深度学习: LeNet-5 网络模型小结
Posted TechArtisan6
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深度学习: LeNet-5 网络模型小结相关的知识,希望对你有一定的参考价值。
1989年,Yann Lecun在论文 Gradient-Based Learning Applied to Document Recognition 中提出了LeNet-5网络模型,它是一种用于手写体字符识别的非常高效的卷积神经网络。从此深度学习开始被人们所熟知。LeNet-5 网络架构的成功应用,不断地推动着深度学习领域的发展。
1 MNIST手写字体数据集
如下图所示,MNIST数据集是一个手写体数据集,该数据集是机器学习领域中非常经典的一个数据集,数据集中每一个样本都是 0 ~ 9 的手写数字,该数据集由 4 部分组成:训练图片集、训练标签集、测试图片集和测试标签集。其中,训练集中有60000个样本,测试集中有10000个样本,每个样本都是一张 28x28 像素的灰度手写数字图片。为了便于存储和下载,官方对 MNIST数据集的图片进行集中处理,将每一张图片拉伸成为 (1, 784) 的向量表示。
数据集官方网站:http://yann.lecun.com/exdb/mnist/
MNIST数据集一共4个文件,训练集、训练集标签、测试集 和 测试集标签.
2 LeNet-5 网络模型
LeNet-5 网络模型作为卷积神经网络中的开创性工作,提取了三大思想:
-
局部感知
-
权值共享
-
下采样
因为图像特征分布在图像的像素上,利用卷积操作可以在多个位置提取相类似的特征,于是有了局部感知。另外由于当年并没有计算能力强悍的 GPU 来辅助训练神经网络,因此通过下采样层有效地加快训练和提取更高维特征,能够节省参数和计算,这与当年的技术相比是一个关键的优势。另外原论文中提到,全卷积不应该被放在第一层,图像特征有着高度的空间相关性,因此权值共享可以充分利用图像上的空间相关性。
LeNet-5模型框图如下图所示:
LeNet-5共有7层,不包含输入层,每层都包含可训练参数;每个层有多个Feature Map,每个Feature Map通过一种卷积滤波器提取输入的一种特征,然后每个Feature Map有多个神经元。
(1) INPUT层首先是数据 INPUT 层,输入图像的尺寸统一归一化为 32x32。注:INPUT层不属于LeNet-5的网络结构,传统上,一般不将INPUT层视为网络层次结构之一。
(2) C1层 (卷积层)
输入图片:32x32 卷积核大小:5x5 卷积核种类:6 输出6个特征图(feature map),每个特征图的大小:28x28
特征图大小的计算公式如下:
其中, 为卷积操作后得到的特征矩阵的大小, 为输入矩阵的大小, 输入矩阵边界的填充数量, 为卷积核的大小, 为卷积操作的步长。 和 分别为操作矩阵的长和宽,一般来说矩阵为方阵时候, .
对于从 INPUT层 ——> C1层 (卷积层), , , , , ,则输出特征图大小为 (28x28):
神经元数量:28x28x6 可训练参数:(5x5+1) x 6=156 (每个滤波器5x5=25个unit参数和一个bias参数,一共6个滤波器) 连接数:(5x5+1)x6x28x28=122304
参数详细说明:对输入图像进行第一次卷积运算(使用 6 个大小为 5x5 的卷积核),得到6个C1特征图(6个大小为28x28的 feature maps, 32-5+1=28)。我们再来看看需要多少个参数,卷积核的大小为5x5,总共就有6x(5x5+1)=156个参数,其中+1是表示一个核有一个bias。
对于卷积层C1,C1内的每个像素都 与 输入图像中的5x5个像素和1个bias有连接,所以总共有 (5x5+1)x6 x 28x28=122304 个连接(connection)。有122304个连接,但是我们只需要学习156个参数,主要是通过权值共享实现的。
(3) S2层-(Pooling层)输入大小:28x28
采样区域:2x2
采样方式:4个输入相加,乘以一个可训练参数,再加上一个可训练偏置。结果通过sigmoid函数
采样种类:6
输出6个特征图(feature map),每个特征图的大小:14x14 (28/2)
神经元数量:14x14x6
连接数:(2x2+1)x6x14x14
S2中每个特征图的大小是C1中特征图大小的1/4。
参数详细说明:第一次卷积之后紧接着就是Pooling(池化)运算,使用 2x2核 进行Pooling操作,于是得到了S2,6个14x14的特征图(28/2=14)。
S2这个pooling层是对C1中的2x2区域内的像素求和乘以一个权值系数再加上一个偏置bias,然后将这个结果再做一次映射。故同时有(2x2+1)x6x14x14=5880个连接。
(4) C3层 (卷积层)输入大小:S2中所有6个或者几个特征图(feature map)组合
卷积核大小:5x5
卷积核种类:16
输出16个特征图(feature map),每个特征图的大小:10x10
特征图大小的计算过程如下:
C3中的每个特征图是连接到S2中的所有(6个)或者几个特征图的,表示本层的特征图是上一层提取到的特征图的不同组合。
存在的一个方式是:C3的前6个特征图以S2中3个相邻的特征图子集为输入。接下来6个特征图以S2中4个相邻特征图子集为输入。然后的3个以不相邻的4个特征图子集为输入。最后一个将S2中所有特征图为输入。
则可训练参数:6x(3x5x5+1) + 6x(4x5x5+1) + 3x(4x5x5+1) + 1x(6x5x5+1) =1516
连接数:10x10x1516=151600
参数详细说明:第一次Pooling之后是第二次卷积,第二次卷积的输出是C3,16个10x10的特征图,卷积核大小是 5x5 。我们知道S2 有6个 14x14 的特征图,那么问题来了,如何从6 个特征图得到 16个特征图了?
这里是通过对S2 的特征图特殊组合计算得到的16个特征图。如下图所示:
-
C3的前6个特征图(对应上图第1个红框的6列)与S2层相连的3个特征图相连接; -
C3的后面6个特征图(上图第2个红框)与S2层相连的4个特征图相连接; -
C3的后面3个特征图(上图第3个红框)与S2层部分不相连的4个特征图相连接; -
C3的最后一个特征图(上图第4个红框)与S2层的所有特征图相连。
卷积核大小依然为5x5,所以总共有:6x(3x5x5+1)+6x(4x5x5+1)+3x(4x5x5+1)+1x(6x5x5+1)=1516个参数。
因为图像大小为10x10,所以共有151600个连接。
C3的前6个特征图(上图第1个红框)与S2中前3个特征图相连的卷积结构如下图所示:
上图对应的参数为 3x5x5+1,一共进行6次卷积得到6个特征图,所以有6x(3x5x5+1)参数。
那么为什么采用上述这样的组合了?
论文中说有两个原因:
-
减少参数; -
这种不对称的组合连接的方式有利于提取多种组合特征。
(5) S4层 (Pooling层)输入大小:10x10
采样区域:2x2
采样方式:4个输入相加,乘以一个可训练参数,再加上一个可训练偏置。结果通过sigmoid
采样种类:16
输出16个特征图(feature map),每个特征图的大小:5x5 (10/2)
神经元数量:5x5x16=400
连接数:16x(2x2+1)x5x5=2000
S4中每个特征图的大小是C3中特征图大小的1/4
参数详细说明:S4是pooling层,窗口大小仍然是2x2,共计16个特征图(feature map),C3层的16个10x10的图分别进行以2x2为单位的Pooling操作得到16个5x5的特征图。所以共有5x5x5x16=2000个连接。连接的方式与S2层类似。
(6) C5层 (卷积层)输入大小:S4层的全部16个单元特征map(与s4全相连)
卷积核大小:5x5
卷积核种类:120
输出120个特征图(feature map),每个特征图的大小:1x1
可训练参数/连接:120x(16x5x5+1)=48120
参数详细说明:C5层是一个卷积层。由于S4层的16个图的大小为5x5,与卷积核的大小相同,所以卷积后形成的图的大小为1x1。
这里形成120个卷积结果。每个都与上一层的16个图相连。所以共有(5x5x16+1)x120 = 48120个参数,同样有48120个连接。
C5层的网络结构如下图所示:
(7) F6层 (全连接层)F6层与C5进行全连接
输入大小:C5层输出的 120维向量(120x1)
计算方式:计算输入向量和权重向量之间的点积,再加上一个偏置,结果通过sigmoid函数输出。
输出:84维向量(84x1)
可训练参数:84x(120+1)=10164
参数详细说明:F6层是全连接层。F6层有84个节点,对应于一个7x12的比特图,-1表示白色,1表示黑色,这样每个符号的比特图的黑白色就对应于一个编码。
该层的训练参数和连接数是 (120+1)x84=10164 。
ASCII编码图如下:
F6层的连接方式如下:
(8) Output层 (全连接层)Output层也是全连接层,共有10个节点,分别代表数字 0~9,且如果节点i的值为0,则网络识别的结果是数字 。采用的是径向基函数(RBF)的网络连接方式。假设 是上一层的输入, 是RBF的输出,则RBF输出的计算方式是:
其中, 的值由 的比特图编码确定, 从0~9, 取值从 0 到 7x12-1。RBF输出的值越接近于0,则越接近于 ,即越接近于 的ASCII编码图,表示当前网络输入的识别结果是字符 。该层有 84x10=840 个参数和连接。
下图是LeNet-5识别 图片数字3,每一层特征图可视化的过程。
3 实验
LeNet-5采用上图架构。共7层,分别为卷积 ——> 最大池化 ——> 卷积 ——> 最大池化 ——> 全连接x3 。保留了LeNet-5中的大部分细节,未加入dropout,最后一层改用softmax。
代码主要参考博客:https://blog.csdn.net/chai_zheng/article/details/79751020
代码如下
# !/usr/bin/env python3
# coding=utf-8
"""
LeNet-5 Using TensorFlow
Date : 2019.8.22
"""
import tensorflow.examples.tutorials.mnist.input_data as input_data
import tensorflow as tf
mnist = input_data.read_data_sets('./data/mnist/', one_hot=True) #读取路径下的数据集,如果路径下没有,就自动下载。
sess = tf.InteractiveSession()
x = tf.placeholder('float', shape=[None, 28*28])
y_true = tf.placeholder('float', shape=[None, 10])
x_image = tf.reshape(x, [-1, 28, 28, 1])
def weights(shape):
initial = tf.truncated_normal(shape, stddev=0.1)
return tf.Variable(initial)
def bias(shape):
initial = tf.constant(0.1, shape=shape)
return tf.Variable(initial)
def conv2d(x, W):
return tf.nn.conv2d(input=x, filter=W, strides=[1, 1, 1, 1], padding='SAME')
def max_pool_2x2(x):
return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
# 1st layer: conv + relu + max_pool
w_conv1 = weights([5, 5, 1, 6])
b_conv1 = bias([6])
h_conv1 = tf.nn.relu(conv2d(x_image, w_conv1)+b_conv1)
h_pool1 = max_pool_2x2(h_conv1)
# 2nd layer: conv + relu + max_pool
w_conv2 = weights([5, 5, 6, 16])
b_conv2 = bias([16])
h_conv2 = tf.nn.relu(conv2d(h_pool1, w_conv2)+b_conv2)
h_pool2 = max_pool_2x2(h_conv2)
h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*16])
# 3rd layer: 3*full connection
w_fc1 = weights([7*7*16, 120])
b_fc1 = bias([120])
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, w_fc1)+b_fc1)
w_fc2 = weights([120, 84])
b_fc2 = bias([84])
h_fc2 = tf.nn.relu(tf.matmul(h_fc1, w_fc2)+b_fc2)
w_fc3 = weights([84, 10])
b_fc3 = bias([10])
h_fc3 = tf.nn.softmax(tf.matmul(h_fc2, w_fc3)+b_fc3)
cross_entropy = -tf.reduce_sum(y_true*tf.log(h_fc3))
train_step = tf.train.AdamOptimizer(1e-3).minimize(cross_entropy)
correct_prediction = tf.equal(tf.argmax(h_fc3, 1), tf.argmax(y_true, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, 'float'))
sess.run(tf.global_variables_initializer())
for i in range(1000):
batch = mnist.train.next_batch(60)
if i%100 == 0:
train_accuracy = accuracy.eval(session=sess, feed_dict={x: batch[0], y_true: batch[1]})
print('step {}, training accuracy: {}'.format(i, train_accuracy))
train_step.run(session=sess, feed_dict={x: batch[0], y_true: batch[1]})
print('test accuracy: {}'.format(accuracy.eval(session=sess, feed_dict={x: mnist.test.images, y_true:
mnist.test.labels})))
运行结果如下
4 小结
如上图所示,对照着上图,对每层重要的参数进行总结:
(1) INPUT层
输入图像的尺寸统一归一化为 32x32。
(2) C1层 (卷积层)
输入图片:32x32
卷积核大小:5x5
卷积核种类:6
输出6个特征图(feature map),每个特征图的大小:28x28
(3) S2层-(Pooling层)
输入大小:28x28
采样区域:2x2
采样方式:4个输入相加,乘以一个可训练参数,再加上一个可训练偏置。结果通过sigmoid函数
采样种类:6
输出6个特征图(feature map),每个特征图的大小:14x14 (28/2)
(4) C3层 (卷积层)
输入大小:S2中所有6个或者几个特征图(feature map)组合
卷积核大小:5x5
卷积核种类:16
输出16个特征图(feature map),每个特征图的大小:10x10
(5) S4层(Pooling层)
输入大小:10x10
采样区域:2x2
采样方式:4个输入相加,乘以一个可训练参数,再加上一个可训练偏置。结果通过sigmoid
采样种类:16
输出16个特征图(feature map),每个特征图的大小:5x5 (10/2)
(7) F6层 (全连接层)
F6层与C5进行全连接
输入大小:C5层输出的 120维向量(120x1)
计算方式:计算输入向量和权重向量之间的点积,再加上一个偏置,结果通过sigmoid函数输出。
输出:84维向量(84x1)
(8) Output层 (全连接层)输入:84维向量(84x1)
输出:10维向量(10x1),代表所抽取的特征属于哪个类别
LeNet-5网络模型特点
-
LeNet-5是一种用于手写体字符识别的非常高效的卷积神经网络; -
卷积神经网络能够很好的利用图像的结构信息; -
卷积层的参数较少,这也是由卷积层的主要特性即局部连接和共享权重所决定。
参考资料
[1] 图解深度学习
[2] 深度学习原理与实践
[3] TensorFlow实战Google深度学习框架(第2版)
[4] 网络解析(一):LeNet-5详解 | Jack Cui
[5] LeNet-5及其TensorFlow实现
2 CSDN博客:https://xiongyiming.blog.csdn.net/
3 知乎:https://www.zhihu.com/people/xiongyiming
以上是关于深度学习: LeNet-5 网络模型小结的主要内容,如果未能解决你的问题,请参考以下文章
深度学习100例-卷积神经网络(LeNet-5)深度学习里的“Hello Word” | 第22天
深度学习100例-卷积神经网络(LeNet-5)深度学习里的“Hello Word” | 第22天