继续温故,CNN篇。这次重新思考的是CNN中每层的作用,以及之前没有思考过的BP中梯度更新的过程。
CNN的结构
最典型的CNN的结构是由如若干个卷积层+池化层,再接若干个(一般一到两个)全连接层组成。
总的来说,这个最典型的CNN结构,终究是起到一个分类器的作用。
卷积层做不同特征提取,采样层负责选择相应的特征,全连接层负责分类。
卷积层
卷积运算这里就不讲了,这里讲一下filter。filter对应的神经网络的概念其实是权重,filter矩阵和图像的单通道像素值进行点成,最后将多个通道的结果求sum,作为一个filter的卷积结果,这就是为什么filter的depth,可以理解为下一层中的通道数。
有几个点注意:
- 为什么要将不同通道的结果最后相加呢? 这里可以理解为filter对不同的颜色通道做卷积得到的是一个特征的分量,最后将所有特征分量相加才是一个完整的feature map。
- 如果识别一张人脸,肯定是眼睛下面是鼻子,下面是嘴巴,倒过来也是嘴巴下面是鼻子,鼻子字面是眼睛。图像是存在空间位置关系的,所以滑动窗口是从左往右,从上往下。stride会是遗失部分信息,如果保证在一个合理小的范围内,但是这个并不影响结果
- 为什么要padding?padding可以让我们获取图像边缘更多的信息,另外控制卷积后的feature map的size
池化层
池化层的的运作方式可以这样理解: 一个2*2的卷积核,这个卷积核不是做卷积运算,而是取最大值(平均值)。
Pooling层说到底还是一个特征选择,信息过滤的过程,也就是说我们损失了一部分信息,这是一个和计算性能的一个妥协,随着运算速度的不断提高,我这个按道理说会妥协会越来越小。现在有些网络就开始少用或者不用pooling了。
池化的常见方法分为max pooling,average pooling。
采用max pooling,最主要的作用是提高空间不变性。因为一个像素不管最大值上在池化框内的哪个位置,都可以取到最大值。
average pooling,就是将池化框内的值求平均,这样做的好处可以减少池化框大小带来的误差,更多的保留背景信息。
而max pooling是减少卷积层权值参数的误差,更多的保留纹理信息。
全连接层(FC)
以两层全连接层为例,主要有三个问题。
-
最后一个池化层的结果怎么连接上FC的?
这个问题,在Keras中的代码结构是加了一个Flatten操作(展平),比如把一个(n * w * h)的变成一个(1 * 1 * nwh)的向量结构(可以理解为3D -> 2D),(nwh)是神经元个数。这里也可以换种理解方式,比如说最后一层卷积可得输出为77512,FC层含4096个神经元。感觉到不对啊,77512(这个数值是编的,应该是25644)是怎么展都展平不了到4096啊。
pooling层到FC层中间做了一个卷积,如下图所示。
因为有4096个神经元,实际就是用一个3x3x5x4096的卷积层去卷积激活函数的输出。这些filter是训练过程中更新的。
-
第一个FC层的作用是什么?
pooling到FC层,中间做的这个flatten(卷积),其实是把前面卷积提取到的抽象特征(“分布式特征表示”Distributed Feature Representation,论文里是这么说的,什么鬼其实我也不太懂),映射到标记好的样本空间的一个过渡。因为我们标记的是分类结果,而pooling输出的feature map,这中间必然有个映射关系。 -
第二个FC层有什么用?
其实到这一步就可以理解为神经网络(MLP)的结构的后两层了。特征都是标记样本空间的特征,最后做一个softmax的分类就OK。
因为FC层参数特别多,占到整个CNN中参数的80%左右,所以一些网络(ResNet和GoogLeNet等)取消了全连接层。全卷积神经网络(FCN)将最后的FC层都换成用1*1的卷积核做的卷积,最后分类。
向后传播过程中的权值变化
CNN梯度下降中的求导公式太多,具体我推荐两个博客:
https://www.cnblogs.com/pinard/p/6494810.html (非常详细,一下公式就是在这篇博客里面摘出来的)
https://www.jefkine.com/general/2016/09/05/backpropagation-in-convolutional-neural-networks/ (外国小哥的推导,图文并茂)
我这里写卷积层和池化层的向前推导,因为以前没太弄明白是怎么回事,全连接层的反向求导和mlp中的一样。
卷积层的向前求导
这里是一个卷积核的求导过程
假设我们输入a是4x4的矩阵,卷积核W是3x3的矩阵,输出z是2x2的矩阵,那么反向传播的z的梯度误差δ也是2x2的矩阵。卷积过程实际上是以下的式子:
既:
对a求导,即为
可以求出9个式子:
等等
最后用矩阵表示出来是:
看到没有,这里的w和之前矩阵公式里的那个w有一个对角翻转。
所以我们得到一个核心的卷积层求梯度的公式:
卷积核被旋转了180度,即式子中的rot180()。
池化层的向前求导
pooling层可以这样理解,如果是max pooling,就是一个最大选择,将小的数都丢掉了,实际上这就相当于dropout类似的意义。所以我们只需要关注对没有丢弃的元素做反向求导。
average pooling的话,就是把所有子矩阵的各个池化局域的值取平均后放在还原后的子矩阵位置。这个过程一般叫做upsample。具体可以参考我给出的第一个博客,里面的解释非常详细。
网友评论