前言
本文是我在学习卷积神经网络(Convolutional Neural Network)时的笔记,主要参考资料是Andrew Ng老师在UFLDL Tutorial中的相关章节。关于CNN的笔记在网络上很多了,本文不再详述各种细节,只对其中容易混淆和难以理解的算法细节做一个讲解,这些细节都是这两年与学生交流讨论中总结出来的。
文章小节安排如下:
1)全连接(Fully connected)与局部连接(Locally connected)
2)卷积(Convolution)
3)池化(Pooling)
4)参考文献
机器学习的内容丰富,涉及的数学知识很多,是需要脚踏实地一点一点琢磨的,从来没有捷径,也不存在速成的方法!无论任何一门学科,学习重要的是兴趣和毅力,以及平和的心态。
一、全连接(Fully connected)与局部连接(Locally connected)
1.1 multilayer neural network
UFLDL中讲解了两种神经网络,一种是Multilayer Neural Network,另一种是本文要重点讲解的Convolutional Neural Network。两种神经网络并非完全独立的,CNN可以看作是普通多层神经网络的高级进化版本,具有更强的特征学习能力,再各个任务上表现的都很好,雷霆万钧般的几乎碾压所有机器学习算法。但究其本质,CNN仍然属于神经网络的范畴,在前向传播和反向传播的计算方面,与普通多层神经网络其实也没有本质的差异。
在探索CNN之前,先回顾一下最普通的多层神经网络:
Multilayer Neural Network是一种 全连接的网络结构,也就是隐层中每个神经元都连接前一层的所有神经元。这种神经网络更多的是作为一种分类器,对输入的特征进行层层映射,最终在新的特征空间进行分类。
1.2 全连接与局部连接
通过下面一幅图,可以很好地对比 Fully Connected 和 Locally Connected:
上图左:
全连接网络。每个隐藏单元都连接图像的每一个像素点,这就是一种全连接方式。如果我们有1000x1000像素的图像,有1百万个隐层神经元,每个隐层单元都连接图像的每一个像素点,就有1000x1000x1000000=10^12个连接,也就是10^12个权值参数。
上图右:
局部连接网络。每个隐含单元仅仅连接输入图像的一小片相邻区域,那么这就是一种局部连接方式。每个隐层单元与图像中同位置单元附近10x10的窗口相连接,则1百万个隐层神经元就只有100w乘以100个连接,即10^8个参数。其参数个数比原来减少了四个数量级。
网络部分连通的思想,是受启发于生物学里面的视觉系统结构,视觉皮层的神经元就是局部接受信息的(即这些神经元只响应某些特定区域的刺激)。
利用这样一种局部连接结构,一方面降低了需要学习的参数数量,提高了前向传播和反向传播的计算速度;另一方面,这种结构所具有的局部感受能力也更符合人类视觉系统的认知方式。同时,卷积神经网络真正实现了端到端的学习,一个网络结构包括了特征提取和分类两部分,更适合实际业务中的算法部署。
1.3 卷积神经网络的结构
UFLDL给出的卷积神经网络的结构如下:
CodeMeals绘制的一个卷积神经网络结构如下:
这张图清晰的给出了CNN结构中,从输入到输出之间的卷积层、池化层和最后的全连接层,以及各个层之间的连接关系。
二、卷积(Convolution)
2.1 卷积操作与特征图
局部连接的具体实现方式,就是所谓卷积操作!但要注意的是,这不是真正的卷积操作,而是相关操作(也就是两个同型矩阵对应元素相乘将结果相加),只是因为可以使用卷积的方式进行计算,所以就使用了这样一个名字,在后面会通过图表和公式来解释这个问题。
请出最经典的卷积操作示意图:
UFLDL中的这张GIF图基本就解释了卷积神经网络中的核心计算 - 卷积操作。再次强调, 这里执行的其实是相关操作!而非真正的卷积(真正的卷积操作=将卷积核旋转180度后再与矩阵进行相关操作)!
Feature map的解释
卷积操作的本质其实是一次active,也就是对大尺寸图像中的patch逐个进行激活,得到的激活值组合起来就是卷积特征图(feature map)。
Feature map的尺寸
假定图像大小是 r * c,卷积核大小是 a * b,则最终得到的特征图尺寸:(r−a+1)×(c−b+1)
2.2 卷积核
卷积核(kernel)是一个或一组权重矩阵,每个权重矩阵是一个正方形,多个权重矩阵叠加构成一个卷积核(一个cube or volume)。
注意两点:
1)卷积核(kernel)的权重是需要学习的,CNN的训练就是在学习这些卷积核的权重矩阵;
2)卷积核(kernel)中的权重矩阵数量与输入层(例如图像层或Pooling层)的feature map数量可以是一致的,也可以是不一致的。
2.3 卷积神经网络前向传播中的卷积
卷积神经网络中前向传播中的卷积操作过程:
很多同学都会在卷积核这里感到困惑,搞不清楚卷积核的结构,以及卷积计算的过程。我们就说上面的图, Pooling Layer有3个feature map,Conv Layer有4个feature map,对应有4个卷积核,每个卷积核中有3个权重矩阵。在卷积操作时,卷积核中的3个权重矩阵分别对应Pooling Layer中的3个feature map,计算过程如图所示,不再赘述。
卷积核的结构是很灵活的,上面的图示是其中一种,即卷积核中的权重矩阵数量与输入层的feature map的数量一致,卷积时,卷积核中的权重矩阵与输入层的feature map对应执行卷积操作,再将输出的temp feature map叠加求和,进行激活(例如Sigmoid),生成一个feature map。另外,卷积核中也可以只有1个权重矩阵(或者说所有权重矩阵都相同),卷积时,该权重矩阵与输入层的所有feature map执行卷积操作,再将输出的temp feature map叠加求和,进行激活(例如Sigmoid),生成一个feature map。
2.4 卷积操作的公式
将上一幅图进行修改,来理解卷积操作的数学形式。
公式如下:
第l+1个卷积层第i个特征图a
i(l+1)计算:
注意这里使用的计算符号⊙,这表示相关操作,因为CNN中的卷积计算实质上是相关操作,各位一定要弄清楚!
2.5 卷积神经网络在学什么?
卷积神经网络的卷积核到底在学什么呢?其实可以看作是在学习一个局部模式检测器,因此对一副图像进行卷积操作的过程可以看作是:局部模式探测过程。这和Sift、Surf等局部特征提取过程其实是类似的。
如果对卷积核进行可视化,我们就可以观察到一个个局部模式。其可视化效果与sparse autoencoder练习中weights可视化的结果类似。
三、池化(Pooling)
3.1 池化操作
池化操作(Pooling)其实就是在计算一种统计特征,一般是取平均值或者取最大值,这些统计特征不仅具有低得多的维度,同时还会改善结果(不容易过拟合)。
请出经典的池化操作示意图(池化不重合区域 ):
注意两点:
1) 从计算方式上来说,池化也是通过卷积操作完成,但池化卷积核的参数是固定的(至少在UFLDL里是这样),所以权重矩阵的参数不需要学习。
2) Pooling层的feature map与Conv层的feature map是一一对应的;
3.2 平均池化操作
Mean Pooling操作的示意,注意kernel size和stride的设置。
Max Pooling操作的示意:
max-pooling需要注意记录每次pooling时最大值的位置,在反向传播回传误差时需要使用。
关于max-pooling和mean-pooling的区别:
无论是max还是average都是在提取区域特征,均相当于一种抽象,抽象就是过滤掉了不必要的信息(当然也会损失信息细节),所以在抽象层次上可以进行更好的识别。
至于max与average效果是否一样,还是要看需要识别的图像细节特征情况,这个不一定的,不过据说差异不会超过2%。
不过仔细点说的话,评估特征提取的误差主要来自两个方面:
(1)邻域大小受限造成的估计值方差增大,average能减小这种误差。
(2)卷积层参数误差造成估计均值的偏移,max能减小这种误差。
也就是说,average对背景保留更好,max对纹理提取更好,如果是识别字体什么的,应该考虑max。
3.3 卷积神经网络前向传播中的池化
卷积神经网络中前向传播中的池化(Pooling)操作过程:
池化操作是比较好理解的,对应在CNN中的结构也很好理解,即,卷积层与池化层之间的feature map是一一对应的。