PyTorch 实现经典模型1:LeNet5
生活随笔
收集整理的這篇文章主要介紹了
PyTorch 实现经典模型1:LeNet5
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
模型:LeNet5
- 網絡結構
- 符號說明
- 網絡參數
- 代碼實現
- 1) 導入必需的包
- 2) 搭建網絡模型
- 3) 導入使用的數據集
- 4) 訓練模型
- 5) 保存模型
- 6) 測試模型效果
- 所遇錯誤
- '_IncompatibleKeys' object is not callable
- Ref
本著簡單易理解的原則,所有代碼均為采取最簡單的辦法進行編寫實現,還望各位莫嫌臃腫,大牛們莫怪低端。
“世界上最好的捷徑,就是沒有捷徑”
網絡結構
符號說明
- C 代表卷積層
- S 代表降采樣層(池化層)
- F 代表全連接層
網絡參數
- Input —> C1:number of kernels(卷積核數量)= 6,kernel_size(卷積核大小) = 5x5,stride(步長)=1
- C1 —> S2:
代碼實現
1) 導入必需的包
# 1) 導入必需的包 import torch import torch.nn as nn import torch.nn.functional as F import torchvision import torchvision.transforms as transforms import torch.optim as optim2) 搭建網絡模型
# 2) 搭建網絡模型 class LeNet5(nn.Module):def __init__(self):super(LeNet5, self).__init__()self.c1 = nn.Conv2d(in_channels=1, out_channels=6, kernel_size=5, stride=1, padding=2)self.s2 = nn.MaxPool2d(kernel_size=2, stride=2)self.c3 = nn.Conv2d(in_channels=6, out_channels=16, kernel_size=5, stride=1)self.s4 = nn.MaxPool2d(kernel_size=2, stride=2)# 遇到了卷積層變為全連接層self.c5 = nn.Linear(16*5*5, 120)self.f6 = nn.Linear(120, 84)self.f7 = nn.Linear(84, 10)def forward(self, x):x = self.c1(x)# x = F.relu(x)x = self.s2(x)x = self.c3(x)# x = F.relu(x)x = self.s4(x)# 剛才的卷積層變為全連接層,使用下邊代碼實現x = x.view(-1, 16*5*5)x = self.c5(x)# x = F.relu(x)x = self.f6(x)# x = F.relu(x)x = self.f7(x)# x = F.sigmoid(x)return x3) 導入使用的數據集
本次測試使用的是 MNIST 數據集,關于此數據集的詳細介紹,請參考此篇文章:fly吧。
如果想要直接復制代碼即可使用,就需要確保工程文件中含有 data 文件夾,并且 MNIST 數據集已經下載完成。否則,需要進行下載。
4) 訓練模型
# 4) 訓練模型 for epoch in range(num_epoch):LeNet5.train(0)train_loss = 0.0for idx, (img, label) in enumerate(trainloader):# print('開始訓練第 {} 批數據'.format(idx+1))optimizer.zero_grad()img = img.to(device)label = label.to(device)output = LeNet5(img)loss = criterion(output, label)loss.backward()optimizer.step()train_loss += loss.item()print('完成第 {} 輪訓練,train_loss: {}'.format(epoch+1, train_loss))5) 保存模型
關于保存模型方法和加載模型請參考此篇教程:fly吧
# 5) 保存模型結構參數 torch.save(LeNet5.state_dict(), 'LeNet5_state_dict.pth')6) 測試模型效果
使用模型測試時,記得將第 4 步模型訓練和第 5 步模型保存的程序進行注釋掉,否則還會再次對模型進行一次訓練,浪費掉時間。
# 6) 加載模型并測試模型效果 LeNet5.load_state_dict(torch.load('LeNet5_state_dict.pth')) LeNet5.eval()correct_num = 0 data_num = 0 for idx, (img, label) in enumerate(testloader):img = img.to(device)label = label.to(device)output = LeNet5(img)idx, pred = output.max(1)for i in range(len(label)):if label[i] == pred[i]:correct_num += 1data_num += 1print('data_num: {} \t correct_num: {} \t Accuracy: {:.2f}%'.format(data_num, correct_num, correct_num*100/data_num))所遇錯誤
‘_IncompatibleKeys’ object is not callable
解決辦法參考此篇文章:fly吧
Ref
2021-11-06 更新
重新復制模型程序到文件中,發現出現了一些 bug,于是重新調整了結構加了一句 main 能跑下來。
# 1) 導入必需的包 import torch import torch.nn as nn import torch.nn.functional as F from torch.utils import data import torchvision import torchvision.transforms as transforms import torch.optim as optim# 2) 搭建網絡模型 class LeNet5(nn.Module):def __init__(self):super(LeNet5, self).__init__()self.c1 = nn.Conv2d(in_channels=1, out_channels=6, kernel_size=5, stride=1, padding=2)self.s2 = nn.MaxPool2d(kernel_size=2, stride=2)self.c3 = nn.Conv2d(in_channels=6, out_channels=16, kernel_size=5, stride=1)self.s4 = nn.MaxPool2d(kernel_size=2, stride=2)# 遇到了卷積層變為全連接層self.c5 = nn.Linear(16*5*5, 120)self.f6 = nn.Linear(120, 84)self.f7 = nn.Linear(84, 10)def forward(self, x):x = self.c1(x)# x = F.relu(x)x = self.s2(x)x = self.c3(x)# x = F.relu(x)x = self.s4(x)# 剛才的卷積層變為全連接層,使用下邊代碼實現x = x.view(-1, 16*5*5)x = self.c5(x)# x = F.relu(x)x = self.f6(x)# x = F.relu(x)x = self.f7(x)# x = F.sigmoid(x)return x# 3) 導入使用的數據集、網絡結構、優化器、損失函數等 LeNet5 = LeNet5() device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu') LeNet5 = LeNet5.to(device=device)optimizer = optim.Adam(LeNet5.parameters(), lr=0.001) criterion = nn.CrossEntropyLoss() batch_size = 128 num_epoch = 3transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize(0.5, 0.5)] ) # 如果沒有下載 MNIST 數據集,那么需要設置 download 參數為 True # 如果已經下載 MNIST 數據集,那么只需設置 download 參數為 False trainset = torchvision.datasets.MNIST(root='./data', train=True, transform=transform, download=False) trainloader = torch.utils.data.DataLoader(dataset=trainset, batch_size=batch_size, shuffle=True, num_workers=2) testset = torchvision.datasets.MNIST(root='./data', train=False, transform=transform, download=True) testloader = torch.utils.data.DataLoader(dataset=testset, batch_size=batch_size, shuffle=True, num_workers=2)if __name__ == '__main__':# 4) 訓練模型for epoch in range(num_epoch):LeNet5.train()train_loss = 0.0for idx, (img, label) in enumerate(trainloader):# print('開始訓練第 {} 批數據'.format(idx+1))optimizer.zero_grad()img = img.to(device)label = label.to(device)output = LeNet5(img)loss = criterion(output, label)loss.backward()optimizer.step()train_loss += loss.item()print('完成第 {} 輪訓練,train_loss: {}'.format(epoch+1, train_loss))# 5) 保存模型結構參數torch.save(LeNet5.state_dict(), 'LeNet5_state_dict.pth')# 6) 加載模型并測試模型效果LeNet5.load_state_dict(torch.load('LeNet5_state_dict.pth'))LeNet5.eval()correct_num = 0data_num = 0for idx, (img, label) in enumerate(testloader):img = img.to(device)label = label.to(device)output = LeNet5(img)idx, pred = output.max(1)for i in range(len(label)):if label[i] == pred[i]:correct_num += 1data_num += 1print('data_num: {} \t correct_num: {} \t Accuracy: {:.2f}%'.format(data_num, correct_num, correct_num*100/data_num))總結
以上是生活随笔為你收集整理的PyTorch 实现经典模型1:LeNet5的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PyTorch 实现 GAN 生成式对抗
- 下一篇: PyTorch 实现经典模型2:Alex