前言
- LeNet是早期成功的神经网络
- 先使用卷积层来学习图片空间信息
- 然后使用全连接层来转换到类别空间
结构
这是最初始的结构图, 卷积核为5*5
, 最后得到10维的输出
这里是以分类Mnist图片的例子, 原结构做了padding为2, 所以最开始的输入维度是32*32
下面看一下实现:
import torch
import torch.nn as nn
class Reshape(nn.Module):
def forward(self, x):
return x.view(-1, 1, 28, 28)
# MLP线性层之间要有激活函数, 不然就还是一个线性层
# padding 后是加了2*padding
# RELU函数也很好用, 有时候比Sigmoid函数好用
# nn.Flatten() 保留第一维度也就是batch, 然后把后面的合起来
net = 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(),
nn.AvgPool2d(kernel_size=2, stride=2), nn.Flatten(),
nn.Linear(16*5*5, 120), nn.Sigmoid(),
nn.Linear(120, 84), nn.Sigmoid(),
nn.Linear(84, 10)
)
# 测试输入
x = torch.rand(1, 1, 28, 28)
y = net(x)
print(y.shape)
for layer in net:
x = layer(x)
print(layer.__class__.__name__, 'output shape: \t', x.shape)
>>
>torch.Size([1, 10])
Reshape output shape: torch.Size([1, 1, 28, 28])
Conv2d output shape: torch.Size([1, 6, 28, 28])
Sigmoid output shape: torch.Size([1, 6, 28, 28])
AvgPool2d output shape: torch.Size([1, 6, 14, 14])
Conv2d output shape: torch.Size([1, 16, 10, 10])
Sigmoid output shape: torch.Size([1, 16, 10, 10])
AvgPool2d output shape: torch.Size([1, 16, 5, 5])
Flatten output shape: torch.Size([1, 400])
Linear output shape: torch.Size([1, 120])
Sigmoid output shape: torch.Size([1, 120])
Linear output shape: torch.Size([1, 84])
Sigmoid output shape: torch.Size([1, 84])
Linear output shape: torch.Size([1, 10])
QA
- 维度减小, 通道增加
- max和avg没有很明显的优劣