完整代码:LeNet实现完整代码
LeNet-5
LeNet-5由Yann LeCun于1998年提出,是卷积网络的开篇之作。(论文:Gradient-based learning applied to document recognition)。
由于 LeNet-5 提出的时间比较早,其网络中使用的一些技术在现在已经很少使用,因此现在我们所使用的 LeNet-5 与原始论文的有所不同。
LeNet-5 的结构图
C
i
C_i
Ci:卷积层;
S
i
S_i
Si:下采样层(池化层);
F
i
F_i
Fi:全连接层
对上图中的每层操作及参数进行解释:
层序 | 操作 | 输入数据维度 | 输出数据维度 | 卷积核 | 卷积步长 | 池化核大小 | 池化步长 | 填充 | 激活函数 | 可训练参数 | 连接数 |
---|---|---|---|---|---|---|---|---|---|---|---|
INPUT | 输入层 | — | (32,32,1) | — | — | — | — | — | — | — | — |
C1 | 卷积层 | (32,32,1) | (28,28,6) | (5,5,6) | 1 | — | — | valid | sigmoid | 156 | 122304 |
S2 | 下采样层 | (28,28,6) | (14,14,6) | — | — | (2,2) | 2 | valid | — | 12 | 5880 |
C3 | 卷积层 | (14,14,6) | (10,10,16) | (5,5,16) | 1 | — | — | valid | sigmoid | 1516 | 151600 |
S4 | 下采样层 | (10,10,16) | (5,5,16) | — | — | (2,2) | 2 | valid | — | 32 | 2000 |
C5 | 卷积层 | (5,5,16) | (1,1,120) | (5,5,120) | 1 | — | — | valid | sigmoid | 48120 | 48120 |
F6 | 全连接层 | (120,) | (84,) | — | — | — | — | — | sigmoid | 10164 | — |
OUTPUT | 全连接层(输出层) | (84,) | (10,) | – | – | – | — | — | RBF | — | — |
问题一:LeNet-5现在为什么是5层?
在神经网络中,输入层不算在层数内。现在我们认为层中没有可训练的参数,也不计算在内。现在的下采样层(池化层)没有训练参数,因此原始的LeNet-5包含3层卷积和2个全连接层,共5层。
问题二:LeNet-5使用的激活函数和下采样层?
原论文是这样写的 "The four inputs to a unit in S2 are added, then multiplied by a trainable coefficient, and added to a trainable bias. The result is passed through a sigmoided function. "。因此从原论文中下采样层认为是平均池化,激活函数用的是Sigmoid函数。
问题三:现在用的LeNet-5有3层全连接??
由于S4层的16个特征图的大小为(5, 5),与C5的卷积核的大小相同,所以卷积后形成的图的大小为1x1,因此C5可以认为是全连接层。
问题四:OUTPUT使用RBF???
RBF,也称径向基函数。现在的LeNet-5用softamx激活函数实现分类结果输出。
Keras实现LeNet-5网络
import keras
def LeNet(input_shape=None, classes=None):
inp = keras.layers.Input(input_shape) # 输入层
conv1 = keras.layers.Conv2D(filters=6, kernel_size=(5, 5),
strides=1, padding='valid',
activation='sigmoid')(inp) # 第一层卷积
pooling1 = keras.layers.AvgPool2D(pool_size=(2, 2),
strides=2,
padding='valid')(conv1) # 第一层池化
conv2 = keras.layers.Conv2D(filters=16, kernel_size=(5, 5),
strides=1, padding='valid',
activation='sigmoid')(pooling1) # 第二层卷积
pooling2 = keras.layers.AvgPool2D(pool_size=(2, 2),
strides=2,
padding='valid')(conv2) # 第二层池化
flatten = keras.layers.Flatten()(pooling2) # 扁平化
fc1 = keras.layers.Dense(120, activation='sigmoid')(flatten) # 第一个全连接层
fc2 = keras.layers.Dense(84, activation='sigmoid')(fc1) # 第二个全连接层
output = keras.layers.Dense(classes, activation='softmax')(fc2) # 第三个全连接层(输出层)
model = keras.models.Model(inp, output)
return model
卷积神经网络的优点
a)输入图像和网络的拓扑结构能很好的吻合;
b)特征提取和模式分类同时进行,并同时在训练中产生;
c)权重共享可以减少网络的训练参数,使神经网络结构变得更简单,适应性更强。
卷积网络在本质上是一种输入到输出的映射,它能够学习大量的输入与输出之间的映射关系,而不需要任何输入和输出之间的精确的数学表达式。
总结
通过对LeNet-5的网络结构的分析,可以直观地了解一个卷积神经网络的构建方法,可以为分析、构建更复杂、更多层的卷积神经网络做准备。