先留一段圖像分類代碼,空閑時間再做分析:
創建神經網絡:
import torch
from torch import nn
import torch.nn.functional as F
class MyAlexNet(nn.Module):def __init__(self):super(MyAlexNet, self).__init__()self.c1=nn.Conv2d(in_channels=3,out_channels=48,kernel_size=11,stride=4,padding=2)self.ReLU=nn.ReLU()self.c2=nn.Conv2d(in_channels=48,out_channels=128,kernel_size=5,stride=1,padding=2)self.s2=nn.MaxPool2d(2)self.c3=nn.Conv2d(in_channels=128,out_channels=192,kernel_size=3,stride=1,padding=1)self.s3=nn.MaxPool2d(2)self.c4=nn.Conv2d(in_channels=192,out_channels=192,kernel_size=3,stride=1,padding=1)self.c5=nn.Conv2d(in_channels=192,out_channels=128,kernel_size=3,stride=1,padding=1)self.s5=nn.MaxPool2d(kernel_size=3,stride=2)self.flatten=nn.Flatten()self.f6=nn.Linear(128*6*6,2048)self.f7=nn.Linear(2048,2048)self.f8=nn.Linear(2048,1000)self.f9=nn.Linear(1000,2)def forward(self,x):x=self.ReLU(self.c1(x))x=self.ReLU(self.c2(x))x=self.s2(x)x=self.ReLU(self.c3(x))x=self.s3(x)x=self.ReLU(self.c4(x))x=self.ReLU(self.c5(x))x=self.s5(x)x=self.flatten(x)x=self.f6(x)x=F.dropout(x,p=0.5)x=self.f7(x)x=F.dropout(x,p=0.5)x=self.f8(x)x=F.dropout(x,p=0.5)x=self.f9(x)return x
if __name__ == '__main__':x=torch.rand([1,3,224,224])model=MyAlexNet()y=model(x)
數據預處理:
import os
from shutil import copy
import random
def mkdir(file):if not os.path.exists(file):os.makedirs(file)
#獲取data文件夾下所有文件夾名(即需要分類的類名)
file_path='E:/BaiduNetdiskDownload/Kaggle貓狗大戰/train'
flower_class= [cla for cla in os.listdir(file_path)]
#創建訓練集train文件夾,并由類名在其目錄下創建子目錄
mkdir('data/train')
mkdir('data/train/cat')
mkdir('data/train/dog')
mkdir('data/val')
mkdir('data/val/cat')
mkdir('data/val/dog')
split_rate=0.1
for cla in flower_class:cla_path=file_path+'/'+cla#"E:\BaiduNetdiskDownload\Kaggle貓狗大戰\train\train\cat.0.jpg"images=os.listdir(cla_path)print(cla_path)num=len(images)eval_index=random.sample(images,k=int(num*split_rate))for index,image in enumerate(images):if image in eval_index:image_path = cla_path+'/'+imageif "cat" in image_path:new_path = 'data/val/cat/'else:new_path = 'data/val/dog/'copy(image_path,new_path)else:image_path=cla_path+'/'+imageif "cat" in image_path:new_path='data/train/cat/'else:new_path='data/train/dog/'copy(image_path,new_path)print("\r[{}]processing[{}/{}]".format(cla,index+1,num),end="")print()
print("processing done!")
訓練集用于 訓練權重:
import torch
from torch import nn
from net import MyAlexNet
import numpy as np
from torch.optim import lr_scheduler
import os
from torchvision import transforms
from torchvision.datasets import ImageFolder
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus']=False
ROOT_TRAIN = 'C:/Users/86156/PycharmProjects/pythonProject1/cat-dog/data/train'
ROOT_TEST='C:/Users/86156/PycharmProjects/pythonProject1/cat-dog/data/val'
normalize=transforms.Normalize([0.5,0.5,0.5],[0.5,0.5,0.5])
train_transform=transforms.Compose([transforms.Resize((224,224)),transforms.RandomVerticalFlip(),transforms.ToTensor(),normalize
])
val_transform=transforms.Compose([transforms.Resize((224,224)),transforms.ToTensor(),normalize
])
train_dataset=ImageFolder(ROOT_TRAIN,transform=train_transform)
val_dataset=ImageFolder(ROOT_TEST,transform=val_transform)
train_dataloader=DataLoader(train_dataset,batch_size=32,shuffle=True)
val_dataloader=DataLoader(val_dataset,batch_size=32,shuffle=True)
model=MyAlexNet()
loss_fn=nn.CrossEntropyLoss()
optimizer=torch.optim.SGD(model.parameters(),lr=0.01,momentum=0.9)
lr_scheduler=lr_scheduler.StepLR(optimizer,step_size=10,gamma=0.5)
def train(dataloader,model,loss_fn,optimizer):loss,current,n =0.0,0.0,0.0for batch,(x,y) in enumerate(dataloader):image,y =x,youtput=model(image)cur_loss=loss_fn(output,y)_,pred=torch.max(output,axis=1)cur_acc=torch.sum(y==pred)/output.shape[0]optimizer.zero_grad()cur_loss.backward()optimizer.step()loss+=cur_loss.item()current+=cur_acc.item()n+=1train_loss=loss/ntrain_acc=current/nprint('train_loss'+str(train_loss))print('train_acc'+str(train_acc))return train_loss,train_acc
def val(dataloader,model,loss_fn):model.eval()loss,current,n=0.0,0.0,0.0with torch.no_grad():for batch,(x,y) in enumerate(dataloader):image,y =x,youtput=model(image)cur_loss=loss_fn(output,y)_,pred=torch.max(output,axis=1)cur_acc=torch.sum(y==pred)/output.shape[0]loss+=cur_loss.item()current+=cur_acc.item()n+=1val_loss=loss/nval_acc=current/nprint('val_loss'+str(val_loss))print('val_acc'+str(val_acc))return val_loss,val_acc
def matplot_loss(train_loss,val_loss):plt.plot(train_loss,label='train_loss')plt.plot(val_loss,label='val_loss')plt.legend(loc='best')plt.ylabel('loss')plt.xlabel('epoch')plt.title("訓練集和驗證集loss值對比圖")plt.show()
def matplot_acc(train_loss,val_loss):plt.plot(train_acc,label='train_acc')plt.plot(val_acc,label='val_acc')plt.legend(loc='best')plt.ylabel('acc')plt.xlabel('epoch')plt.title("訓練集和驗證集acc值對比圖")plt.show()
loss_train=[]
acc_train=[]
loss_val=[]
acc_val=[]
epoch=20
min_acc=0
for t in range(epoch):lr_scheduler.step()print(f"epoch{t+1}\n----------------")train_loss,train_acc=train(train_dataloader,model,loss_fn,optimizer)val_loss,val_acc=val(val_dataloader,model,loss_fn)loss_train.append(train_loss)acc_train.append(train_acc)loss_val.append(val_loss)acc_val.append(val_acc)if val_acc>min_acc:folder='save_model'if not os.path.exists(folder):os.mkdir('save_model')min_acc=val_accprint(f"save best model,第{t+1}輪")torch.save(model.state_dict(),'save_model/best.model.pth')if t==epoch-1:torch.save(model.state_dict(),'save_model/last_model.pth')
print('Done')
測試集用于測試模型:
import torch
from net import MyAlexNet
from torch.autograd import variable
from torchvision import datasets,transforms
from torchvision.transforms import ToPILImage
from torchvision.datasets import ImageFolder
from torchvision.transforms import ToTensor
from torch.utils.data import DataLoader
ROOT_TRAIN = 'C:/Users/86156/PycharmProjects/pythonProject1/cat-dog/data/train'
ROOT_TEST='C:/Users/86156/PycharmProjects/pythonProject1/cat-dog/data/val'
normalize=transforms.Normalize([0.5,0.5,0.5],[0.5,0.5,0.5])
train_transform=transforms.Compose([transforms.Resize((224,224)),transforms.RandomVerticalFlip(),transforms.ToTensor(),normalize
])
val_transform=transforms.Compose([transforms.Resize((224,224)),transforms.ToTensor(),normalize
])
train_dataset=ImageFolder(ROOT_TRAIN,transform=train_transform)
val_dataset=ImageFolder(ROOT_TEST,transform=val_transform)
train_dataloader=DataLoader(train_dataset,batch_size=32,shuffle=True)
val_dataloader=DataLoader(val_dataset,batch_size=32,shuffle=True)
model=MyAlexNet()
model.load_state_dict(torch.load("C:/Users/86156/PycharmProjects/pythonProject1/cat-dog/save_model/best.model.pth"))
classes=["cat","dog",
]
show=ToPILImage()
model.eval()
for i in range(50):x,y = val_dataset[i][0],val_dataset[i][1]show(x).show()x=torch.tensor(torch.unsqueeze(x,dim=0).float(),requires_grad=True)x=torch.tensor(x)with torch.no_grad():pred=model(x)print(pred)predicted,actual=classes[torch.argmax(pred[0])],classes[y]print(f'predicted:"{predicted}",Actual:"{actual}"')
沒有顯卡慢的跟狗屎一樣。