好久没有写乐乎的博客了,写博客有利于记住学习过的内容,对学生的我来说是很有帮助的。我决定要重拾写博客的好习惯,督促自己学习。
卷积神经网络(Convolutional Neural Networks, CNN)由输入层、卷积层、池化层、激活层,全连接层及输出层构成,是一种专门用来处理具有类似网格结构数据的神经网络。卷积网络是指那些至少在网络的一层中使用卷积运算来替代一般的矩阵乘法运算的神经网络。
cnn网络常用于图像识别,图像分割,语音处理和更高级的图像降噪等。卷积层(convolutional layer)主要作用是提取图像特征,池化层(pooling layer)(下采样)主要作用是数据降维、避免过拟合,激活层对数据进行处理,一般是非线性映射,在cnn网络中采用ReLU函数。全连接层是可以整合卷积层或者池化层中具有类别区分性的局部信息并且根据不同的任务输出我们想要的结果。
我理解的卷积即是一种运算方法,它就好像乘法,加法一样是处理数据的一种方法。上文中所述cnn使用卷积代替了矩阵乘法。在图像处理中常用矩阵,在语音处理中我还没有了解。值得注意的是在数学中也有卷积的运算,神经网络所用的是离散卷积但严格意义上和数学的定义有所不同,更像是一种滤波,下面我将一一分析。
数学上的卷积定义为:
其中,f与g的卷积,进一步,连续的卷积定义为:
而离散的定义为:
这是一维的卷积定义,进而给出二维离散的卷积定义:
这里,将f与g看成矩阵,f为输入矩阵, g 为权重系数矩阵,即通常所说的卷积核(convolutional kernel),x与y为对应的矩阵坐标,即x列y行。
卷积核是卷积运算的关键,它一般是一个奇数阶方阵。
将这个定义代入矩阵de 操作为:
先设有两个矩阵A,B其中A为输入矩阵,B为卷积核,注意:要做卷积,矩阵下标并不是相对应的,这点在上文定义的公式中也可以看到。
得出结果c11,将下标为和1的结果加起来:
不难看出,在做卷积运算的时候B矩阵好像被旋转了180度。
上述均为在数学上规定的卷积,而用于图像处理的卷积则更类似于一种过滤。
首先,我们知道图像就是一个一个像素组成的二维数组,即一个矩阵,长度为它的列数,宽度为它的行数,矩阵元素就是像素值。顺便一提,在长度和宽度的基础上,我们还定义了高度,即像素的通道。
例如在图像上的卷积示意图:
图像处理中所用到的就是对应元素的加权求和。
比如平滑滤波的卷积核为:
边缘提取卷积核为:
神经网络中的卷积核一般是通过机器学习训练得出的,通俗的理解就是特征,人眼在看世界的时候大脑总是自然的将看到景象的特征提取出来,这样通过经验和以前学习的知识来使用这些特征做比对,进一步分析出自己看到了什么。神经网络的思维也在此,cnn网络的第一步就是使用卷积,将代表某种特征的卷积核同输入吧图像卷积,获得该图像中具有同卷积核相同特征的图像,进行下一步分析。
需要注意的是,每次卷积只能获取一个高度上的结果,即一个通道(例如RGB颜色值的R,G,B通道)。需要多个通道上的值需要再做一次卷积。
在cnn网络中,卷积的下一步叫做池化,池化(pooling),初识这个词语有一种丈二和尚的感觉,就好像我第一次听说“鲁棒性”这个词语。通俗理解,池化即为采样(对于学图形学的人来说,采样更好理解)。
常用的池化方式有3种:最大池化(max pooling)、均值池化(mean pooling)和全局最大(或平均)池化。
原数据:
a) 最大池化:采样矩阵中的最大值,并将这个最大值作为该位置的值
b) 平均池化:计算矩阵中的平均值,并将这个值作为该位置的值
c) 全局最大(或平均)池化:是计算整个特征图内的最大值(或平均值)
显而易见,池化是再大量数据中按特定的规则进行采样获取的结果,很大程度上用低维的数据表达了高维数据的特性。池化操作可以降低矩阵的维数,使运算更快。同时,它还可以很好的去除再卷积操作过后的信息冗余(相邻的大部分像素都具有相同的特征,卷积后可能回保留这些冗余的特征),避免过拟合,提高了网络的准确率和高效性。要注意选择和要解决问题相关的池化操作。
激活其实就是非线性映射,将上一步池化得来的数据进行处理,使得多层神经网络具有实际意义。如果不使用激活函数,每一层节点的输入都是上层输出的线性函数,这样无论有多少层神经网络,最后的结果依然是输入的线性函数,这就和最原始的多层感知机(MLP)一样了。自然界中的数据大多不是线性相关的,所以引入了激活层来使神经网络更加强大,几乎可以逼近任意函数。
激活函数的定义
激活函数决定了某个神经元是否被激活,这个神经元接受到的信息是否有用,是该留下还是该抛弃掉。在神经网络中我们需要一个机制来区分有用信息和无用信息,类似于大脑中的神经元,有的神经对于某些信号是敏感的而有些神经元对这些信号是抑制的,在神经网络中能起到这个作用的就是激活函数。
下面介绍几种常见的激活函数:
ReLU
在cnn中常用ReLU函数,它的定义如下:
导数:
优点是计算简单,求导也简单。同时可以使一部分神经元的输出为0,这样就造成了网络的稀疏性,并且减少了参数的相互依存关系,缓解了过拟合问题的发生。但缺点是过于“脆弱”,并有可能“死亡”。例如一个有很大的梯度流过ReLU神经元时,可能会使其梯度计入一种无法被其它数据激活的状态。即以后流经该神经元的梯度均为0,则宣告该神经元“死亡”,这种情况是不可逆的,导致了数据多样化的丢失。如果学习率设置得太高,会大规模导致这种情况的发生。
sigmoid
除了ReLU函数,还有最具代表性的sigmoid函数,百度百科中的描述为:sigmoid函数是一个在生物学中常见的S型函数,也称为S型生长曲线。在信息科学中,由于其单增以及反函数单增等性质,常被用作神经网络的激活函数。同时sigmoid函数又叫Logistic函数它的作用是将任意实数映射到(0,1)区间,在特征相差比较复杂或者相差不是特别大的时候效果比较好。sigmoid函数定义如下:
对其求导可得:
它的优点是平滑,易于求导。但激活函数计算量大,反向传播求误差的时候,求导涉及到除法,很容易出现梯度消失的情况,从而无法完成深层网络的训练的缺点使它的使用具有很大的局限性。
Tanh
即双曲正切(hyperbolic tangent),Tanh函数可以将任意实数映射到(-1,1)区间内,像一个扩展版的sigmoid。其定义如下:
不难推出它是2 * sigmoid(2x) - 1。
求导:
tanh的导数取值范围在0至1之间,优于sigmoid的0至1/4,在一定程度上,减轻了梯度消失的问题。变化敏感区间较宽,导数值渐进于0、1,符合人脑神经饱和的规律,比sigmoid函数延迟了饱和期。
同时,tanh在原点附近与y=x函数形式相近,当激活值较低时,可以直接进行矩阵运算,训练相对容易。
他和sigmoid均为全部激活(fire),使得网络较重(heavy)。
常用于RNN网络。
这一步就是收尾了,我们将,卷积,池化,激活后的二维数据进行行主序或列主序展开成一位,输入全连接神经网络中进行训练,最后得出结果。要注意的是卷积,池化,激活只是三种操作,我们可以重复这些操作,然后任意组合,得到我们想要的结果。