最通俗的理解
CNN:
提取特征的过程
先观察下面两张图:
怎么让机器进行匹配识别呢?
观察这两张X图,可以发现尽管像素值无法一一对应,但也存在着某些共同点。
看到解决思路了没有?
如上图所示,两张图中三个同色区域的结构完全一致!
从标准的X图中我们提取出三个特征(feature):
只要用这三个feature便可定位到X的某个局部
feature在CNN中也被成为卷积核(filter),一般是3X3,或者5X5的大小。
执行卷积运算:
卷积运算就是将原始图片的与特定的Feature Detector(filter)做卷积运算(符号⊗),卷积运算就是将下图两个3x3的矩阵作相乘后再相加
下面的动图更好地解释了计算过程:
中间的Feature Detector(Filter)会随机产生好几种(ex:16种):
利用Feature Detector萃取出物体的边界
回到本例中,继续执行卷积运算:
9个都计算完了就会变成这样:
这张新的图我们称之为 feature map (特征图)。
进行卷积对应相乘运算并求得均值后,滑动窗便开始向右边滑动。根据步长的不同选择滑动幅度。比如,若步长 stride=1,就往右平移一个像素。若 步长 stride=2,就往右平移两个像素。
经过一系列卷积对应相乘,求均值运算后,终于把一张完整的feature map填满了.
feature map是每一个feature从原始图像中提取出来的“特征”。其中的值,越接近为1表示对应位置和feature的匹配越完整,越是接近-1,表示对应位置和feature的反面匹配越完整,而值接近0的表示对应位置没有任何匹配或者说没有什么关联。
一个feature作用于图片产生一张feature map,对这张X图来说,我们用的是3个feature,因此最终产生3个 feature map。
非线性激活层
对原图运算多个卷积后还要产生一组线性激活响应,而非线性激活层是对之前的结果进行一个非线性的激活响应。
在神经网络中用到最多的非线性激活函数是Relu函数,它的公式定义如下:,
使用Relu函数去掉负值,更能淬炼出物体的形状:
保留大于等于0的值,其余所有小于0的数值直接改写为0。
如下图所示:>=0的值不变
而<0的值一律改写为0
得到非线性激活函数作用后的结果:
pooling池化层
池化层的作用是最大的目标就是减少数据量。
池化分为两种,Max Pooling 最大池化、Average Pooling平均池化。顾名思义,最大池化就是取最大值,平均池化就是取平均值。
选择池化尺寸为2x2,因为选定一个2x2的窗口,在其内选出最大值更新进新的feature map。
同样向右依据步长滑动窗口:
最终得到池化后的feature map。可明显发现数据量减少了很多。
最大池化保留了每一个小块内的最大值,相当于保留了这一块最佳匹配结果(因为值越接近1表示匹配越好)。
到这里就介绍了CNN的基本配置---卷积层、Relu层、池化层。
在常见的几种CNN中,这三层都是可以堆叠使用的,将前一层的输入作为后一层的输出。比如:
也可以自行添加更多的层以实现更为复杂的神经网络。
全连接层
原图片尺寸为9X9,在一系列的卷积、relu、池化操作后,得到尺寸被压缩为2X2的三张特征图。
我们最初和最终的目的到底是什么?是对这张照片进行识别,识别它到底是X还是O呢(其实也算是对它进行一个二分类)。
全连接层要做的,就是对之前的所有操作进行一个总结,给我们一个最终的结果。
它最大的目的是对特征图进行维度上的改变,来得到每个分类类别对应的概率值。全连接层的部分就是将之前的结果平坦化之后接到最基本的神经网络了.
上图中得到一些2X2的特征图后,对其应用全连接网络,再全连接层中有一个非常重要的函数----Softmax,它是一个分类函数,输出的是每个对应类别的概率值。
假设对一张看起来并不标准的图进行分类。如下:
对于进行一系列操作后,假设得到的概率值如下所示:
对结果进行统计分析后可判断这张图片里的字母为X。
神经网络的训练与优化
前面说了那么多,其实只是一个大致的框架的设计而已,里面的参数具体是多少则是需要训练的。
针对这个识别X的例子,我们可以人为定义三个3X3的卷积核,便可实现对X的特征提取。但是在实际运用中,比如识别手写字母,几乎不可能存在标准的写法,每个人的字迹都完全不同,因此原来的那三个标准的卷积核就变得不再适用了,为了提高CNN模型的通用性(机器学习中的“泛化能力”),就需要对卷积核进行改写。经过成千上万的训练集来训练,每一次加入新的数据,都有可能对卷积核里的值造成影响。
那么具体的训练方法是什么呢?
就是赫赫有名的BP算法---BackProp反向传播算法。
在训练时,我们采用的训练数据一般都是带有标签label的图片。如果图片中的字母是X,则label=x,如果图片中的字母是A,则label=A。 标签能直观地反映图片。
在最开始,训练前,我们定义一个大小为3X3的卷积核,那么里面具体的值是多少,我们都不知道,但又不能为0吧,所以就用随机初始化法来进行赋值,卷积核获取到了一个随机值,便可以开始工作。
卷积神经网络便可以开始工作了,输入一张带有标签的图片(假设图片内容是字母X)。经网络识别后判断是X的概率为0.3。本来应该是1.0的概率,现在只有0.3,问题就很明显了,存在了很大的误差。
一种简单定义误差error的计算公式为
训练的终极目的就是使得这个误差最小,常用的方法是 梯度下降法。
内部设计的具体复杂公式在此不多做叙述。
简单的说可以参照下图,要使得误差error最小,就是让卷积核里的参数w往梯度下降最小的反向改变。
用这种方法来改变卷积核里的参数W使得误差最小。
卷积层是构建卷积神经网络的核心层,它产生了网络中大部分的计算量。注意是计算量而不是参数量。
3个超参数控制着输出数据体的尺寸:深度(depth),步长(stride)和零填充(zero-padding)。
- 将沿着深度方向排列、感受野相同的神经元集合称为深度列(depth column),也有人使用纤维(fibre)来称呼它们。
在滑动滤波器的时候,必须指定步长。当步长为1,意味着滤镜逐个像素地滑动。通过增加步幅大小,滤波器在输入上滑动的间隔更大,因此单元之间的重叠更少。
下面的动画显示步幅大小为1。当步长为2,滤波器滑动时每次移动2个像素。
- 有时候将输入数据体用0在边缘处进行填充是很方便的。这个零填充(zero-padding)的尺寸是一个超参数。零填充有一个良好性质,即可以控制输出数据体的空间尺寸(最常用的是用来保持输入数据体在空间上的尺寸,使得输入和输出的宽高都相等)。
输出数据体在空间上的尺寸可以通过输入数据体尺寸 ,卷积层中神经元的感受野尺寸(F),步长(S),滤波器数量(K)和零填充的数量(P)计算输出出来。
一般说来,当步长S=1时,零填充的值是P=(F-1)/2,这样就能保证输入和输出数据体有相同的空间尺寸。
可视化卷积层的一种好方法如下所示,最后我们以一张动图解释下卷积层到底做了什么:
CNN架构简单来说就是:图片经过各两次的Convolution, Pooling, Fully Connected就是CNN的架构了,因此只要搞懂Convolution, Pooling, Fully Connected三个部分的内容就可以完全掌握了CNN!