|

一.网络结构
LeNet-5是最早应用于手写数字识别的卷积神经网络模型,由Yann LeCun等人在1998年提出。
它包含了如下层:
1.输入层:32x32的灰度图像。
2.卷积层C1:输入通道为1,输出通道为6,使用sigmoid作为激活函数,卷积核大小为5x5,边界填充方式为"valid"。
3.池化层S2:采用最大池化,池化核大小为2x2,步长为2。
4.卷积层C3:输入通道为6,输出通道为16,使用sigmoid作为激活函数,卷积核大小为5x5。
5.池化层S4:采用最大池化,池化核大小为2x2,步长为2。
6.全连接层C5:120个节点,使用sigmoid作为激活函数。
7.全连接层F6:84个节点,使用sigmoid作为激活函数。
8.输出层:10个节点,使用softmax作为激活函数,对应10个数字类别。
二.手写数字识别
这里选择的依旧是Kaggle上著名的入门项目:Digit Recognizer | Kaggle
由于这里的手写数字的图片大小是28*28,故这里无法直接使用LeNet-5,这里使用的是它的其中一种变化版.
卷积神经网络的相关操作(卷积、池化、激活函数、全连接层、激活函数)都在匀速小子:用Pytorch搭建卷积神经网络(以mnist时装数据集为例)里介绍过了,这里就讲一下这个网络是怎么搭建的吧.
第一层:
一开始我们得到是28*28的图片,我们通过padding=2这个操作,把它变成了32*32的图片。
然后用6个5*5的步长为1的卷积核进行卷积操作,可以得到28*28的特征图.
self.model.add_module('conv1',nn.Conv2d(1,6,5,1,2,bias=False))然后用激活函数 Tanh 对它进行非线性变换,此时图片不会改变大小,对于图片上每个像素点 x ,都用 Tanh(x) 去替代。
self.model.add_module('tanh1',nn.Tanh())用了大小为2*2的步长为2的平均池化核之后,变成了6个14*14的特征图。
self.model.add_module("avgpool1",nn.AvgPool2d(2,2,0))
第二层:
用16个5*5的步长为1的卷积核去提取特征,得到16个10*10的特征图.
self.model.add_module('conv2',nn.Conv2d(6,16,5,1,0,bias=False))用激活函数 Tanh 对它进行非线性变换.
self.model.add_module('tanh2',nn.Tanh())同样的平均池化核,此时得到16个5*5的特征图.
self.model.add_module("avgpool2",nn.AvgPool2d(2,2,0))第三层:
用120个5*5的步长为1的卷积核去提取特征,得到120个1*1的特征图.
self.model.add_module('conv3',nn.Conv2d(16,120,5,1,0,bias=False))全连接层:
将这些特征图展平得到(1,120)的向量后,将它们传入全连接层,中间用一次激活函数 Tanh 激活,最后输出10个数的概率。
self.model.add_module('linear1',nn.Linear(120,84))
self.model.add_module('tanh3_1',nn.Tanh())
self.model.add_module('linear2',nn.Linear(84,10))LeNet-5代码如下:
class LeNet_5(nn.Module):
def __init__(self):
#继承父类nn的所有方法
super(LeNet_5,self).__init__()
#构建序列化的神经网络,将网络层按照传入的顺序组合起来
self.model=nn.Sequential()
#第一层卷积神经网络
#传入1*28*28的图片
self.model.add_module('conv1',nn.Conv2d(1,6,5,1,2,bias=False))
#输出6*28*28的图片
self.model.add_module('tanh1',nn.Tanh())
#这里使用了平均池化的操作
self.model.add_module("avgpool1",nn.AvgPool2d(2,2,0))
#输出6×14×14的图片
#第二层卷积神经网络
self.model.add_module('conv2',nn.Conv2d(6,16,5,1,0,bias=False))
#输出16×10×10的图片
self.model.add_module('tanh2',nn.Tanh())
#这里使用了平均池化的操作
self.model.add_module("avgpool2",nn.AvgPool2d(2,2,0))
#输出16×5×5的图片
#第三层卷积神经网络
self.model.add_module('conv3',nn.Conv2d(16,120,5,1,0,bias=False))
#输出120×1×1的图片
self.model.add_module('tanh3',nn.Tanh())
#全连接层
self.model.add_module('linear1',nn.Linear(120,84))
self.model.add_module('tanh3_1',nn.Tanh())
self.model.add_module('linear2',nn.Linear(84,10))
#前向传播
def forward(self,input):
output=input
#name是名字,module是对象
for name,module in self.model.named_children():
if name=='linear1':
#将输出的数据进行展平操作
output=output.view(-1,120*1*1)
output=module(output)
return F.softmax(output,dim=1)其他部分代码和匀速小子:用Pytorch搭建卷积神经网络(以mnist时装数据集为例)一样.
这个模型预测的准确率为97%以上,目前最好成绩:训练集中准确率: 0.9826428571428572 提交准确率为:0.97696。
训练好的模型可以保存起来,万一以后需要使用,可以减少重复训练的时间.
torch.save(netC,"LeNet_5.pth")#保存训练好的LeNet_5模型下次需要的时候只需加载即可,不过需要先运行一下LeNet_5这个类:
netG=torch.load("LeNet_5.pth")参考资料:
1.Ensemble learning LeNet-5 on MNIST 99.325 accuracy |
|