1.參考視頻:
2.1 pytorch官方demo(Lenet)_嗶哩嗶哩_bilibili
2.總結:
(1)LeNet網絡就是 我最開始用來預測mnist數據集的那個網絡,簡單的2個conv+2個maxpool+3個linear層
(2)up主整理的train.py等內容里面的細節分析值得學習
(3)對于預測代碼的撰寫,可以參考代碼的predict.py文件
3.幾個文件的源代碼我都貼一下(都不多——但很精):
(1)首先是 model.py:
import torch.nn as nn
import torch.nn.functional as Fclass LeNet(nn.Module):def __init__(self):super(LeNet, self).__init__()self.conv1 = nn.Conv2d(3, 16, 5)self.pool1 = nn.MaxPool2d(2, 2)self.conv2 = nn.Conv2d(16, 32, 5)self.pool2 = nn.MaxPool2d(2, 2)self.fc1 = nn.Linear(32*5*5, 120)self.fc2 = nn.Linear(120, 84)self.fc3 = nn.Linear(84, 10)def forward(self, x):x = F.relu(self.conv1(x)) # input(3, 32, 32) output(16, 28, 28)x = self.pool1(x) # output(16, 14, 14)x = F.relu(self.conv2(x)) # output(32, 10, 10)x = self.pool2(x) # output(32, 5, 5)x = x.view(-1, 32*5*5) # output(32*5*5)x = F.relu(self.fc1(x)) # output(120)x = F.relu(self.fc2(x)) # output(84)x = self.fc3(x) # output(10)return x
模型 == 2個conv + 2個max_pool + 3個linear
(2) train.py訓練模型的文件:
import torch
import torchvision
import torch.nn as nn
from model import LeNet
import torch.optim as optim
import torchvision.transforms as transformsdef main():# 定義transform的數據增強transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])# 處理cifar10的 train和val的數據集的問題# 50000張訓練圖片# 第一次使用時要將download設置為True才會自動去下載數據集train_set = torchvision.datasets.CIFAR10(root='./data', train=True,download=False, transform=transform)train_loader = torch.utils.data.DataLoader(train_set, batch_size=36,shuffle=True, num_workers=0)# 10000張驗證圖片# 第一次使用時要將download設置為True才會自動去下載數據集val_set = torchvision.datasets.CIFAR10(root='./data', train=False,download=False, transform=transform)val_loader = torch.utils.data.DataLoader(val_set, batch_size=5000,shuffle=False, num_workers=0)val_data_iter = iter(val_loader)val_image, val_label = next(val_data_iter)# classes = ('plane', 'car', 'bird', 'cat',# 'deer', 'dog', 'frog', 'horse', 'ship', 'truck')# 訓練前的準備: 實例化model網絡net , 定義 loss函數 CrossEntropyLoss() 和 Adam優化器net = LeNet()loss_function = nn.CrossEntropyLoss()optimizer = optim.Adam(net.parameters(), lr=0.001)# 開始訓練:zero_grad() + outputs + loss backward + optim stepfor epoch in range(5): # loop over the dataset multiple timesrunning_loss = 0.0for step, data in enumerate(train_loader, start=0):# get the inputs; data is a list of [inputs, labels]inputs, labels = data# zero the parameter gradientsoptimizer.zero_grad()# forward + backward + optimizeoutputs = net(inputs)loss = loss_function(outputs, labels)loss.backward()optimizer.step()# print statisticsrunning_loss += loss.item()if step % 500 == 499: # print every 500 mini-batcheswith torch.no_grad():outputs = net(val_image) # [batch, 10]predict_y = torch.max(outputs, dim=1)[1]accuracy = torch.eq(predict_y, val_label).sum().item() / val_label.size(0)print('[%d, %5d] train_loss: %.3f test_accuracy: %.3f' %(epoch + 1, step + 1, running_loss / 500, accuracy))running_loss = 0.0print('Finished Training')# 最后把 model的 參數save 為一個.pth文件save_path = './Lenet.pth'torch.save(net.state_dict(), save_path)if __name__ == '__main__':main()
分析:數據集劃分 + 實例化網絡_優化器_loss函數 + 分epoch開始尋 + save_pth權重
(3)predict.py:
import torch
import torchvision.transforms as transforms
from PIL import Imagefrom model import LeNetdef main():# 將需要檢測圖像 裁剪為32*32transform = transforms.Compose([transforms.Resize((32, 32)),transforms.ToTensor(),transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])classes = ('plane', 'car', 'bird', 'cat','deer', 'dog', 'frog', 'horse', 'ship', 'truck')#實例化網絡 + 才入權重net = LeNet()net.load_state_dict(torch.load('Lenet.pth'))# 打開圖像,轉換格式im = Image.open('1.jpg')im = transform(im) # [C, H, W]im = torch.unsqueeze(im, dim=0) # [N, C, H, W]# 輸入到網絡中, 得到預測的結果with torch.no_grad():outputs = net(im)predict = torch.max(outputs, dim=1)[1].numpy()print(classes[int(predict)])if __name__ == '__main__':main()
predict == 處理圖像 + 實例化權重 + 得到預測結果