PyTorch之实现LeNet-5卷积神经网络对mnist手写数字图片进行分类
論文:Gradient-based learning applied to document recognition
簡(jiǎn)單介紹
意義: 對(duì)手寫(xiě)數(shù)據(jù)集進(jìn)行識(shí)別,對(duì)后續(xù)卷積網(wǎng)絡(luò)的發(fā)展起到了奠基作用
特點(diǎn):
1)局部感受野(local receptive fields): 基于圖像局部相關(guān)的原理,保留了圖像局部結(jié)構(gòu),同時(shí)減少了網(wǎng)絡(luò)的權(quán)值。
2)權(quán)值共享(shared weights): 也是基于圖像局部相關(guān)的原理,同時(shí)減少網(wǎng)絡(luò)的權(quán)值參數(shù)。
3)下采樣(sub-sampling):對(duì)平移和形變更加魯棒,實(shí)現(xiàn)特征的不變性,同時(shí)起到了一定的降維的作用。
LeNet-5: 這里的5表示卷積層+全連接層一共為5層
網(wǎng)絡(luò)結(jié)構(gòu)
代碼
1)導(dǎo)入相應(yīng)的包
import torch import torch.nn as nn import torch.utils.data as Data import torchvision import os2)定義超參數(shù)
EPOCH = 1 BATCH_SIZE = 10 LR = 0.001 DOWNLOAD_MNIST = False3)加載數(shù)據(jù)集,這里使用pytorch中自帶的mnist數(shù)據(jù)集
if not(os.path.exists('./mnist/')) or not os.listdir('./mnist/'):DOWNLOAD_MNIST = True # 如果沒(méi)有數(shù)據(jù)集則進(jìn)行下載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()) # 測(cè)試數(shù)據(jù)集 test_loader = Data.DataLoader(dataset=test_data, batch_size=BATCH_SIZE, shuffle=True)4)定義網(wǎng)絡(luò)
class Net(nn.Module):def __init__(self):super(Net, self).__init__() # 上述是自定義網(wǎng)絡(luò)的常規(guī)寫(xiě)法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) # 展開(kāi)成一維向量,方便后面進(jìn)行全連接x3 = self.fc1(x2)x4 = self.fc2(x3)x5 = self.fc3(x4)return x5net = Net() print(net)首先輸入圖像是單通道的28 x 28大小的圖像,用矩陣表示就是[Batch,28,28]
第一個(gè)卷積層conv1所用的卷積核尺寸為55,滑動(dòng)步長(zhǎng)為1,卷積核數(shù)目為6,那么經(jīng)過(guò)該層后圖像尺寸變?yōu)?4,28-5+1=24,輸出矩陣為[6,24,24]。
第一個(gè)池化層pool核尺寸為22,步長(zhǎng)2,這是沒(méi)有重疊的max pooling,池化操作后,圖像尺寸減半,變?yōu)?2×12,輸出矩陣為[6,12,12]。
第二個(gè)卷積層conv2的卷積核尺寸為55,步長(zhǎng)1,卷積核數(shù)目為16,卷積后圖像尺寸變?yōu)?,這是因?yàn)?2-5+1=8,輸出矩陣為[16,8,8].
第二個(gè)池化層pool2核尺寸為22,步長(zhǎng)2,這是沒(méi)有重疊的max pooling,池化操作后,圖像尺寸減半,變?yōu)?×4,輸出矩陣為[16,4,4]。
pool2后面接全連接層fc1,神經(jīng)元數(shù)目為120,再接relu激活函數(shù)。
fc1后面接全連接層fc2,神經(jīng)元數(shù)目為84,再接relu激活函數(shù)。
再接fc3,神經(jīng)元個(gè)數(shù)為10,得到10維的特征向量,用于10個(gè)數(shù)字的分類(lèi)訓(xùn)練,送入softmax分類(lèi),得到分類(lèi)結(jié)果的概率output。
5)開(kāi)始訓(xùn)練
loss_func = nn.CrossEntropyLoss() # 損失函數(shù) 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) # 網(wǎng)絡(luò)輸出結(jié)果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
總結(jié)
以上是生活随笔為你收集整理的PyTorch之实现LeNet-5卷积神经网络对mnist手写数字图片进行分类的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: iometer测试工具
- 下一篇: 763 划分字母区间