卷积神经网络模型结构

一般地,CNN的基本结构包括两层,其一为特征提取层,每个神经元的输入与前一层的局部接受域相连,并提取该局部的特征。一旦该局部特征被提取后,它与其它特征间的位置关系也随之确定下来;其二是特征映射层,网络的每个计算层由多个特征映射组成,每个特征映射是一个平面,平面上所有神经元的权值相等。特征映射结构采用影响函数核小的sigmoid函数作为卷积网络的激活函数,使得特征映射具有位移不变性。此外,由于一个映射面上的神经元共享权值,因而减少了网络自由参数的个数。卷积神经网络中的每一个卷积层都紧跟着一个用来求局部平均与二次提取的计算层,这种特有的两次特征提取结构减小了特征分辨率。

CNN主要用来识别位移、缩放及其他形式扭曲不变性的二维图形。由于CNN的特征检测层通过训练数据进行学习,所以在使用CNN时,避免了显式的特征抽取,而隐式地从训练数据中进行学习;再者由于同一特征映射面上的神经元权值相同,所以网络可以并行学习,这也是卷积网络相对于神经元彼此相连网络的一大优势。卷积神经网络以其局部权值共享的特殊结构在语音识别和图像处理方面有着独特的优越性,其布局更接近于实际的生物神经网络,权值共享降低了网络的复杂性,特别是多维输入向量的图像可以直接输入网络这一特点避免了特征提取和分类过程中数据重建的复杂度。

卷积

对于1维的卷积,公式(离散)与计算过程(连续)如下,要记住的是其中一个函数(原函数或者卷积函数)在卷积前要翻转180度。

对于离散卷积,f的大小是n1,g的大小是n2,卷积后的大小是n1+n2-1。

图像卷积

同样地,卷积的时候需要对卷积核进行180的旋转,同时卷积核中心与需计算的图像像素对齐,输出结构为中心对齐像素的一个新的像素值,计算例子如下

这样计算出左上角(即第一行第一列)像素的卷积后像素值。

给出一个更直观的例子,从左到右看,原像素经过卷积由1变成-8。

通过滑动卷积核,就可以得到整张图片的卷积结果。

Depth为1的卷积

假设一张图像有 $55$ 个像素,1 代表白,0 代表黑,这幅图像被视为 $55$ 的单色图像。现在用一个由随机地 0 和 1 组成的 $33$ 矩阵去和图像中的子区域做乘法,每次迭代移动一个像素,这样该乘法会得到一个新的 $33$ 的矩阵。下面的动图展示了这个过程。

上述的 $33$ 的矩阵被称作「滤波器」,它的任务是提取图像特征,它使用「优化算法」来决定 $33$ 矩阵中具体的 0 和 1。我们在神经网络的卷积层中使用好几个这样的滤波器来提取多个特征。$3*3$ 矩阵的每一个单个步骤被称作「步幅」(stride)。

在上面两个公式中,W2是卷积后Feature Map的宽度;W1是卷积前图像的宽度;F是filter的宽度;P是Zero Padding数量,Zero Padding是指在原始图像周围补几圈0,如果的值是1,那么就补1圈0;S是步幅;H2是卷积后Feature Map的高度;H1是卷积前图像的高度。

Depth大于1的卷积

下面的例子中,输入层是高度和宽度是 7 x 7 ,深度是3。两个Filter的,每个Filter的高度和宽度是 3 x 3 ,深度因为要和输入层保持一致,所以也必须是 3。

最左边的输入层(Input Volume)和Filter W0 进行计算(输入的第一层和Filter的第一层进行运算,第二层和第二层进行运算,第三层和第三层进行运算,最后三层结果累加起来),获得了 Output Volume 的第一个结果(绿色的上面一个矩阵);和Filter W1 进行计算,获得了 Output Volume 的第二个结果(绿色的下面一个矩阵)。

前面我们已经讲了深度为1的卷积层的计算方法,如果深度大于1怎么计算呢?其实也是类似的。如果卷积前的图像深度为D,那么相应的filter的深度也必须为D。我们扩展一下式1,得到了深度大于1的卷积计算公式:

上式中,D是深度;F是filter的大小(宽度或高度,两者相同);$w_{d,m,n}$是filter的第n层第i行第j列像素;其他的含义与上述深度为1的时候卷积层计算公式相同。

不管深度为多少,经过一个Filter,最后都通过上面的公式变成一个深度为1的特征图(feature map)。

