卷积神经网络的基本结构大致包括:卷积层、激活函数、池化层、全连接层、输出层等。
二维卷积运算:给定二维的图像I作为输入,二维卷积核K,卷积运算可表示为 S ( i , j ) = ( I ∗ K ) ( i , j ) = ∑ m ∑ n I ( i − m , j − n ) K ( m , n ) S(i, j)=(I * K)(i, j)=\sum_{m} \sum_{n} I(i-m, j-n) K(m, n) S(i,j)=(I∗K)(i,j)=∑m∑nI(i−m,j−n)K(m,n),卷积核需要进行上下翻转和左右反转
S ( i , j ) = sum ( I ( i − 2 , j − 2 ) I ( i − 2 , j − 1 ) I ( i − 2 , j ) I ( i − 1 , j − 2 ) I ( i − 1 , j − 1 ) I ( i − 1 , j ) I ( i , j − 2 ) I ( i , j − 1 ) I ( i , j ) ] . ∗ [ K ( 2 , 2 ) K ( 2 , 1 ) K ( 2 , 0 ) K ( 1 , 2 ) K ( 1 , 1 ) K ( 1 , 0 ) K ( 0 , 2 ) K ( 0 , 1 ) K ( 0 , 0 ) ] ) \left.S(i, j)=\operatorname{sum}\left(\begin{array}{ccc}I(i-2, j-2) & I(i-2, j-1) & I(i-2, j) \\ I(i-1, j-2) & I(i-1, j-1) & I(i-1, j) \\ I(i, j-2) & I(i, j-1) & I(i, j)\end{array}\right] . *\left[\begin{array}{rll}K(2,2) & K(2,1) & K(2,0) \\ K(1,2) & K(1,1) & K(1,0) \\ K(0,2) & K(0,1) & K(0,0)\end{array}\right]\right) S(i,j)=sum⎝⎛I(i−2,j−2)I(i−1,j−2)I(i,j−2)I(i−2,j−1)I(i−1,j−1)I(i,j−1)I(i−2,j)I(i−1,j)I(i,j)⎦⎤.∗⎣⎡K(2,2)K(1,2)K(0,2)K(2,1)K(1,1)K(0,1)K(2,0)K(1,0)K(0,0)⎦⎤⎠⎞
卷积实际上就是互相关
卷积的步长(stride):卷积核移动的步长
卷积的模式:Full**,** Same和Valid
数据填充:如果我们有一个 × 的图像,使用× 的卷积核进行卷积操作,在进行卷积操作之前我们在图像周围填充 层数据,输出的维度:
感受野:卷积神经网络每一层输出的特征图(featuremap)上的像素点在输 入图片上映射的区域大小,即特征图上的一个点对应输入图上的区 域。
那么如何计算感受野的大小,可以采用从后往前逐层的计算方法:
卷积层的深度(卷积核个数):一个卷积层通常包含多个尺寸一致的卷积核
【卷积核的大小一般为奇数奇数】 11,33,55,77都是最常见的。这是为什么呢?为什么没有偶数偶数?
(1)更容易padding
在卷积时,我们有时候需要卷积前后的尺寸不变。这时候我们就需要用到padding。假设图像的大小,也就是被卷积对象的大小为nn,卷积核大小为kk,padding的幅度设为(k-1)/2时,卷积后的输出就为(n-k+2*((k-1)/2))/1+1=n,即卷积输出为n*n,保证了卷积前后尺寸不变。但是如果k是偶数的话,(k-1)/2就不是整数了。
(2)更容易找到卷积锚点
在CNN中,进行卷积操作时一般会以卷积核模块的一个位置为基准进行滑动,这个基准通常就是卷积核模块的中心。若卷积核为奇数,卷积锚点很好找,自然就是卷积模块中心,但如果卷积核是偶数,这时候就没有办法确定了,让谁是锚点似乎都不怎么好。
激活函数是用来加入非线性因素,提高网络表达能力,卷积神经网络中最常用的是ReLU,Sigmoid使用较少。
1. ReLU函数
f ( x ) = { 0 , x < 0 x , x ≥ 0 f(x)=\left\{\begin{array}{l}0, x<0 \\ x, x \geq 0\end{array}\right. f(x)={ 0,x<0x,x≥0
ReLU函数的优点:
ReLU函数的缺点:
2. Parametric ReLU
f ( x ) = { α x , x < 0 x , x ≥ 0 f(x)=\left\{\begin{array}{l}\alpha x, x<0 \\ x, x \geq 0\end{array}\right. f(x)={ αx,x<0x,x≥0
PReLU函数的优点:
PReLU函数的缺点:需要再学习一个参数,工作量变大
3. ELU函数
f ( x ) = { α ( e x − 1 ) , x < 0 x , x ≥ 0 f(x)=\left\{\begin{array}{l}\alpha (e^x-1), x<0 \\ x, x \geq 0\end{array}\right. f(x)={ α(ex−1),x<0x,x≥0
ELU函数的优点:
ELU函数的缺点:计算量较大,收敛速度较慢
特征图
池化操作使用某位置相邻输出的总体统计特征作为该位置 的输出,常用最大池化**(max-pooling)和均值池化(average- pooling)**。
池化层不包含需要训练学习的参数,仅需指定池化操作的核大小、操作步幅以及池化类型。
池化的作用:
对于分类问题:使用Softmax函数
y i = e z i ∑ i = 1 n e z i y_i = \frac{e^{z_i}}{\sum_{i = 1}^{n}e^{z_i}} yi=∑i=1neziezi
对于回归问题:使用线性函数
y i = ∑ m = 1 M w i m x m y_i = \sum_{m = 1}^{M}w_{im}x_m yi=m=1∑Mwimxm
Step 1:用随机数初始化所有的卷积核和参数/权重
Step 2:将训练图片作为输入,执行前向步骤(卷积, ReLU,池化以及全连接层的前向传播)并计算每个类别的对应输出概率。
Step 3:计算输出层的总误差
Step 4:反向传播算法计算误差相对于所有权重的梯度,并用梯度下降法更新所有的卷积核和参数/权重的值,以使输出误差最小化
注:卷积核个数、卷积核尺寸、网络架构这些参数,是在 Step 1 之前就已经固定的,且不会在训练过程中改变——只有卷 积核矩阵和神经元权重会更新。
和多层神经网络一样,卷积神经网络中的参数训练也是使用误差反向传播算法,关于池化层的训练,需要再提一下,是将池化层改为多层神经网络的形式
将卷积层也改为多层神经网络的形式
输入图片的尺寸:一般用n*n表示输入的image大小。
卷积核的大小:一般用 f*f 表示卷积核的大小。
填充(Padding):一般用 p 来表示填充大小。
步长(Stride):一般用 s 来表示步长大小。
输出图片的尺寸:一般用 o来表示。
如果已知n 、 f 、 p、 s 可以求得 o ,计算公式如下:
其中"[ ]"是向下取整符号,用于结果不是整数时进行向下取整。
LeNet-5由LeCun等人提出于1998年提出,主要进行手写数字识别和英文字母识别。经典的卷积神经网络,LeNet虽小,各模块齐全,是学习 CNN的基础。
参考:http://yann.lecun.com/exdb/lenet/
Y. LeCun, L. Bottou, Y. Bengio, and P. Haffner. Gradient-based learning applied to document recognition. Proceedings of the IEEE, November 1998.
网络结构
输入层: 32 ∗ 32 32*32 32∗32 的图片,也就是相当于1024个神经元
C1层(卷积层):选择6个 5 ∗ 5 5*5 5∗5 的卷积核,得到6个大小为32-5+1=28的特征图,也就是神经元的个数为 6 ∗ 28 ∗ 28 = 4704 6*28*28=4704 6∗28∗28=4704
S2层(下采样层):每个下抽样节点的4个输入节点求和后取平均(平均池化),均值 乘上一个权重参数加上一个偏置参数作为激活函数的输入,激活函数的输出即是下一层节点的值。池化核大小选择 2 ∗ 2 2*2 2∗2,得到6个 14 ∗ 14 14*14 14∗14 大小特征图
C3层(卷积层):用 5 ∗ 5 5*5 5∗5的卷积核对S2层输出的特征图进行卷积后,得到6张 10 ∗ 10 10*10 10∗10 新 图片,然后将这6张图片相加在一起,然后加一个偏置项b,然后用 激活函数进行映射,就可以得到1张 10 ∗ 10 10*10 10∗10 的特征图。我们希望得到 16 张 10 ∗ 10 10*10 10∗10 的 特 征 图 , 因 此 我 们 就 需 要 参 数 个 数 为 16 ∗ ( 6 ∗ ( 5 ∗ 5 ) ) = 16 ∗ 6 ∗ ( 5 ∗ 5 ) 16*(6*(5*5))=16*6*(5*5) 16∗(6∗(5∗5))=16∗6∗(5∗5) 个参数
S4层(下采样层):对C3的16张 10 ∗ 10 10*10 10∗10 特征图进行最大池化,池化核大小为 2 ∗ 2 2*2 2∗2,得到16张大小为 5 ∗ 5 5*5 5∗5 的特征图。神经元个数已经减少为: 16 ∗ 5 ∗ 5 = 400 16*5*5=400 16∗5∗5=400
C5层(卷积层):用 5 ∗ 5 5*5 5∗5 的卷积核进行卷积,然后我们希望得到120个特征图,特征图 大小为5-5+1=1。神经元个数为120(这里实际上是全连接,但是原文还是称之为了卷积层)
F6层(全连接层):有84个节点,该层的训练参数和连接数都 ( 120 + 1 ) ∗ 84 = 10164 (120+1)* 84=10164 (120+1)∗84=10164
Output层:共有10个节点,分别代表数字0到9,如果节点i的输出值为0,则网络识别的结果是数字i。采用的是径向基函数(RBF)的网络连接方式:
y i = ∑ j ( x − j − w i j ) 2 y_i = \sum_j(x-j - w_{ij})^2 yi=j∑(x−j−wij)2
总结:卷积核大小、卷积核个数(特征图需要多少个)、池化核大小(采样率多少)这些参数都是变化的,这就是所谓的CNN调参,需要学会根据需要进行不同的选择。
AlexNet由Hinton的学生Alex Krizhevsky于2012年提出,获得ImageNet LSVRC-2012(物体识别挑战赛)的冠军,1000个类别120万幅高清图像(Error: 26.2%(2011) →15.3%(2012)),通过AlexNet确定了CNN在计算机视觉领域的王者地位。
参考:A. Krizhevsky, I. Sutskever, and G. Hinton. Imagenet classification with deep convolutional neural networks. In NIPS, 2012.
网络结构
AlexNet可分为8层(池化层未单独算作一层),包括5个卷 积层以及3个全连接层
输入层:AlexNet首先使用大小为224×224×3图像作为输入(后改为227×227×3) (227-11+2*0)/4+1=55
第一层(卷积层):包含96个大小为11×11的卷积核,卷积步长为4,因此第一层输出大小为55×55×96;然后构建一个核大小为3×3、步长为2的最大池化层进行数据降采样,进而输出大小为27×27×96
第二层(卷积层):包含256个大小为5×5卷积核,卷积步长为1,同时利用padding保证 输出尺寸不变,因此该层输出大小为27×27×256;然后再次通过 核大小为3×3、步长为2的最大池化层进行数据降采样,进而输出大小为13×13×256
第三层与第四层(卷积层):均为卷积核大小为3×3、步长为1的same卷积,共包含384个卷积核,因此两层的输出大小为13×13×384
第五层(卷积层):同样为卷积核大小为3×3、步长为1的same卷积,但包含256个卷积 核,进而输出大小为13×13×256;在数据进入全连接层之前再次 通过一个核大小为3×3、步长为2的最大池化层进行数据降采样, 数据大小降为6×6×256,并将数据扁平化处理展开为9216个单元
第六层、第七层和第八层(全连接层):全连接加上Softmax分类器输出1000类的分类结果,有将近6千万个参数
VGGNet由牛津大学和DeepMind公司提出
参考:K. Simonyan and A. Zisserman. Very deep convolutional networks for large-scale image recognition. In ICLR, 2015.
网络结构
Inception Net 是Google公司2014年提出,获得ImageNet LSVRC-2014冠军。文章提出获得高质量模型最保险的做法就是增加模型的深度(层数)或者是其宽度(层核或者神经元数),采用了22层网络。
Inception四个版本所对应的论文及ILSVRC中的Top-5错误率:
[v1] Going Deeper with Convolutions: 6.67%
[v2] Batch Normalization: Accelerating Deep Network Training by
Reducing Internal Covariate Shift: 4.8%
[v3]RethinkingtheInceptionArchitectureforComputerVision:3.5%
[v4] Inception-v4, Inception-ResNet and the Impact of Residual Connections on Learning: 3.08%
Inception Module
ResNet(Residual Neural Network),又叫做残差神经网 络,是由微软研究院的何凯明等人2015年提出,获得ImageNet ILSVRC 2015比赛冠军,获得CVPR2016最佳论文奖。
随着卷积网络层数的增加,误差的逆传播过程中存在的梯 度消失和梯度爆炸问题同样也会导致模型的训练难以进行,甚至会出现随着网络深度的加深,模型在训练集上的训练误差会出现先降低再升高的现象。残差网络的引入则有助于解决梯度消失和梯度爆炸问题。
残差块
ResNet的核心是叫做残差块(Residual block)的小单元, 残差块可以视作在标准神经网络基础上加入了跳跃连接(Skip connection)
a l + 1 = σ ( W l + 1 a l + b l + 1 ) a l + 2 = σ ( W l + 2 a l + 1 + b l + 2 ) a_{l+1} = \sigma(W_{l+1}a_l+b_{l+1}) \\ a_{l+2} = \sigma(W_{l+2}a_{l+1}+b_{l+2}) al+1=σ(Wl+1al+bl+1)al+2=σ(Wl+2al+1+bl+2)
a l + 1 = σ ( W l + 1 a l + b l + 1 ) a l + 2 = σ ( W l + 2 a l + 1 + b l + 2 + a l ) a_{l+1} = \sigma(W_{l+1}a_l+b_{l+1}) \\ a_{l+2} = \sigma(W_{l+2}a_{l+1}+b_{l+2}+a_l) al+1=σ(Wl+1al+bl+1)al+2=σ(Wl+2al+1+bl+2+al)
Skip connection的作用
记 u l + 1 = W l + 1 a l + b l + 1 , u l + 2 = W l + 2 a l + 1 + b l + 2 + a l = u ^ l + 2 + a l u_{l+1} = W_{l+1}a_l+b_{l+1},u_{l+2} = W_{l+2}a_{l+1}+b_{l+2}+a_l = \hat{u}_{l+2} + a_l ul+1=Wl+1al+bl+1,ul+2=Wl+2al+1+bl+2+al=u^l+2+al
DenseNet中,两个层之间都有直接的连接,因此该网络的直接连接个数为L(L+1)/2。
对于每一层,使用前面所有层的特征映射作为输入,并且使用其自身的特征映射作为所有后续层的输入
参考:Huang, G., Liu, Z., Van Der Maaten, L., & Weinberger, K. Q. (2017). Densely connected convolutional networks. In Proceedings of the IEEE conference on computer vision and pattern recognition (pp. 4700- 4708).
5层的稠密块示意图
DenseNets可以自然地扩展到数百个层,而没有表现出优化困难。在实验中,DenseNets随着参数数量的增加,在精度上产生一致的提高,而没有任何性能下降或过拟合的迹象。
优点: