卷积神经网络
图像处理中,往往会将图像看成是一个或者多个二维向量,传统的神经网络采用全联接的方式,即输入层到隐藏层的神经元都是全部连接的,这样做将导致参数量巨大,使得网络训练耗时甚至难以训练,而CNN则通过局部链接、权值共享等方法避免这一困难。
局部连接(Sparse Connectivity)与权值共享(Shared Weights)
下图是一个很经典的图示,左边是全连接,右边是局部连接。
卷积神经网络
Lenet-5是Lecun大神在1998年提出的卷积网络模型,共有7层(除输入层)。本文主要详细介绍卷积层与池化层,及其在caffe中的网络描述,最后介绍Lenet-5网络在数字识别方面的应用。
Lenet网络结构:
预处理
去均值:把输入数据各个维度都中心化到0
归一化:幅度归一化到同一范围
卷积操作
卷积特征提取的过程
卷积核为3x3,则 3×3 的数据作为输入,且假设这个隐藏层有 k 个单元(每个单元也被称为一个卷积核 - Convolution Kernel,由对应的权值向量 W 和 b 来体现)。
每个隐藏单元的输入是用自己的权值向量 W 与 3×3 的小图做内积,再与偏置相加得到的:
假如深度网络的输入是 5×5 的大图,SAE 要从中提取特征,必须将 5×5 的大图分解成若干 3×3 的小图并分别提取它们的特征。分解方法就是:从大图的 (1, 1)、(1, 2)、(1, 3)、... 、(3, 3)等 9 个点开始分别作为小图的左上角起点,依次截取 9 张带有重合区域的小图,然后分别提取这 9 张小图的特征:
所以,每个隐藏单元将有 9 个输入,不同于之前的 1 个。然后将所有输入分别导入激活函数计算相应的输出,卷积特征提取的工作就完成了。
池化(Pooling)
池化过程
在隐藏层这个矩阵上划分出几个不重合的区域,然后在每个区域上计算该区域内特征的均值或最大值,然后用这些均值或最大值参与后续的训练,这个过程就是【池化】。
池化的优点
有一个 12×12 的 feature map (隐藏层的一个单元提取到的卷积特征矩阵),池化区域的大小为 6×6,那么池化后,feature map 的维度变为 2×2。
假设原 feature map 中灰色元素的值为 1,白色元素的值为 0。如果采用 max pooling,那么池化后左上角窗口的值为 1。如果将图像向右平移一个像素:
池化后左上角窗口的值还是 1。如果将图像缩小:
池化后左上角窗口的值依然是 1。
通常我们认为图像经过有限的平移、缩放、旋转,不应改变其识别结果,这就要求经过平移、缩放、旋转的图片所提取的特征与原图所提取的特征相同或相似,因此分类器才能把它们识别成同一类
线性整流层(Rectified Linear Units layer, ReLU layer)--激励层
把卷积层输出结果做非线性映射。
CNN采用的激励函数一般为ReLU(The Rectified Linear Unit/修正线性单元),它的特点是收敛快,求梯度简单,但较脆弱,图像如下。
激励层的实践经验:
①慎用sigmoid
② 尝试使用RELU,Leaky ReLU因为快
全连接层就是把所有局部特征结合变成全局特征,用来计算最后每一类的得分,一般接在池化层后面。
全连结网络
例如传统神经网络:
如果一个图像的尺寸是(32,32,1),即代表这个图像的是一个长宽均为32,channel为1的图像(channel也叫depth,此处1代表灰色图像)。如果使用全连接的网络结构,即,网络中的神经与与相邻层上的每个神经元均连接,那就意味着我们的网络有32 * 32 =1024个神经元,hidden层采用了15个神经元,那么简单计算一下,我们需要的参数个数(w和b)就有:1024*15*10+15+10=153625个
卷积神经网络
Input: 图像大小为32*32
C1: bottom:1*32*32,kernel:6*5*5,top:6*28*28
参数个数:(5*5+1)*6
S2: bottom:6*28*28,kernel:2*2,top :6*14*14
参数个数:(1+1)*6
C3:bottom:6*14*14,kernel:16*5*5,top:16*10*10
连接方式:
参数个数:(5*5*3+1)*6+(5*5*4+1)*9+5*5*6+1
S4: bottom:16*10*10,kernel:2*2,top:16*5*5
参数个数:(1+1)*16
C5:bottom:16*5*5,kernel:120*5*5,top:120*1*1
参数个数:(5*5*16+1)*120
F6:bottom:120*1*1,top:86*1*1
参数个数:86*120
输出: bottom:86*1*1,top:10*1*1
参数个数:86*10
https://www.cnblogs.com/guoyaohua/p/8542554.html
数据层:
1.原图尺寸大小输入
2.进行padding处理输入:这样做的目的是为了保证输入图像的所有内容。
3.一般进行归一化(幅度归一化到同样的范围),减均值(把数据各个维度都中心化到0)等预处理操作。
接下来我们考虑数据层在caffe的实现:
数据库(LevelDB和LMDB)、图像、内存、HDF5等,在这只介绍来源于图像,其他的可查看《caffe官方教程中译本》
其中制作成的LevelDB数据存放在examples/mnist下
layer { name: "mnist" type: "Data" top: "data" top: "label" include { phase: TRAIN } transform_param { scale: 0.00390625 } data_param { source: "examples/mnist/mnist_train_leveldb" batch_size: 64 #选择采用LevelDB还是LMDB,默认是LevelDB backend: LEVELDB } } |
其中数据路径为:F:\deep_learning\lenet下的mnist文件下,由test(测试数据集)与train(训练数据集)两个文件夹组成:
其中0-9文件夹下为每一类的图像;labels.txt为标签0-9;train.txt由路径和标签组成如
layer { name: "mnist" type: "ImageData" top: "data" top: "label" include {#指定训练or测试状态 phase: TRAIN } transform_param {#数据预处理 scale: 0.00390625 #1/255 #mean_file_size:用一个配置文件进行 #均值操作 #mirror:1表示开启镜像,0表示关闭 } image_data_param { #source:一个文本文件的名字,每一行 #给定图像文件夹的名称和标签 source: "F:/deep_learning/lenet/ mnist/train/train.txt" #batch_size:每一次处理的数据个数, #即图像数 batch_size: 64 #可选参数: #rand_skip:在开始时略过某个数据的 #输入,通常对异步SGD很有用 #shuffle:随即打乱顺序,默认false #new_height,new_width:如果设置, #则将图像进行resize new_height:28 new_width:28 root_folder: "F:/deep_learning/ lenet/" } } |
卷积层:
我们利用一个3*3的卷积核对一5*5的矩阵(图像)进行卷积来说明卷积的具体操作,
1.输出卷积特征大小:
2.对应矩阵点乘求和进行填充输出矩阵元素
layer { name: "conv1" type: "Convolution" bottom: "data" top: "conv1" #param { # lr_mult: 1 权值学习率系数,最终的学习率是这个数乘以solver.prototxt配置文件中的base_lr # } # param { # lr_mult: 2 偏置学习系数 # } convolution_param { #卷积核的个数 num_output: 20 #卷积核大小 kernel_size: 5 #卷积核步长 stride: 1 #pad:扩充边缘,默认为0,不扩充 # weight_filler权值初始化,默认为constant值全为0 weight_filler { type: "xavier" } # bias_filler偏置初始化 bias_filler { type: "constant" } } } |
池化层(下采样层):
池化主要有三种方法:Max-pooling,Mean-pooling与Stochastic-pooling。我们利用一个4*4的矩阵进行池化来说明池化的具体操作,如下图:
l 图像大小:4*4
l Padding:为0,没有进行边缘填充操作
l 池化核大小:2*2
l 池化步长:2
l 利用如下公式可以确定输出特征的大小为2*2
2.对池化核大小内(即2*2)的元素进行求最大值,均值,以最大概率取值,填充到池化结果矩阵中。
layer { name: "pool1" type: "Pooling" bottom: "conv1" top: "pool1" pooling_param { #池化方法,默认Max,可选MAX,AVE或STOCHASTIC pool: MAX #池化核大小 kernel_size: 2 #池化步长 stride: 2 #pad:进行边缘填充 } } |