feature map的理解:在每个卷积层,数据都是以三维形式存在的。你可以把它看成许多个二维图片叠在一起,其中每一个称为一个feature map。在输入层,如果是灰度图片,那就只有一个feature map;如果是彩色图片,一般就是3个feature map(红绿蓝)。层与层之间会有若干个卷积核(kernel),上一层中每个feature map跟每个卷积核做卷积,都会产生下一层的一个feature map。

卷积的类型

在matlab中对2维卷积的计算分为了3类,1.full 2.same 3. valid 参考这里

图像卷积小节中第一个图对应的是same,Depth为1的卷积小节中的第一个图对应的是valid,full对应如下图:

上图中蓝色为原图像,白色为对应卷积所增加的padding,通常全部为0,绿色是卷积后图片。图6的卷积的滑动是从卷积核右下角与图片左上角重叠开始进行卷积,滑动步长为1,卷积核的中心元素对应卷积后图像的像素点。可以看到卷积后的图像是4X4,比原图2X2大了,我们还记1维卷积大小是n1+n2-1,这里原图是2X2,卷积核3X3,卷积后结果是4X4,与一维完全对应起来了。其实这才是完整的卷积计算,其他比它小的卷积结果都是省去了部分像素的卷积。下面是WIKI对应图像卷积后多出部分的解释:

Kernel convolution usually requires values from pixels outside of the image boundaries. There are a variety of methods for handling image edges.意思就是多出来的部分根据实际情况可以有不同的处理方法。(其实这里的full卷积就是后面要说的反卷积)

这里,我们可以总结出full,same,valid三种卷积后图像大小的计算公式:

  1. full: 滑动步长为1,图片大小为N1xN1,卷积核大小为N2xN2,卷积后图像大小:N1+N2-1 x N1+N2-1
    如1.4中的第一个图, 滑动步长为1,图片大小为2x2,卷积核大小为3x3,卷积后图像大小:4x4
  2. same: 滑动步长为1,图片大小为N1xN1,卷积核大小为N2xN2,卷积后图像大小:N1xN1
  3. valid:滑动步长为S,图片大小为N1xN1,卷积核大小为N2xN2,卷积后图像大小:(N1-N2)/S+1 x (N1-N2)/S+1

如1.2中的第一个图,滑动步长为1,图片大小为5x5,卷积核大小为3x3,卷积后图像大小:3x3

反卷积

这里提到的反卷积跟1维信号处理的反卷积计算是很不一样的,FCN作者称为backwards convolution,有人称Deconvolution layer is a very unfortunate name and should rather be called a transposed convolutional layer. 我们可以知道,在CNN中有con layer与pool layer,con layer进行对图像卷积提取特征,pool layer对图像缩小一半筛选重要特征,对于经典的图像识别CNN网络,如IMAGENET,最后输出结果是1X1X1000,1000是类别种类,1x1得到的是。FCN作者,或者后来对end to end研究的人员,就是对最终1x1的结果使用反卷积(事实上FCN作者最后的输出不是1X1,是图片大小的32分之一,但不影响反卷积的使用)。

这里图像的反卷积与1.4中第一个图的full卷积原理是一样的,使用了这一种反卷积手段使得图像可以变大,FCN作者使用的方法是这里所说反卷积的一种变体,这样就可以获得相应的像素值,图像可以实现end to end。

这里说另外一种反卷积做法,假设原图是3X3,首先使用上采样让图像变成7X7,可以看到图像多了很多空白的像素点。使用一个3X3的卷积核对图像进行滑动步长为1的valid卷积,得到一个5X5的图像,我们知道的是使用上采样扩大图片,使用反卷积填充图像内容,使得图像内容变得丰富,这也是CNN输出end to end结果的一种方法。韩国作者Hyeonwoo Noh使用VGG16层CNN网络后面加上对称的16层反卷积与上采样网络实现end to end 输出,其不同层上采样与反卷积变化效果如下,

图像的deconvolution

目前使用得最多的deconvolution有2种,上文都已经介绍。

方法1:full卷积, 完整的卷积可以使得原来的定义域变大

方法2:记录pooling index,然后扩大空间,再用卷积填充

图像的deconvolution过程如下,

