LeNet-5

LeNet-5简介

LeNet-5是1998年LeCun发表的用于手写字符识别的经典卷积神经网络模型。当年美国很多银行就采用了这种模型来识别支票上的手写数字,能够达到如此高的商业程度,可见其识别精准和在深度学习发展史上的重要地位。

LeNet-5在论文中被用于识别MNIST数据集提供的0~9共10个手写数字。MNIST是当时Google实验室的Corinna Cortes和纽约大学柯朗研究所的Yann LeCun共同建立的手写数字数据库,包含训练集60000张即测试集10000张手写数字图片。该数据集提供的图片尺寸统一为28*28,图中包含字符的最大尺寸为20*20。

231n中对LeNet的评价:

  • LeNet. The first successful applications of Convolutional Networks were developed by Yann LeCun in 1990’s. Of these, the best known is the LeNet architecture that was used to read zip codes, digits, etc.

LeNet-5详解

LeNet-5网络除输入层外包含7层,每层都含有可学习的参数。如下图所示,卷积层标记为 CxC_x ,下采样层标记为 SxS_x ,全连接层标记为 FxF_x ,其中 xx 表示层下标(这个下标是指的在网络中的顺序,不是第几个这样的层)。

输入:32*32的手写字体图片,这些手写字体包含0~9数字,也就是相当于10个类别的图片。网络输入是32*32像素的图片,这一尺寸明显大于MNIST提供的字符尺度(28*28)。这样设计的原因是希望如笔画末端或尖端等潜在的有效特征能够出现在最高层特征检测子感受野的中心位置,换句话说,网络高层的各个特征都集成了笔画和尖角边缘信息。在LeNet-5中,最后一个卷积层( C3C_3 )的所有感受野中心会在输入的32像素*32像素图片中形成一个20*20的区域。此外,还需对输入像素的取值进行标准化:白色背景取值 0.1-0.1 ,黑色前景取值 1.1751.175 ,这样使得在MNIST数据集上像素点取值均值近似为 00 ,方差近似为 11 。数据标准化能够有效地加速训练过程。

输出:分类结果,0~9之间的一个数。因此我们可以知道,这是一个多分类问题,总共有十个类,因此神经网络的最后输出层必然是SoftMax问题,然后神经元的个数是10个。

输入层

输入层:32*32的图片(因为是灰度图,所以其实是32*32*1),也就是相当于1024个神经元。

第一层(卷积)

C1C_1 层:是网络的第一个卷积层,paper这里选择6个卷积核,卷积核大小选择5*5,这样我们可以得到6个特征图,每个特征图大小为28*28(28=325+128=32-5+1),也就是神经元的个数为 62828=7846*28*28=784 。所以现在我们的维度从32*32*1变成了28*28*6

第二层(下采样)

S2S_2 层:是下采样层,也就数使用最大池化进行下采样,池化的大小选择 (2,2)(2,2) ,也就相当于对 C1C_1 层28*28的图片,进行分块(即邻域),每个块的大小为2*2,这样我们可以得到14*14个块,我们统计每个块中最大的值作为下采样的新像素,因此我们可以得到14*14大小的图片,共有6个这样的图片。至此,我们的维度从28*28*6变成了14*14*6。在最初的论文中,会将邻域里的4个值求和乘系数并加上一个偏置,所得结果再通过Sigmoid激活函数来产生 S2S_2 层的特征图。这里系数和偏置便是本层需要学习的参数。在后来的实现中,常用最大池化取代上述过程。

第三层(卷积-关键)

C3C_3 层:同样是卷积层,这一层卷积核大小仍未5*5,据此我们可以得到新的图片大小为10*10( 10=145+110 = 14-5+1 ),然后我们希望可以得到16张特征图,即我们的维度从14*14*6变成10*10*16。

那么问题来了,这一层是最难理解的,我们知道 S2S_2 包含:6张14*14大小的图片,我们希望这一层得到的结果是:16张10*10的图片。这16张图片的每一张,是通过 S2S_2 的6张图片进行加权组合得到的,具体怎么组合如下面所示:

