介绍CNN的BP算法之前还是先看下DNN,两者有很多相似的地方
DNN的BP算法
1.第i层神经元的输出
2.第i层神经元的输入
3.从第l-1层mapping到l层的权值矩阵
4.与上面参数对应的偏移量
5.train data的输入
6.train data的输出
7.设我们的输出层为第l层,对应,采用均方差来度量误差,对应的损失函数为
有了损失函数之后就开始采用梯度下降法,记住我们的目的是为了求出每层的和,先来看下输出层的输出
我们把(2)代入(1)中得到
我们利用链式求导法,求得,的梯度
其中表示两个向量的乘积
上面两个式子有个公共的部分,那就是,我们可以单独把它拎出来看
我们这里引入了一个新的符号,这样我们就可以合并(4)、(5)两个式子
此时形势简单多了,我们只需要把,求出来就OK了
仔细看下式子(6),我们的数据按网络结果正向传播到输出层的时候可以求出来,我们能不能依靠来求,,呢?
(因为反向传播算法,所以这里考虑能不能由后面的一项求相应的前面一项)
继续使用链式求导法可以得出:
可见,想通过来求,关键是看怎么求好,我们再来看和的关系,由式子(2)可以得出。
那么,代入(9)中得到。
我们根据,再根据上式的递推关系就可以求出每层的,也就可以求出每层的的梯度了。
CNN的BP算法
现在再来看看CNN的BP算法,由于CNN可以分为卷积层,池化层和全连接层,全连接层和DNN一样,不需要再说了,主要看另外两层,首先看看卷积层。
再说CNN的基本思想的时候我们已经给出了卷积层正向传播的公式:
仔细看这个公式,和DNN正向传播的公式唯一区别就是有卷积操作,注意这不是乘号*,我们还沿用和上述DNN相同的损失函数。公式(7),(8),(9)同样适用于卷积层,但是和的关系变了
这里和DNN的区别就是,对于含有卷积的式子求导,卷积核(W)被旋转180度,意思就是上下翻转,然后左右翻转,因此我们的公式(12)变成了:
对卷积求导原理感兴趣的同学可以自行百度。
有了对卷积求导的知识就可以很轻易写出:
刚刚说公式(8)同样适合卷积层其实不够严谨,对于b的梯度不能像DNN那样直接等于 ,因为b是一个向量,而这里的因为经过了卷积求导后变成了一个三维的张量,所以可以近似地用一个误差向量代替:
到这里我们已经解决了如何求卷积层上的的梯度,就剩池化层了,池化层上的梯度怎么求呢?不对,基本思想里说过池化层压根就没有呀。那是不是可以直接忽略池化层呢?不行!CNN网络结构是一个整体,BP算法运行时,数据流肯定会经过池化层,误差在经过池化层后也会发生相应的变化。那求它的什么呢?想想,卷积层在求时要依赖后一层的,卷积层的后一层不正是池化层吗?所以我们要求出池化层的。
在基本思想里面讲到,前向传播时池化层一般的操作是MAX或Average等,我们现在是要从压缩过的误差来还原一个较大区域的误差。我们首先把所有的子矩阵大小还原成池化前的大小,如果用的是MAX操作的话,就把所有子矩阵各个池化局部的值放在之前做前向传播时得到最大值的位置。这个过程叫做unsample。
举个例子就好理解了,假设第k个子矩阵是
假设我们池化窗口大小是2*2,则将其还原成原来大小就是
这里假设我们之前前向传播时记录的最大值的位置分别是左上,右下,右上,左下,unsample后就是
由于我们池化层是对卷积层的输出做池化的,所以在求时不同于卷积层和全连接层,链式求导时先是对上一层的求偏导,再乘上上一层的的偏导,公式如下:
概括下:
这里不同的池化操作也对应着不同的unsample操作