输入:2x2, 卷积核:4x4, 滑动步长:3, 输出:7x7。即输入为2x2的图片经过4x4的卷积核进行步长为3的反卷积的过程。

  1. 输入图片每个像素进行一次full卷积,根据full卷积大小计算可以知道每个像素的卷积后大小为 1+4-1=4, 即4x4大小的特征图,输入有4个像素所以4个4x4的特征图
  2. 将4个特征图进行步长为3的fusion(即相加); 例如红色的特征图仍然是在原来输入位置(左上角),绿色还是在原来的位置(右上角),步长为3是指每隔3个像素进行fusion,重叠部分进行相加,即输出的第1行第4列是由红色特阵图的第一行第四列与绿色特征图的第一行第一列相加得到,其他如此类推。

可以看出翻卷积的大小是由卷积核大小与滑动步长决定, in是输入大小, k是卷积核大小, s是滑动步长, out是输出大小

得到 $out = (in - 1) * s + k$

上图过程就是, $(2 - 1) * 3 + 4 = 7$

卷积的优势

局部感知

由卷积的操作可知,输出图像中的任何一个单元,只跟输入图像的一部分有关系:

而传统神经网络中,由于都是全连接,所以输出的任何一个单元,都要受输入的所有的单元的影响。这样无形中会对图像的识别效果大打折扣。而图像中,每一个区域都有自己的专属特征,我们不希望它受到其他区域的影响。

简单来说,卷积核的大小一般小于输入图像的大小(如果等于则是全连接),因此卷积提取出的特征会更多地关注局部 —— 这很符合日常我们接触到的图像处理。而每个神经元其实没有必要对全局图像进行感知,只需要对局部进行感知,然后在更高层将局部的信息综合起来就得到了全局的信息。

参数共享

参数共享机制,让我们的网络的参数数量大大地减少。这样,我们可以用较少的参数,训练出更加好的模型,典型的事半功倍,而且可以有效地避免过拟合。 同样,由于filter的参数共享,即使图片进行了一定的平移操作,我们照样可以识别出特征,这叫做 “平移不变性”。因此,模型就更加稳健了。

多核

一般我们都不会只用一个卷积核对输入图像进行过滤,因为一个核的参数是固定的,其提取的特征也会单一化。这就有点像是我们平时如何客观看待事物,必须要从多个角度分析事物,这样才能尽可能地避免对该事物产生偏见。我们也需要多个卷积核对输入图像进行卷积。

参数计算

举例1:

比如输入是一个32x32x3的图像,3表示RGB三通道,每个filter/kernel是5x5x3,一个卷积核产生一个feature map,下图中,有6个5x5x3的卷积核,故输出6个feature map(activation map),大小即为28x28x6(32 - 5 + 1)。

下图中,第二层到第三层,其中每个卷积核大小为5x5x6,这里的6就是28x28x6中的6,两者需要相同,即每个卷积核的“层数”需要与输入的“层数”一致。有几个卷积核,就输出几个feature map,下图中,与第二层作卷积的卷积核有10个,故输出的第三层有10个通道。

举例2:

NxN大小的输入(暂时不考虑通道数),与FxF大小的卷积核(暂时不考虑个数)做卷积,那么输出大小为多大?计算公式为:(N - F) / stride + 1,其中stride为做卷积是相邻卷积核的距离。

举例3:

当输入为7x7大小,卷积核为3x3,stride=1,在7x7周围补上一圈0(pad=1个像素),那么输出大小为多大?

是7x7。

举例4:

输入为32x32x3,卷积核大小为5x5,总共有10个卷积核,做卷积的时候stride=1,pad=2,那么这一层总共含有多少参数?

每个卷积核含有的参数个数为:553 + 1 = 76,其中1是偏置bias,由于有10个卷积核,故总参数为76*10=760。

总结:

其中,卷积核的数量K一般是2的整数次幂,这是因为计算方便(计算机计算2^n比较快)

池化层

这个层主要使用不同的函数为输入降维。通常,最大池化层(max-pooling layer)出现在卷积层之后。池化层使用 $2*2$ 的矩阵,以卷积层相同的方式处理图像,不过它是给图像本身降维。下面分别是使用「最大池化」和「平均池化」的示例。

池化层会损失信息,所以也不是首选的。通常的做法是在卷机层中使用一个较大的步幅。

常用的还有resnet中的global average pool。对于类似imagenet这样的分类任务,可以用来代替常规网络中的倒数第二个全连接层。该池化操作为比如现在输入尺寸为64x64x256,对每一个特征图所有像素求平均,即可得到1x1x256的特征图。使用该操作有两个优点,一:近似全连接操作,但是可以极大降低参数量。二:网络输入可以为任意大小。

除此之外,还有ROI Pooling。例如,我们有一个8*8大小的feature map,一个感兴趣区域ROI,以及输出大小为2*2.对于一个feature map,region proposal 投影之后位置(左上角,右下角坐标):(0,3),(7,8)。

将其划分为(2*2)个sections(因为输出大小为2*2),我们可以得到:

对每个section做max pooling,可以得到:

整体过程如下:

ROI Pooling 就是将大小不同的feature map 池化成大小相同的feature map,利于输出到下一层网络中。

总结:global average pool可以代替分类任务中的全连接层,而其余三种池化不可以。global average pool与ROI Pooling均可以实现让网络输入为任意大小。

池化层作用

  • 做窗口滑动卷积的时候,卷积值就代表了整个窗口的特征。因为滑动的窗口间有大量重叠区域,出来的卷积值有冗余,进行最大pooling或者平均pooling就是减少冗余。减少冗余的同时,pooling也丢掉了局部位置信息,所以局部有微小形变,结果也是一样的。就像图片上的字母A,局部出现微小变化,也能够被识别成A。而加上椒盐噪音,就是字母A上有很多小洞,同样的能够被识别出来。而平移不变性,就是一个特征,无论出现在图片的那个位置,都会识别出来。所以平移不变性不是pooling带来的,而是层层的权重共享带来的
  • 如果人们选择图像中的连续范围作为池化区域,并且只是池化相同(重复)的隐藏单元产生的特征,那么,这些池化单元就具有平移不变性(translation invariant)。

注意这两点:1、连续范围 2、池化相同隐藏单元产生的特征。这意思是指,在池化单元内部能够具有平移的不变性,它的平移范围也是有一定范围的,因为每个池化单元都是连续的,所以能够保证图像整体上发生了平移一样能提取特征进行匹配。

无论是max还是average都是在提取区域特征,均相当于一种抽象,抽象就是过滤掉了不必要的信息(当然也会损失信息细节),所以在抽象层次上可以进行更好的识别。

至于max与average效果是否一样,还是要看需要识别的图像细节特征情况,这个不一定的,不过据说差异不会超过2%。

不过仔细点说的话,评估特征提取的误差主要来自两个方面:
(1)邻域大小受限造成的估计值方差增大,average能减小这种误差。
(2)卷积层参数误差造成估计均值的偏移,max能减小这种误差。

也就是说,average对背景保留更好,max对纹理提取更好,如果是识别字体什么的,应该考虑max.

总结来说,主要是两个作用:

  1. invariance(不变性),这种不变性包括translation(平移),rotation(旋转),scale(尺度)
  2. 保留主要的特征同时减少参数(降维,效果类似PCA)和计算量,防止过拟合,提高模型泛化能力

参数计算

关于池化层的参数计算:

参考:斯坦福大学CS231N课程PPT

全连接层

一维

一般常见的是这种一维的全连接层,下面这种图就很常见。全连接层,通俗的说就是前面一层的每个单元都与后面一层的相连接。如下图的绿色 Hidden 层,Hidden 层的每个单元都与 Input 层的所有单元相连接,同理 Output 层的与 Hidden 层的也是如此。

1
2
(1*3)*(3*4)=(1*4)
(1*4)*(4*2)=(1*2)

即 Input 到 Hidden 这个全连接层中间的参数矩阵是 (3,4) 维的,Hidden 到 Output 的参数矩阵是 (4,2) 为的

二维

二维的图主要是这样的,左边的 v 层是 (4, 2) 的矩阵,通过全连接层,得到一个四维的向量,看中间的 H 层也是每个单元都与前面 v层的八个单元都相连的。他们中间的参数矩阵应该是(2, 1) 的。

