传统的模式识别方法如下图所示,通常包含2个部分,第一部分为特征提取模块,第二部分为分类模块。特征提取模块通常会提取一些基本的特征,与任务是无关的,此模块通常为人工设计的。分类模块通常是针对任务的并且是可训练的。传统的方法很大程度上依赖人工设计的特征提取模块能否提取到有效的特征,并且对于不同的任务需要重新设计。
相比较之前的优点
第一、卷积相比较FC所需要的参数少。
第二、FC丢失了空间信息,而卷积操作可以很好的保留。
网络结构
LeNet5网络包含两层卷积层和三层全连接层。
输入为32×32的图片。
输入图像的shape:1×32×32
1、卷积层C1
kenel size: 5×5
#kernel:6
经过卷积之后的shape:6×28×28
#parameters:6*(551+1) = 156 (包含bias)
2、下采样层S2(平均池化层)
kenel size: 2×2
经过下采样之后的shape:6×14×14
现在的实现常用最大池化。
3、卷积层C3
kenel size: 5×5
#kernel:16
经过卷积之后的shape:16×10×10
论文中提到的是前6个feature map 与S2中的3个相邻的feature map相连,接下来的6个feature map与S2中的4个相邻的feature map相连,再接下来的3个feature map与S2
中的4个不相邻的feature map相连,最后一个feature map与S2中所有的feature map相连。
#parameters:6*(553+1) + 6*(554+1) + 3*(554+1) + 1*(556+1) = 1516
4、下采样层S4(平均池化层)
kenel size: 2×2
经过下采样之后的shape:16×5×5
现在的实现常用最大池化。
5、卷积层C5
kenel size: 5×5
#kernel:120
经过卷积之后的shape:120×1×1
#parameters:120*(5516+1) = 48120
6、全连接层F6
F6相当于MLP(Multi-Layer Perceptron,多层感知机)中的隐含层,有84个节点,所以有84∗(120+1)=10164 个参数,F6采用了sigmoid函数,不过现在实现通常用ReLU函数。
7、输出层
全连接层,共有10个节点,采用的是径向基函数(RBF)的网络连接方式。
代码
import torch
from torch import nn
class LeNet5(nn.Module):
def __init__(self):
super(LeNet5, self).__init__()
self.conv1 = nn.Sequential(
nn.Conv2d(in_channels=1, out_channels=6, kernel_size=5, padding=2),
# nn.BatchNorm2d(6),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2, stride=2)
)
self.conv2 = nn.Sequential(
nn.Conv2d(in_channels=6, out_channels=16, kernel_size=5),
# nn.BatchNorm2d(16),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2, stride=2)
)
self.fc = nn.Sequential(
nn.Linear(16 * 5 * 5, 120),
nn.Linear(120, 84),
nn.Linear(84, 10)
)
def forward(self, x):
x = self.conv1(x)
x = self.conv2(x)
x = x.view(x.shape[0], -1)
x = self.fc(x)
return x
if __name__ == '__main__':
x = torch.rand(8,1,28,28)
net = LeNet5()
y = net(x)
print(y.shape)
print(y)