PyTorch之实现LeNet-5卷积神经网络对mnist手写数字图片进行分类
論文:Gradient-based learning applied to document recognition
簡單介紹
意義: 對手寫數據集進行識別,對后續卷積網絡的發展起到了奠基作用
特點:
1)局部感受野(local receptive fields): 基于圖像局部相關的原理,保留了圖像局部結構,同時減少了網絡的權值。
2)權值共享(shared weights): 也是基于圖像局部相關的原理,同時減少網絡的權值參數。
3)下采樣(sub-sampling):對平移和形變更加魯棒,實現特征的不變性,同時起到了一定的降維的作用。
LeNet-5: 這里的5表示卷積層+全連接層一共為5層
網絡結構
代碼
1)導入相應的包
import torch import torch.nn as nn import torch.utils.data as Data import torchvision import os2)定義超參數
EPOCH = 1 BATCH_SIZE = 10 LR = 0.001 DOWNLOAD_MNIST = False3)加載數據集,這里使用pytorch中自帶的mnist數據集
if not(os.path.exists('./mnist/')) or not os.listdir('./mnist/'):DOWNLOAD_MNIST = True # 如果沒有數據集則進行下載train_data = torchvision.datasets.MNIST(root='./mnist/',train=True, # training datatransform=torchvision.transforms.ToTensor(), # Converts a PIL.Image or numpy.ndarray to torch.FloatTensor of shape (C x H x W) and normalize in the range [0.0, 1.0]download=DOWNLOAD_MNIST, ) train_loader = Data.DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True)test_data = torchvision.datasets.MNIST(root='./mnist/', train=False, transform=torchvision.transforms.ToTensor()) # 測試數據集 test_loader = Data.DataLoader(dataset=test_data, batch_size=BATCH_SIZE, shuffle=True)4)定義網絡
class Net(nn.Module):def __init__(self):super(Net, self).__init__() # 上述是自定義網絡的常規寫法self.conv1 = nn.Sequential( nn.Conv2d(1, 6, 5), # 輸入通道,輸出通道,卷積核大小nn.ReLU(), nn.MaxPool2d(2), )self.conv2 = nn.Sequential( nn.Conv2d(6, 16, 5), nn.ReLU(), nn.MaxPool2d(2), )self.fc1 = nn.Sequential(nn.Linear(256, 120), # 輸入特征,輸出特征nn.ReLU(),)self.fc2 = nn.Sequential(nn.Linear(120, 84),nn.ReLU(),)self.fc3 = nn.Sequential(nn.Linear(84, 10),nn.ReLU(),)def forward(self, x):x1 = self.conv1(x)x2 = self.conv2(x1)x2 = x2.view(x.size(0), -1) # 展開成一維向量,方便后面進行全連接x3 = self.fc1(x2)x4 = self.fc2(x3)x5 = self.fc3(x4)return x5net = Net() print(net)首先輸入圖像是單通道的28 x 28大小的圖像,用矩陣表示就是[Batch,28,28]
第一個卷積層conv1所用的卷積核尺寸為55,滑動步長為1,卷積核數目為6,那么經過該層后圖像尺寸變為24,28-5+1=24,輸出矩陣為[6,24,24]。
第一個池化層pool核尺寸為22,步長2,這是沒有重疊的max pooling,池化操作后,圖像尺寸減半,變為12×12,輸出矩陣為[6,12,12]。
第二個卷積層conv2的卷積核尺寸為55,步長1,卷積核數目為16,卷積后圖像尺寸變為8,這是因為12-5+1=8,輸出矩陣為[16,8,8].
第二個池化層pool2核尺寸為22,步長2,這是沒有重疊的max pooling,池化操作后,圖像尺寸減半,變為4×4,輸出矩陣為[16,4,4]。
pool2后面接全連接層fc1,神經元數目為120,再接relu激活函數。
fc1后面接全連接層fc2,神經元數目為84,再接relu激活函數。
再接fc3,神經元個數為10,得到10維的特征向量,用于10個數字的分類訓練,送入softmax分類,得到分類結果的概率output。
5)開始訓練
loss_func = nn.CrossEntropyLoss() # 損失函數 optimizer = torch.optim.Adam(net.parameters(),lr = LR) # 梯度下降cuda_gpu = torch.cuda.is_available() # have gpu for epoch in range(EPOCH):net.train()for batch_idx, (data, target) in enumerate(train_loader):if cuda_gpu:data, target = data.cuda(), target.cuda()net.cuda()output = net(data) # 網絡輸出結果loss = loss_func(output, target)optimizer.zero_grad()loss.backward()optimizer.step()if (batch_idx+1) % 400 == 0:#--------------------------test-------------------------net.eval()correct = 0for data, target in test_loader:if cuda_gpu:data, target = data.cuda(), target.cuda()net.cuda()output = net(data)pred = output.data.max(1)[1] # get the index of the max log-probabilitycorrect += pred.eq(target.data).cpu().sum()accuracy = 1. * correct / len(test_loader.dataset)print('Epoch: ', epoch, '| train loss: %.4f' % loss.data.numpy(), '| test accuracy: %.2f' % accuracy)完整的代碼可參考:LeNet-5
總結
以上是生活随笔為你收集整理的PyTorch之实现LeNet-5卷积神经网络对mnist手写数字图片进行分类的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: iometer测试工具
- 下一篇: 从LeNet到SENet——卷积神经网络