全连接层的作用

  • 全连接层(fully connected layers,FC)在整个卷积神经网络中起到“分类器”的作用。如果说卷积层、池化层和激活函数层等操作是将原始数据映射到隐层特征空间的话,全连接层则起到将学到的“分布式特征表示”映射到样本标记空间的作用。在实际使用中,全连接层可由卷积操作实现:对前层是全连接的全连接层可以转化为卷积核为1x1的卷积;而前层是卷积层的全连接层可以转化为卷积核为hxw的全局卷积,h和w分别为前层卷积结果的高和宽(_注1_)。
  • 卷积取的是局部特征,全连接就是把以前的局部特征重新通过权值矩阵组装成完整的图。因为用到了所有的局部特征,所以叫全连接。
  • 目前由于全连接层参数冗余(仅全连接层参数就可占整个网络参数80%左右),近期一些性能优异的网络模型如ResNet和GoogLeNet等均用全局平均池化(global average pooling,GAP)取代FC来融合学到的深度特征,最后仍用softmax等损失函数作为网络目标函数来指导学习过程。需要指出的是,用GAP替代FC的网络通常有较好的预测性能。GAP的优势是:1.因为FC的参数众多,这么做就减少了参数的数量(在最近比较火的模型压缩中,这个优势可以很好的压缩模型的大小)。2.因为减少了参数的数量,可以很好的减轻过拟合的发生。另外,这种直接用 feature map 表示属于某个类的 confidence map 的做法很符合CNN的思想。3.若之前无fc层,可以让网络输入任意大小。为具体案例可参见我们在ECCV’16(视频)表象性格分析竞赛中获得冠军的做法:「冠军之道」Apparent Personality Analysis竞赛经验分享 - 知乎专栏 ,project:Deep Bimodal Regression for Apparent Personality Analysis
  • 在FC越来越不被看好的当下,我们近期的研究(In Defense of Fully Connected Layers in Visual Representation Transfer)发现,FC可在模型表示能力迁移过程中充当“防火墙”的作用。具体来讲,假设在ImageNet上预训练得到的模型为$\mathcal{M}$ ,则ImageNet可视为源域(迁移学习中的source domain)。微调(fine tuning)是深度学习领域最常用的迁移学习技术。针对微调,若目标域(target domain)中的图像与源域中图像差异巨大(如相比ImageNet,目标域图像不是物体为中心的图像,而是风景照,见下图),不含FC的网络微调后的结果要差于含FC的网络。因此FC可视作模型表示能力的“防火墙”,特别是在源域与目标域差异较大的情况下,FC可保持较大的模型capacity从而保证模型表示能力的迁移。(冗余的参数并不一无是处。)

_注1_: 有关卷积操作“实现”全连接层,有必要多啰嗦几句。

以VGG-16为例,对224x224x3的输入,最后一层卷积可得输出为7x7x512,如后层是一层含4096个神经元的FC,则可用卷积核为7x7x512x4096的全局卷积来实现这一全连接运算过程,其中该卷积核参数如下:

1
“filter size = 7, padding = 0, stride = 1, D_in = 512, D_out = 4096”

经过此卷积操作后可得输出为1x1x4096。

如需再次叠加一个2048的FC,则可设定参数为“filter size = 1, padding = 0, stride = 1, D_in = 4096, D_out = 2048”的卷积层操作。

Dropout

dropout是指在深度学习网络的训练过程中,对于神经网络单元,按照一定的概率将其暂时从网络中丢弃。注意是暂时,对于随机梯度下降来说,由于是随机丢弃,故而每一个mini-batch都在训练不同的网络。

dropout是CNN中防止过拟合提高效果的一个大杀器,但对于其为何有效,却众说纷纭。这里主要有两种看法。

解释一

观点

规模的神经网络有两个缺点:

  • 费时
  • 容易过拟合

过拟合是很多机器学习的通病,过拟合了,得到的模型基本就废了。而为了解决过拟合问题,一般会采用ensemble方法,即训练多个模型做组合,此时,费时就成为一个大问题,不仅训练起来费时,测试起来多个模型也很费时。总之,几乎形成了一个死锁。

Dropout的出现很好的可以解决这个问题,每次做完dropout,相当于从原始的网络中找到一个更的网络,如下图所示:

因而,对于一个有N个节点的神经网络,有了dropout后,就可以看做是$2^n$个模型的集合了,但此时要训练的参数数目却是不变的,这就解脱了费时的问题。

动机论

虽然直观上看dropout是ensemble在分类性能上的一个近似,然而实际中,dropout毕竟还是在一个神经网络上进行的,只训练出了一套模型参数。那么他到底是因何而有效呢?这就要从动机上进行分析了。论文中作者对dropout的动机做了一个十分精彩的类比:

在自然界中,在中大型动物中,一般是有性繁殖,有性繁殖是指后代的基因从父母两方各继承一半。但是从直观上看,似乎无性繁殖更加合理,因为无性繁殖可以保留大段大段的优秀基因。而有性繁殖则将基因随机拆了又拆,破坏了大段基因的联合适应性。

