1 LeNet介绍
LeNet是由Yann Lecun(2018年图灵奖得主,CNN的缔造者)创造的CNN经典网络,是卷积神经网络史上的开篇之作。
诞生于1990年,在手写体字符识别领域创造性的引入了卷积神经网络的基本操作,意义重大,可以说是现代卷积神经网络的发展起点。
1.1 思路
引入卷积层+池化层等结构
1.2 网络结构
输入图像分辨率:28x28
结构:
-
(1)卷积层1:5x5 --->输出4个24×24大小的特征图;
-
(2)池化层1:平均池化层 2x2;
-
(3)卷积层2:5x5 --->输出12个8x8大小的特征图;
-
(4)池化层2:2x2
-
(5)全连接层 ---->输出
1.3 优势与不足
优势:采用CNN自动提取特征。
不足:使用了平均池化,一般而言,不如 Max-Pooling 提取特征具有分类辨识度。
2 LeNet-5 介绍
诞生于1998年,在LeNet初期版本上迭代进化而来。卷积核大小为5x5。
2.1 思路
输入是32X32像素的图像,利用CNN提取特征并进行分类,输出0~9个类别。
2.2 网络结构
层数:7层(不含输入),包括3层卷积层,2层池化层,2层全连接层
输入图片大小:32x32
2.3 优势与不足
-
优势
-
充分利用卷积、参数共享、池化等操作提取特征,降低了计算成本,增加了特征图通道,增加了全连接层,在手写体字符识别上表现的很成功,错误率仅1%。
-
已经具备了卷积神经网络的雏形(卷积层+池化层+全连接层)
-
-
不足
- 由于时代的局限性,激活函数采用的 sigmoid 而不是常用的Relu之类的,最后一层多分类采用的是Gaussian Connections,而目前常用的是 softmax。
- 池化层用的是平均池化,在分类任务中可能最大池化效果会更佳。因此目前若使用该网络常需要更新修改后再使用,与原始版本略有差异。
-
但瑕不掩瑜,LeNet-5 仍旧不失为一个较为优秀的网络。
3 重写CNNNet
使用LeNet 重写之前的CNNNet 初始化及串联层级方法。
# 定义层级
def __init__(self):
super(LeNet, self).__init__()
# 第一层卷积网络,输入通道,输出通道,卷积盒,步长
self.conv1 = nn.Conv2d(in_channels=3, out_channels=6, kernel_size=5)
# 第二层卷积网络
self.conv2 = nn.Conv2d(in_channels=6, out_channels=16, kernel_size=5)
# 全连接层,输入特征,输出特征
self.fc1 = nn.Linear(16*5*5, 120)
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10)
# 串联层级
def forward(self, x):
# 处理卷积之后的非线性变化
x = fun.relu(self.conv1(x))
x = fun.max_pool2d(x, 2)
x = fun.relu(self.conv2(x))
x = fun.max_pool2d(x, 2)
x = x.view(x.size(0), -1)
x = fun.relu(self.fc1(x))
x = fun.relu(self.fc2(x))
x = self.fc3(x)
return x
运行程序后,打印出训练集中使用到的参数
其参数规模相比 CNNNet 减少了三分之二,同时又比全局平均池化参数更加丰富。
训练后的测试效果如下