PyTorch项目实战13——CIFAR10训练模型使用LeNet

394 阅读3分钟

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

运行程序后,打印出训练集中使用到的参数

image.png

其参数规模相比 CNNNet 减少了三分之二,同时又比全局平均池化参数更加丰富。

训练后的测试效果如下

image.png

4 LeNet 全量代码

image.png