但是自然选择中毕竟没有选择无性繁殖,而选择了有性繁殖,须知物竞天择,适者生存。我们先做一个假设,那就是基因的力量在于混合的能力而非单个基因的能力。不管是有性繁殖还是无性繁殖都得遵循这个假设。为了证明有性繁殖的强大,我们先看一个概率学小知识。

比如要搞一次恐怖袭击,两种方式:

  • 集中50人,让这50个人密切精准分工,搞一次大爆破。
  • 将50人分成10组,每组5人,分头行事,去随便什么地方搞点动作,成功一次就算。

哪一个成功的概率比较大? 显然是后者。因为将一个大团队作战变成了游击战。

那么,类比过来,有性繁殖的方式不仅仅可以将优秀的基因传下来,还可以降低基因之间的联合适应性,使得复杂的大段大段基因联合适应性变成比较小的一个一个小段基因的联合适应性。

dropout也能达到同样的效果,它强迫一个神经单元,和随机挑选出来的其他神经单元共同工作,达到好的效果。消除减弱了神经元节点间的联合适应性,增强了泛化能力

dropout带来的模型的变化

而为了达到ensemble的特性,有了dropout后,神经网络的训练和预测就会发生一些变化。

训练层面

无可避免的,训练网络的每个单元要添加一道概率流程。

  • 对应的公式变化如下如下:

    • 没有dropout的神经网络
    • 有dropout的神经网络
测试层面

预测的时候,每一个单元的参数要预乘以p。

解释二

观点

观点十分明确,就是对于每一个dropout后的网络,进行训练时,相当于做了Data Augmentation,因为,总可以找到一个样本,使得在原始的网络上也能达到dropout单元后的效果。 比如,对于某一层,dropout一些单元后,形成的结果是(1.5,0,2.5,0,1,2,0),其中0是被drop的单元,那么总能找到一个样本,使得结果也是如此。这样,每一次dropout其实都相当于增加了样本。

Padding层

在TensorFlow中,这里有两种padding的方式:

  • same:即要求输出的特征图尺寸和输入的特征图尺寸相同。引入零填充去填充所需要的维度。
  • valid:即没有padding,只利用已有的数据进行卷积,多余的数据扔掉。

两种padding示意图如图所示:

  • "VALID" =无填充:

    1
    2
    3
    inputs:         1  2  3  4  5  6  7  8  9  10 11 (12 13)
    |________________| dropped
    |_________________|
  • "SAME" =带零填充:

    1
    2
    3
    4
    5
                pad|                                      |pad
    inputs: 0 |1 2 3 4 5 6 7 8 9 10 11 12 13|0 0
    |________________|
    |_________________|
    |________________|

在这个例子中:

  • 输入宽度= 13
  • 卷积核宽度= 6
  • 步幅= 5

“VALID” 只会删除最右边的列(或最底部的行)。
“SAME” 试图左右均匀填充,但如果要添加的列数是奇数,它将在右侧添加额外的列,就像本例中的情况一样(垂直的时候相同的逻辑:可能会有额外的行底部为零)。

  • 对于 SAME 填充,输出高度和宽度计算如下:

    1
    2
    out_height = ceil(float(in_height) / float(strides[1]))
    out_width = ceil(float(in_width) / float(strides[2]))
  • 对于 VALID 填充,输出高度和宽度计算如下:

    1
    2
    out_height = ceil(float(in_height - filter_height + 1) / float(strides1))
    out_width = ceil(float(in_width - filter_width + 1) / float(strides[2]))

激励层

激励层由激活函数构成。激励层的主要作用是:假如非线性因素,提高神经网络对模型的表达能力,解决线性模型所不能解决的问题。

激活函数性质

激活函数通常有如下一些性质:

  • 非线性: 当激活函数是线性的时候,一个两层的神经网络就可以逼近基本上所有的函数了。但是,如果激活函数是恒等激活函数的时候(即$f(x)=x$)就不满足这个性质了,而且如果 MLP 使用的是恒等激活函数,那么其实整个网络跟单层神经网络是等价的。
  • 可微性: 当优化方法是基于梯度的时候,这个性质是必须的。
  • 单调性: 当激活函数是单调的时候,单层网络能够保证是凸函数。
  • $f(x)\approx x$: 当激活函数满足这个性质的时候,如果参数的初始化是random的很小的值,那么神经网络的训练将会很高效;如果不满足这个性质,那么就需要很用心的去设置初始值。
  • 输出值的范围: 当激活函数输出值是 有限 的时候,基于梯度的优化方法会更加 稳定,因为特征的表示受有限权值的影响更显著;当激活函数的输出是 无限 的时候,模型的训练会更加高效,不过在这种情况小,一般需要更小的learning rate.