前6个特征图与 S2S_2 层相连的3个特征图相连接,后面6个特征图与 S2S_2 层相连的4个特征图相连接,后面3个特征图与 S2S_2 层部分不相连的4个特征图相连接,最后一个与 S2S_2 层的所有特征图相连。卷积核大小仍然为5*5,所以共有 6(3551)+6(4551)+3(4551)+1(6551)=15166*(3*5*5*1)+6*(4*5*5*1)+3*(4*5*5*1)+1*(6*5*5*1)=1516 个参数,而不是 16(6551)=240016*(6*5*5*1)=2400 个参数。因为图像大小是10*10,所以共有 15161010=1516001516*10*10=151600 个连接而不是 24001010=2400002400*10*10=240000 个。每个 C3C_3 层的特征图只与部分 S2S_2 层的特征图进行连接,这样做有两个原因:

  • 部分不完全的连接能够将连接数控制在一个比较合理的范围内。

  • 更重要的是,它强制地打破了网络的对称性,不同的特征图由于输入不同而能够表达出不同的特征。

第四层(下采样)

S4S_4 层:也是下采样层,采用同样的下采样方式,得到16个5*5的特征图。我们的维度从10*10*16变成5*5*16。

第五层(卷积)

C5C_5 层:这一层是网络最后一个卷积层,具有120个特征图,每个特征图与 S4S_4 层所有的特征图相连接,卷积核大小是5*5,而 S4S_4 层的特征图大小也是 555*5 ,所以 C5C_5 层的特征图就变成了1*1大小的特征图。即维度从5*5*16变成1*1*120。共有 120(25161)=48120120*(25*16*1)=48120 个参数。

当特征图尺寸为1*1时, C5C_5 层等价于一个全连接层。但我们仍以卷积层来命名它,因为当输入图片尺寸增大时,网络结构不发生变化。

第六层(全连接)

F6F_6 层是与 C5C_5 层相连,包含84个单元的全连接层,即有 84(120+1)=1016484*(120+1)=10164个参数 。这一层采用了正切函数,即 xi=f(ai)=A tanh(Sai)x_i=f(a_i)=A\ \text{tanh}(Sa_i)

输出层

最后,输出层由每个类别对应一个欧几里得RBF(Euclidean Radial Basis Function)单元构成。每个RBF单元的输入均为 F6F_6 层的84个输出,输出计算公式如下:

yi=j(xiwij)2y_i=\sum\limits_j(x_i-w_{ij})^2

换言之,每个RBF单元计算的输入向量 xx 和参数向量 ww 之间的欧式距离,输入向量与参数向量之间的距离越远,RBF单元的输出越大。对于一个特定的RBF单元,其输出可以理解成衡量输入向量和对应类别之间匹配程度的一个惩罚项。从概率的观点看,RBF核的输出也可以理解成在由 F6F_6 层定义的高斯分布下一个未经归一化的负对数似然。由此,给定一个输入,损失函数将定义为使得 F6F_6 层输出尽量接近期望类别的RBF参数向量。采用这种方式,RBF单元的参数向量需要手动给出,并保持固定(至少在初始的时候),参数向量的每个元素取 1-111

事实上,在以后的实践中,RBF单元常常被Softmax所取代。

Code实现

def LeNet():
    model = Sequential()
    model.add(Conv2D(32,(5,5),strides=(1,1),input_shape=(28,28,1),padding='valid',activation='relu',kernel_initializer='uniform'))
    model.add(MaxPooling2D(pool_size=(2,2)))
    model.add(Conv2D(64,(5,5),strides=(1,1),padding='valid',activation='relu',kernel_initializer='uniform'))
    model.add(MaxPooling2D(pool_size=(2,2)))
    model.add(Flatten())
    model.add(Dense(100,activation='relu'))
    model.add(Dense(10,activation='softmax'))
    return model

Source

Last updated