文章作者:Tyan
博客:noahsnail.com | CSDN | 简书
1. LeNet神经网络介绍
LeNet神经网络由深度学习三巨头之一的Yan LeCun提出,他同时也是卷积神经网络 (CNN,Convolutional Neural Networks)之父。LeNet主要用来进行手写字符的识别与分类,并在美国的银行中投入了使用。LeNet的实现确立了CNN的结构,现在神经网络中的许多内容在LeNet的网络结构中都能看到,例如卷积层,Pooling层,ReLU层。虽然LeNet早在20世纪90年代就已经提出了,但由于当时缺乏大规模的训练数据,计算机硬件的性能也较低,因此LeNet神经网络在处理复杂问题时效果并不理想。虽然LeNet网络结构比较简单,但是刚好适合神经网络的入门学习。
2. LeNet神经网络结构
LeNet的神经网络结构图如下:
LeNet网络图LeNet网络的执行流程图如下:
LeNet图像处理流程2.1 LeNet第一层(卷积运算)
接下来我们来具体的一层层的分析LeNet的网络结构。首先要了解图像(输入数据)的表示。在LeNet网络中,输入图像是手写字符,图像的表示形式为二维数据矩阵,如下图所示:
图像的表示LeNet网络除去输入输出层总共有六层网络。第一层是卷积层(C1层),卷积核的大小为5\*5
,卷积核数量为6
个,输入图像的大小为32*32
,因此输入数据在进行第一层卷积之后,输出结果为大小为28*28
,数量为6
个的feature map。卷积操作如下面两幅图所示:
卷积操作的过程可描述为:卷积核在图像上滑动,滑动步长为1(即每次移动一格,水平方向从左到右,到最右边之后再从最左边开始,向下移动一格,重复从左到右滑动),当卷积核与图像的一个局部块重合时进行卷积运行,卷积计算方式为图像块对应位置的数与卷积核对应位置的数相乘,然后将所有相乘结果相加即为feature map的值,相乘累加之后的结果位于卷积核中心点的位置,因此如果是3\*3
的卷积核,feature map比原图像在水平和垂直方向上分别减少两行(上下各一行)和两列(左右各一列),因此上面图像原图为5*5
,卷积核为3\*3
,卷积结果大小为3*3
,即(5-2)*(5-2)
,如果卷积核为5*5
,则卷积结果大小为(5-4)*(5-4)
。上图中的卷积核为:
由于神经网络层与层的结构是通过连接来实现的,因此输入层与第一个卷积层的连接数量应为(32-2-2)\*(32-2-2)\*(5\*5+1)\*6= 28\*28\*156 =122304
。
卷积的作用主要是:通过卷积运算,可以使原信号特征增强,并且降低噪音。在图像上卷积之后主要是减少图像噪声,提取图像的特征。例如sobel算子就是一种卷积运算,主要是提取图像的边缘特征。卷积网络能很好地适应图像的平移不变性:例如稍稍移动一幅猫的图像,它仍然是一幅猫的图像。卷积操作保留了图像块之间的空间信息,进行卷积操作的图像块之间的相对位置关系没有改变。图像在不同卷积核上进行卷积之后的效果图如下:
同一幅图像用不同卷积核处理的效果2.2 LeNet第二层(pooling运算)
图像在LeNet网络上进行第一层卷积之后,结果为大小为28*28
,数量为6
个的feature map。LeNet网络的第二层为pooling层(S2层),也称为下采样。在图像处理中,下采样之后,图像的大小会变为原来的1/4
,即水平方向和垂直方向上图像大小分别减半。Pooling有多种,这里主要介绍两种,max-pooling和average-pooling。max-pooling即为从四个元素中选取一个最大的来表示这四个元素,average-pooling则用四个元素的平均值来表示这四个元素。Pooling示意图如下:
在LeNet在进行第二层Pooling运算后,输出结果为14*14
的6
个feature map。其连接数为(2*2+1) * 14 * 14 *6 = 5880
。Pooling层的主要作用就是减少数据,降低数据纬度的同时保留最重要的信息。在数据减少后,可以减少神经网络的纬度和计算量,可以防止参数太多过拟合。LeNet在这一层是将四个元素相加,然后乘以参数w再加上偏置b,然后计算sigmoid值。
2.3 LeNet第三层(卷积运算)
LeNet第三层(C3层)也是卷积层,卷积核大小仍为5*5
,不过卷积核的数量变为16
个。第三层的输入为14*14
的6
个feature map,卷积核大小为5*5
,因此卷积之后输出的feature map大小为10*10
,由于卷积核有16
个,因此希望输出的feature map也为16
个,但由于输入有6
个feature map,因此需要进行额外的处理。输入的6
个feature map与输出的16
个feature map的关系图如下:
如上图所示,第一个卷积核处理前三幅输入的feature map,得出一个新的feature map。
2.4 LeNet第四层(Pooling运算)
上一层卷积运算之后,结果为大小为10*10
的16
个feature map,因此在第四层(S4层)进行pooling运算之后,输出结果为16
个大小为5*5
的feature map。与S2层进行同样的操作。
2.5 LeNet第五层
LeNet第五层是卷积层(C5层),卷积核数目为120个,大小为5*5
,由于第四层输出的feature map大小为5*5
,因此第五层也可以看成全连接层,输出为120个大小为1*1
的feature map。
2.6 LeNet第六层
LeNet第六层是全连接层(F6层),有84个神经元(84与输出层的设计有关),与C5层全连接。
2.7 LeNet各层的参数变化
-
C1
输入大小:32*32
核大小:5*5
核数目:6
输出大小:28*28*6
训练参数数目:(5*5+1)*6=156
连接数:(5*5+1)*6*(32-2-2)*(32-2-2)=122304 -
S2
输入大小:28*28*6
核大小:2*2
核数目:1
输出大小:14*14*6
训练参数数目:2*6=12,2=(w,b)
连接数:(2*2+1)*1*14*14*6 = 5880 -
C3
输入大小:14*14*6
核大小:5*5
核数目:16
输出大小:10*10*16
训练参数数目:6*(3*5*5+1) + 6*(4*5*5+1) + 3*(4*5*5+1) + 1*(6*5*5+1)=1516
连接数:(6*(3*5*5+1) + 6*(4*5*5+1) + 3*(4*5*5+1) + 1*(6*5*5+1))*10*10=151600 -
S4
输入大小:10*10*16
核大小:2*2
核数目:1
输出大小:5*5*16
训练参数数目:2*16=32
连接数:(2*2+1)*1*5*5*16=2000 -
C5
输入大小:5*5*16
核大小:5*5
核数目:120
输出大小:120*1*1
训练参数数目:(5*5*16+1)*120*1*1=48120(因为是全连接)
连接数:(5*5*16+1)*120*1*1=48120 -
F6
输入大小:120
输出大小:84
训练参数数目:(120+1)*84=10164
连接数:(120+1)*84=10164
3. LeNet在Caffe中的配置
LeNet神经网络结构在Caffe中的配置文件如下:
name: "LeNet"
layer {
name: "mnist"
type: "Data"
top: "data"
top: "label"
include {
phase: TRAIN
}
transform_param {
scale: 0.00390625
}
data_param {
source: "examples/mnist/mnist_train_lmdb"
batch_size: 64
backend: LMDB
}
}
layer {
name: "mnist"
type: "Data"
top: "data"
top: "label"
include {
phase: TEST
}
transform_param {
scale: 0.00390625
}
data_param {
source: "examples/mnist/mnist_test_lmdb"
batch_size: 100
backend: LMDB
}
}
layer {
name: "conv1"
type: "Convolution"
bottom: "data"
top: "conv1"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
convolution_param {
num_output: 20
kernel_size: 5
stride: 1
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "pool1"
type: "Pooling"
bottom: "conv1"
top: "pool1"
pooling_param {
pool: MAX
kernel_size: 2
stride: 2
}
}
layer {
name: "conv2"
type: "Convolution"
bottom: "pool1"
top: "conv2"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
convolution_param {
num_output: 50
kernel_size: 5
stride: 1
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "pool2"
type: "Pooling"
bottom: "conv2"
top: "pool2"
pooling_param {
pool: MAX
kernel_size: 2
stride: 2
}
}
layer {
name: "ip1"
type: "InnerProduct"
bottom: "pool2"
top: "ip1"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
inner_product_param {
num_output: 500
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "relu1"
type: "ReLU"
bottom: "ip1"
top: "ip1"
}
layer {
name: "ip2"
type: "InnerProduct"
bottom: "ip1"
top: "ip2"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
inner_product_param {
num_output: 10
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "accuracy"
type: "Accuracy"
bottom: "ip2"
bottom: "label"
top: "accuracy"
include {
phase: TEST
}
}
layer {
name: "loss"
type: "SoftmaxWithLoss"
bottom: "ip2"
bottom: "label"
top: "loss"
}
参考资料:
1.https://ujjwalkarn.me/2016/08/11/intuitive-explanation-convnets/
网友评论