这些性质,也正是我们使用激活函数的原因!

常见激活函数

sigmoid

Sigmoid 是常用的非线性的激活函数,它的数学形式如下:

正如前一节提到的,它能够把输入的连续实值“压缩”到0和1之间。

特别的,如果是非常大的负数,那么输出就是0;如果是非常大的正数,输出就是1.

sigmoid 函数曾经被使用的很多,不过近年来,用它的人越来越少了。主要是因为它的一些 缺点

  • Sigmoids saturate and kill gradients. sigmoid 有一个非常致命的缺点,当输入非常大或者非常小的时候,这些神经元的梯度是接近于0的,从图中可以看出梯度的趋势。所以,你需要尤其注意参数的初始值来尽量避免saturation的情况。如果你的初始值很大的话,大部分神经元可能都会处在saturation的状态而把gradient kill掉,这会导致网络变的很难学习。
  • Sigmoid 的 output 不是0均值. 这是不可取的,因为这会导致后一层的神经元将得到上一层输出的非0均值的信号作为输入。产生的一个结果就是:如果数据进入神经元的时候是正的(e.g. x>0 elementwise in $f=w^T x + b$,那么 w 计算出的梯度也会始终都是正的。
  • 当然了,如果你是按batch去训练,那么那个batch可能得到不同的信号,所以这个问题还是可以缓解一下的。因此,非0均值这个问题虽然会产生一些不好的影响,不过跟上面提到的 kill gradients 问题相比还是要好很多的。

tanh

tanh 见上图中的红线,可以看出,tanh 跟sigmoid还是很像的,实际上,tanh 是sigmoid的变形:

与 sigmoid 不同的是,tanh 是0均值的。因此,实际应用中,tanh 会比 sigmoid 更好(毕竟去粗取精了嘛)。

它是有界的$(-1, 1)$,所以不用担心激活膨胀。值得一提的是,tanh的梯度比sigmoid更激烈(导数更陡峭)。因此,选择sigmoid还是tanh将取决于你对梯度强度的需求。和sigmoid类似,tanh也存在梯度衰减问题(梯度饱和问题)。

为了防止饱和,现在主流的做法会在激活函数前多做一步_batch normalization_,尽可能保证每一层网络的输入具有均值较小的、零中心的分布。

Relu

它的数学表达式如下:

很显然,从图中可以看出,输入信号 <0 时,输出都是0; >0 的情况下,输出等于输入。w 是二维的情况下,使用ReLU之后的效果如下:

ReLU 的优点:

  • Krizhevsky et al.发现使用 ReLU 得到的SGD的收敛速度会比 sigmoid/tanh 快很多。有人说这是因为它是linear,而且 non-saturating
  • 相比于 sigmoid/tanh,ReLU 只需要一个阈值就可以得到激活值,而不用去算一大堆复杂的运算。
  • 激活的稀疏性。想象一个具有很多神经元的大型神经网络。使用sigmoid或tanh会导致几乎所有神经元以模拟的方式激活。这意味着需要处理几乎所有的激活以描述网络的输出。换句话说,激活是密集的。这样成本很高。理想情况下,我们希望网络中的一些神经元不激活,从而使激活变得稀疏和高效。ReLu在这方面很有用。想象一个具备随机初始权重(或归一化的权重)的网络,基于ReLu的特性(x的负值将输出0),基本上50%的网络将生成0。这意味着更少的神经元将被激活(稀疏激活),网络也更轻量。
  • RuLu是非线性的。ReLu的组合也是非线性的!(实际上它是一个很好的逼近子。ReLu的组合可以逼近任何函数。)这意味着我们可以堆叠网络层。不过,它并不是有界的。ReLu的值域是$(0, inf)$。这意味着它将膨胀激活函数。

ReLU 的缺点

ReLu的水平线部分(X的负值)意味着梯度会趋向于0。当激活位于ReLu的水平区域时,梯度会是0,导致权重无法随着梯度而调整。这意味着,陷入此状态的神经元将停止对误差/输入作出反应(很简单,因为梯度是0,没有什么改变)。这被称为死亡ReLu问题。这一问题会导致一些神经元直接死亡、失去响应,导致网络的很大一部分进入被动状态。有一些缓和这一问题的ReLu变体,将水平线转为非水平部分,例如,当x<0时y = 0.01x,使图像从水平线变为略微倾斜的直线。这就是弱修正ReLu(leaky ReLu)。还有其他一些变体。主要的想法是让梯度不为零,这样网络可以逐渐从训练中恢复。

举个例子:一个非常大的梯度流过一个 ReLU 神经元,更新过参数之后,这个神经元再也不会对任何数据有激活现象了。

Leaky ReLUs

解决这个 _“dying ReLU”_ 的问题的。与 ReLU 不同的是:

这里的 $\alpha$$是一个很小的常数。这样,即修正了数据分布,又保留了一些负轴的值,使得负轴信息不会全部丢失。

Maxout

Maxout 公式如下:

假设 w 是2维,那么有:

可以注意到,ReLU 和 Leaky ReLU 都是它的一个变形(比如,$w_1, b_1 = 0$ 的时候,就是 ReLU).

Maxout的拟合能力是非常强的,它可以拟合任意的的凸函数。作者从数学的角度上也证明了这个结论,即只需2个maxout节点就可以拟合任意的凸函数了(相减),前提是”隐隐含层”节点的个数可以任意多。

所以,Maxout 具有 ReLU 的优点(如:计算简单,不会 saturation),同时又没有 ReLU 的一些缺点 (如:容易 go die)。缺点是:就是把参数double了。

特性

功能特性

就功能特性而言,卷积神经网络可以提取数据的多尺度局部特征,然后将这些特征组合起来形成高维有效特征同时正是因为这种局部特性,导致CNN是无法得到全局特征的,需要很深才能得到较大的感受视野。这也是CNN的比较大的问题,导致在CNN在NLP中并不是很适用。

多尺度

在实际场景中,经常含有不同尺度的目标,比如说在图片1中目标的大小为200x200,但是在图片2中目标的大小为100x100,所以需要提取图像的多尺度特征。

具体多尺度操作可以分为卷积核的多尺度(例如inception网络)和输入数据的多尺度(例如SPPnet、图像金字塔)。

局部

Global Feature

全局特征是指图像的整体属性,常见的全局特征包括颜色特征、纹理特征和形状特征,比如强度直方图等。由于是像素级的低层可视特征,因此,全局特征具有良好的不变性、计算简单、表示直观等特点,但特征维数高、计算量大是其致命弱点。此外,全局特征描述不适用于图像混叠和有遮挡的情况。局部特征则是从图像局部区域中抽取的特征,包括边缘、角点、线、曲线和特别属性的区域等。常见的局部特征包括角点类和区域类两大类描述方式。

Local Feature

与线特征、纹理特征、结构特征等全局图像特征相比,局部图像特征具有在图像中蕴含数量丰富 ,特征间相关度小,遮挡情况下不会因为部分特征的消失而影响其他特征的检测和匹配等特点。近年来 ,局部图像特征在人脸识别 、三维重建、目标识别及跟踪 、影视制作 、全景图像拼接 等领域得到了广泛的应用。典型的局部图像特征生成应包括图像极值点检测和描述两个阶段。好的局部图像特征应具有特征检测重复率高、速度快 ,特征描述对光照、旋转、视点变化等图像变换具有鲁棒性,特征描述符维度低,易于实现快速匹配等特点

结构特性

就卷积神经网络的连接而言,有局部连接、权重共享、多层等特性。

其中,局部连接和权重共享可以对应功能特性中的局部特性。而多层可以对应功能特性中的特征组合

技巧

防止过拟合

  • 提前终止(当验证集上的效果变差的时候)
  • L1和L2正则化加权
  • soft weight sharing
  • dropout

CNN为什么比DNN好

DNN的输入是向量形式,没有考虑到平面信息,而这部分在图像处理部分特别重要。CNN的输入是Tensor,可以获得局部信息,而且保留了平面结构信息。

参考

深度学习两种图像数据预处理具体方法
ROI Pooling原理及实现
【DL笔记6】从此明白了卷积神经网络(CNN)
多尺度特征表示在深度学习中的重要意义
【深度学习】什么是局部特征?什么是全局特征

------ 本文结束------
坚持原创技术分享,您的支持将鼓励我继续创作!

欢迎关注我的其它发布渠道