卷积神经网络CNN

卷积神经网络

图像处理中,往往会将图像看成是一个或者多个二维向量,传统的神经网络采用全联接的方式,即输入层到隐藏层的神经元都是全部连接的,这样做将导致参数量巨大,使得网络训练耗时甚至难以训练,而CNN则通过局部链接、权值共享等方法避免这一困难。

局部连接(Sparse Connectivity)与权值共享(Shared Weights)

下图是一个很经典的图示,左边是全连接,右边是局部连接。

 

卷积神经网络CNN_第1张图片

卷积神经网络

Lenet-5是Lecun大神在1998年提出的卷积网络模型,共有7层(除输入层)。本文主要详细介绍卷积层与池化层,及其在caffe中的网络描述,最后介绍Lenet-5网络在数字识别方面的应用。

Lenet网络结构:

 

 

卷积神经网络CNN_第2张图片

预处理

去均值:把输入数据各个维度都中心化到0

归一化:幅度归一化到同一范围

 

卷积神经网络CNN_第3张图片

卷积操作

卷积特征提取的过程

卷积核为3x3,则 3×3 的数据作为输入,且假设这个隐藏层有 k 个单元(每个单元也被称为一个卷积核 - Convolution Kernel,由对应的权值向量 W 和 b 来体现)。

每个隐藏单元的输入是用自己的权值向量 W 与 3×3 的小图做内积,再与偏置相加得到的:

http://static.oschina.net/uploads/space/2015/1223/175518_yszG_1047422.png

假如深度网络的输入是 5×5 的大图,SAE 要从中提取特征,必须将 5×5 的大图分解成若干 3×3 的小图并分别提取它们的特征。分解方法就是:从大图的 (1, 1)、(1, 2)、(1, 3)、...  、(3, 3)等 9 个点开始分别作为小图的左上角起点,依次截取 9 张带有重合区域的小图,然后分别提取这 9 张小图的特征:

卷积神经网络CNN_第4张图片

所以,每个隐藏单元将有 9 个输入,不同于之前的 1 个。然后将所有输入分别导入激活函数计算相应的输出,卷积特征提取的工作就完成了。

池化(Pooling)

池化过程

在隐藏层这个矩阵上划分出几个不重合的区域,然后在每个区域上计算该区域内特征的均值或最大值,然后用这些均值或最大值参与后续的训练,这个过程就是【池化】。

卷积神经网络CNN_第5张图片

池化的优点

  1. 显著减少了参数数量
  2. 池化单元具有平移不变性 (translation invariant)

有一个 12×12 的 feature map (隐藏层的一个单元提取到的卷积特征矩阵),池化区域的大小为 6×6,那么池化后,feature map 的维度变为 2×2。

卷积神经网络CNN_第6张图片

假设原 feature map 中灰色元素的值为 1,白色元素的值为 0。如果采用 max pooling,那么池化后左上角窗口的值为 1。如果将图像向右平移一个像素:

卷积神经网络CNN_第7张图片

池化后左上角窗口的值还是 1。如果将图像缩小:

卷积神经网络CNN_第8张图片

池化后左上角窗口的值依然是 1。

通常我们认为图像经过有限的平移、缩放、旋转,不应改变其识别结果,这就要求经过平移、缩放、旋转的图片所提取的特征与原图所提取的特征相同或相似,因此分类器才能把它们识别成同一类

线性整流层(Rectified Linear Units layer, ReLU layer)--激励层
   把卷积层输出结果做非线性映射。

https://images2015.cnblogs.com/blog/1093303/201704/1093303-20170430194934006-705271151.jpg


    CNN采用的激励函数一般为ReLU(The Rectified Linear Unit/修正线性单元),它的特点是收敛快,求梯度简单,但较脆弱,图像如下。

https://images2015.cnblogs.com/blog/1093303/201704/1093303-20170430194958725-2144325242.png

 

激励层的实践经验:
  ①慎用sigmoid
  ②
尝试使用RELU,Leaky ReLU因为快

全连接层

全连接层就是把所有局部特征结合变成全局特征,用来计算最后每一类的得分,一般接在池化层后面。

参数计算

全连结网络

例如传统神经网络:

卷积神经网络CNN_第9张图片

  如果一个图像的尺寸是(32,32,1),即代表这个图像的是一个长宽均为32,channel为1的图像(channel也叫depth,此处1代表灰色图像)。如果使用全连接的网络结构,即,网络中的神经与与相邻层上的每个神经元均连接,那就意味着我们的网络有32 * 32 =1024个神经元,hidden层采用了15个神经元,那么简单计算一下,我们需要的参数个数(w和b)就有:1024*15*10+15+10=153625个

卷积神经网络

卷积神经网络CNN_第10张图片

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

  连接方式:

卷积神经网络CNN_第11张图片

      参数个数:(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

卷积神经网络CNN_第12张图片

 

训练算法:

BGDSGD、MBGD、Momentum、NAG、Adagrad、Adadelta、RMSpropAdam

https://www.cnblogs.com/guoyaohua/p/8542554.html

 

数据层:

1.原图尺寸大小输入

2.进行padding处理输入:这样做的目的是为了保证输入图像的所有内容。

3.一般进行归一化(幅度归一化到同样的范围),减均值(把数据各个维度都中心化到0)等预处理操作。

接下来我们考虑数据层在caffe的实现:

  1. 数据来源

数据库(LevelDB和LMDB)、图像、内存、HDF5等,在这只介绍来源于图像,其他的可查看《caffe官方教程中译本》

  • 来源于数据库(LevelDB和LMDB):

      其中制作成的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(训练数据集)两个文件夹组成:

 

卷积神经网络CNN_第13张图片

其中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:用一个配置文件进行

#均值操作

#mirror1表示开启镜像,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_heightnew_width:如果设置,

#则将图像进行resize

    new_height:28

    new_width:28

   root_folder: "F:/deep_learning/

lenet/"

  }

}

卷积层:

我们利用一个3*3的卷积核对一5*5的矩阵(图像)进行卷积来说明卷积的具体操作,

 1.输出卷积特征大小:

  • 图像大小:5*5
  • Padding:为0,没有进行边缘填充操作
  • 卷积核大小:3*3
  • 卷积步长:1,隔一个像素点
  • 利用如下公式可以确定输出特征的大小为3*3

    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的矩阵进行池化来说明池化的具体操作,如下图:

  1. 池化结果大小:

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,可选MAXAVESTOCHASTIC

pool: MAX

#池化核大小

kernel_size: 2

#池化步长

stride: 2

#pad:进行边缘填充

  }

}

 

你可能感兴趣的:(deep,learning,CNN)