目录
LeNet
MNIST数据集
LeNet模型图
编辑
总结
代码实现:卷积神经网络 LeNet
LeNet(LeNet-5)由两个部分组成:卷积编码器核全连接层密集块
检查模型
LeNet
卷积神经网络里面最为著名的一个网络,80年代末提出来的,被广泛应用在银行、邮递行业
用于手写数字识别的一个模型
MNIST数据集
- 50000个训练数据(在80年代末期是一个很大的数据集了,那时候内存都只有几兆)
- 10000个测试数据
- 图像大小 28 x 28,已经scale好了,数字都放在图像的中间,是一个灰度图
- 10类
很长一段时间,这个数据集的知名度远高于LeNet模型
LeNet模型图
输入一个32 x 32的image图像
-->放入一个5 x 5的卷积层,输出通道为6
-->一个2 x 2的pooling池化层,把28 x 28池化为6通道的14 x 14
-->再接一个卷积层,仍然是 5 x 5的卷积核,输出编程16通道的10 x 10
--> 一个pooling层,高宽减半,输出通道数不变
-->拉成一个向量,放到mlp全连接层,输出为120
-->第二个全连接层输出为84
-->一个高斯层(但是现在不用了,也可以理解成一个全连接层),最后输出为10(Softmax一下转换为10类的可能性输出)
总结
- LeNet是早期成功的神经网络
- 先使用卷积层来学习图片空间信息
- 通过池化层来降低图片位置敏感度
- 最后使用全连接层来转换到类别空间(10类)
代码实现:卷积神经网络 LeNet
LeNet(LeNet-5)由两个部分组成:卷积编码器核全连接层密集块
为了非线性,在每个卷积后面都加了一个Sigmoid激活函数
import torch
from torch import nn
from d2l import as d2l
class Reshape(torch.nn.Module):
def forward(self, x):
return x.view(-1, 1, 28, 28)
net = torch.nn.Sequential(
Reshape(), nn.Conv2d(1, 6, kernel_size=5, padding=2), nn.Sigmoid()
nn.AvgPool2d(kernel_size=2, stride=2),
nn.Conv2d(6, 16, kernel_size=5), nn.Sigmoid(),
# Flatten():第一维度保持住,后面全部拉成一个维度
nn.AbgPool2d(kernel_size=2, strid=2), nn.Flatten(),
nn.Linear(16 * 5 * 5, 120), nn.Sigmoid(),
nn.Linear(120, 84), nn.Sigmoid(),
nn.Linear(84, 10))
检查模型
因为我们是nn.Sequential定义的,所以可以每一层拿出来算一下
这里是用了__name__,也可以使用PyTorch的summary
X = torch.rand(size=(1, 1, 28, 28), dtype=torch.float32)
for layer in net:
X = layer(X)
print(layer.__class__.__name__, 'output shape:\t', X.shape)
输出如下:
我们可以看到
- 第一个block(卷积层+激活+池化):
【1, 1, 28, 28】 ---> 【1, 6, 14, 14】
做了一个图片大小减半,通道数从1扩到了6的操作,总体来说数据其实是变多了
- 第二个block:
【1, 6, 14, 14】---> 【1, 16, 5, 5】
图片大小减少了大概三倍,通道数从6扩到16
- 三层MLP:
【1,400】--->【1, 120】--->【1, 84】--->【1, 10】
模型核心思想:我们前面讲过一个通道可以看成是一个模式,整个LeNet做的就是不断地把空间信息压缩压缩,然后把抽出来压缩的信息放在不同的通道里面,最后通过几个MLP将不同模式的通道进行融合成我们最后的输出