在SIGAI之前的公众号文章“反向传播算法推导-全连接神经网络”中,我们推导了全连接神经网络的反向传播算法。其核心是定义误差项,以及确定误差项的递推公式,再根据误差项得到对权重矩阵、偏置向量的梯度。最后用梯度下降法更新。卷积神经网络由于引入了卷积层和池化层,因此情况有所不同。在今天这篇文章中,我们将详细为大家推导卷积神经网络的反向传播算法。对于卷积层,我们将按两条路线进行推导,分别是标准的卷积运算实现,以及将卷积转化成矩阵乘法的实现。在文章的最后一节,我们将介绍具体的工程实现,即卷积神经网络的卷积层,池化层,激活函数层,损失层怎样完成反向传播功能。
回顾
首先回顾一下全连接神经网络反向传播算法的误差项递推计算公式。根据第l层的误差项计算第l-1层的误差项的递推公式为:
![](https://img.haomeiwen.com/i12864544/d827831644fb575d.png)
其中W为权重矩阵,u为临时变量,f为激活函数。根据误差项计算权重梯度的公式为:
![](https://img.haomeiwen.com/i12864544/c15f8c7df5767744.png)
其中x为本层的输入向量。这几组公式具有普遍意义,对于卷积神经网络的全连接层依然适用。如果你对这些公式的推导还不清楚,请先去阅读我们之前的文章“反向传播算法推导-全连接神经网络”。
卷积层
首先推导卷积层的反向传播计算公式。正向传播时,卷积层实现的映射为:
![](https://img.haomeiwen.com/i12864544/fd03e11bcbd6f01b.png)
我们用前面的这个例子来进行计算:
卷积输出图像的任意一个元素都与卷积核矩阵的任意一个元素都有关,因为输出图像的每一个像素值都共用了一个卷积核模板。反向传播时需要计算损失函数对卷积核以及偏置项的偏导数,和全连接网络不同的是,卷积核要作用于同一个图像的多个不同位置。
上面的描述有些抽象,下面我们用一个具体的例子来说明。假设卷积核矩阵为:
![](https://img.haomeiwen.com/i12864544/ace454a59175e072.png)
输入图像是:
![](https://img.haomeiwen.com/i12864544/09f8e5b6838313af.png)
卷积之后产生的输出图像是U,注意这里只进行了卷积、加偏置项操作,没有使用激活函数:
![](https://img.haomeiwen.com/i12864544/a01f11e775a174c7.png)
正向传播时的卷积操作为:
![](https://img.haomeiwen.com/i12864544/e1c579eeccd36abb.png)
反向传播时需要计算损失函数对卷积核以及偏置项的偏导数,和全连接网络不同的是,卷积核要反复作用于同一个图像的多个不同位置。根据链式法则,损失函数对第层的卷积核的偏导数为:
![](https://img.haomeiwen.com/i12864544/a689632bbced047d.png)
![](https://img.haomeiwen.com/i12864544/19851cdd0063f4c1.png)
这是激活函数对输入值的导数,激活函数作用于每一个元素,产生同尺寸的输出图像,和全连接网络相同。第三个乘积项为:
![](https://img.haomeiwen.com/i12864544/c23ee1ce209fb617.png)
这是损失函数对临时变量的偏导数。和全连接型不同的是这是一个矩阵:
![](https://img.haomeiwen.com/i12864544/f43632fb9a4e5ac0.png)
尺寸和卷积输出图像相同,而全连接层的误差向量和该层的神经元个数相等。这样有:
![](https://img.haomeiwen.com/i12864544/3a4e38966a26a098.png)
![](https://img.haomeiwen.com/i12864544/8994325da69ca933.png)
下面计算损失函数对卷积核各个元素的偏导数,根据链式法则有:
![](https://img.haomeiwen.com/i12864544/1a5713de2118cac4.png)
![](https://img.haomeiwen.com/i12864544/bac21a6bc449127f.png)
其他的以此类推。从上面几个偏导数的值我们可以总结出这个规律:损失函数对卷积核的偏导数实际上就是输入图像矩阵与误差矩阵的卷积:
![](https://img.haomeiwen.com/i12864544/bf8a47d407e10eb2.png)
正向传播时的卷积操作为:
![](https://img.haomeiwen.com/i12864544/a7d45fba497e9ab7.png)
根据定义:
![](https://img.haomeiwen.com/i12864544/a6b61585d282086f.png)
由于:
![](https://img.haomeiwen.com/i12864544/4c2cdef6aa59fc2a.png)
因此有:
![](https://img.haomeiwen.com/i12864544/9e80a00103db3c77.png)
类似的可以得到:
![](https://img.haomeiwen.com/i12864544/2347d3eacb97492c.png)
从而有:
![](https://img.haomeiwen.com/i12864544/537a4d986cdcbca8.png)
类似的有:
![](https://img.haomeiwen.com/i12864544/324c4fd6cbd611e2.png)
![](https://img.haomeiwen.com/i12864544/f587bf4e0b0ff245.png)
将上面的结论推广到一般情况,我们得到误差项的递推公式为:
![](https://img.haomeiwen.com/i12864544/59e1b555852dc5d4.png)
其中rot180表示矩阵顺时针旋转180度操作。至此根据误差项得到了卷积层的权重,偏置项的偏导数;并且把误差项通过卷积层传播到了前一层。推导卷积层反向传播算法计算公式的另外一种思路是把卷积运算转换成矩阵乘法,这种做法更容易理解,在后面将会介绍。
池化层
![](https://img.haomeiwen.com/i12864544/36ace30e7ce19581.png)
![](https://img.haomeiwen.com/i12864544/26eff570e48f593a.png)
同样的,我们给出推导过程。假设池化函数为:
![](https://img.haomeiwen.com/i12864544/81308b8e23eb0d68.png)
至此我们得到了卷积层和池化层的反向传播实现。全连接层的反向传播计算方法和全连接神经网络相同,组合起来我们就得到了整个卷积网络的反向传播算法计算公式。
将卷积转化成矩阵乘法
如果用标准的形式实现卷积,则要用循环实现,依次执行乘法和加法运算。为了加速,可以将卷积操作转化成矩阵乘法实现,以充分利用GPU的并行计算能力。
整个过程分为以下3步:
1.将待卷积图像、卷积核转换成矩阵
2.调用通用矩阵乘法GEMM函数对两个矩阵进行乘积
3.将结果矩阵转换回图像
在反卷积的原理介绍中,我们也介绍了这种用矩阵乘法实现卷积运算的思路。在Caffe的实现中和前面的思路略有不同,不是将卷积核的元素复制多份,而是将待卷积图像的元素复制多份。
![](https://img.haomeiwen.com/i12864544/15e58a5321e60d52.png)
![](https://img.haomeiwen.com/i12864544/d04ddafebc1f539a.png)
![](https://img.haomeiwen.com/i12864544/0805c2403161ac9e.png)
如果卷积核有多个通道,就将这多个通道拼接起来,形成一个更大的行向量。由于卷积层有多个卷积核,因此这样的行向量有多个,将这些行向量合并在一起,形成一个矩阵:
![](https://img.haomeiwen.com/i12864544/194d8531d763958f.png)
有了上面这些矩阵,最后就将卷积操作转换成如下的矩阵乘积:
![](https://img.haomeiwen.com/i12864544/147ae0d45d3fe9cb.png)
乘积结果矩阵的每一行是一个卷积结果图像。下面用一个实际的例子来说明。假设输入图像为:
![](https://img.haomeiwen.com/i12864544/ef1dd2cd0429021d.png)
卷积核为:
![](https://img.haomeiwen.com/i12864544/6db145f054ba5cdb.png)
则输入图像的第一个卷积位置的子图像为:
![](https://img.haomeiwen.com/i12864544/1141e0a15424d171.png)
转化为列向量后为:
![](https://img.haomeiwen.com/i12864544/cc4b03dc7bd0e86a.png)
第二个卷积位置的子图像为:
![](https://img.haomeiwen.com/i12864544/6a10b8116cded89d.png)
转化成列向量为:
![](https://img.haomeiwen.com/i12864544/be672d1bce9493be.png)
总共有4个卷积子图像,这样整个图像转换成矩阵之后为:
![](https://img.haomeiwen.com/i12864544/e2cb0a9ae61d05fe.png)
将卷积核转换成矩阵之后为:
![](https://img.haomeiwen.com/i12864544/64788e719364cebc.png)
读者可以验证,矩阵乘法:
![](https://img.haomeiwen.com/i12864544/53bd1261316c9809.png)
即为卷积的结果。
采用这种矩阵乘法之后,反向传播求导可以很方面的通过矩阵乘法实现,和全连接神经网络类似。假设卷积输出图像为Y,即:Y=KX
则我们可以很方便的根据损失函数对的梯度计算出对卷积核的梯度,根据之前的文章“反向传播算法推导-全连接神经网络”中证明过的结论,有:
![](https://img.haomeiwen.com/i12864544/2ee7d85f648f04a5.png)
而误差项传播到前一层的计算公式为:
![](https://img.haomeiwen.com/i12864544/9596061ea84059f3.png)
工程实现
下面我们介绍全连接层,卷积层,池化层,激活函层,损失层的工程实现细节。核心是正向传播和反向传播的实现。
在实现时,由于激活函数对全连接层,卷积层,以后要讲述的循环神经网络的循环层都是一样的,因此为了代码复用,灵活组合,一般将激活函数单独拆分成一层来实现。
![](https://img.haomeiwen.com/i12864544/72ed469bfc839a22.png)
在之前的文章“反向传播算法推导-全连接神经网络”中已经介绍过,激活函数实现的是向量到向量的逐元素映射,对输入向量的每个分量进行激活函数变换。正向传播时接受前一层的输入,通过激活函数作用于输入数据的每个元素之后产生输出。反向传播时接受后一层传入的误差项,计算本层的误差项并把误差项传播到前一层,计算公式为:
![](https://img.haomeiwen.com/i12864544/4a1a557bf2320301.png)
由于激活层没有需要训练得到的参数,因此无需根据误差项计算本层的梯度值,只需要将误差传播到前一层即可。
拆出激活函数之后,全连接层的输入数据是一个向量,计算该向量与权重矩阵的乘积,如果需要还要加上偏置,最后产生输出。正向传播的计算公式为:
![](https://img.haomeiwen.com/i12864544/688e8d74c1e8f734.png)
反向传播时计算本层权重与偏置的导数:
![](https://img.haomeiwen.com/i12864544/9dd2e2de5a93fafa.png)
另外还要将误差传播到前一层:
![](https://img.haomeiwen.com/i12864544/63eb1fd7501cb5bd.png)
卷积层和池化层的反向传播实现已经在前面介绍了,因此在这里不再重复。
损失层实现各种类型的损失函数,它们仅在训练阶段使用,是神经网络的最后一层,也是反向传播过程的起点。损失层的功能是在正向传播时根据传入的数据以及函数的参数计算损失函数的值,送入到求解器中使用;在反向传播时计算损失函数对输入数据的导数值,传入前一层。
推荐阅读
[1] 机器学习-波澜壮阔40年 SIGAI 2018.4.13.
[2] 学好机器学习需要哪些数学知识?SIGAI 2018.4.17.
[3] 人脸识别算法演化史 SIGAI 2018.4.20.
[4] 基于深度学习的目标检测算法综述 SIGAI 2018.4.24.
[5] 卷积神经网络为什么能够称霸计算机视觉领域? SIGAI 2018.4.26.
[6] 用一张图理解SVM的脉络 SIGAI 2018.4.28.
[7] 人脸检测算法综述 SIGAI 2018.5.3.
[8] 理解神经网络的激活函数 SIGAI 2018.5.5.
[9] 深度卷积神经网络演化历史及结构改进脉络-40页长文全面解读 SIGAI 2018.5.8.
[10] 理解梯度下降法 SIGAI 2018.5.11.
[11] 循环神经网络综述—语音识别与自然语言处理的利器 SIGAI 2018.5.15
[12] 理解凸优化 SIGAI 2018.5.18
[13] 【实验】理解SVM的核函数和参数 SIGAI 2018.5.22
[14] 【SIGAI综述】行人检测算法 SIGAI 2018.5.25
[15] 机器学习在自动驾驶中的应用—以百度阿波罗平台为例(上) SIGAI 2018.5.29
[16] 理解牛顿法 SIGAI 2018.5.31
[17] 【群话题精华】5月集锦—机器学习和深度学习中一些值得思考的问题 SIGAI 2018.6.1
[18] 大话Adaboost算法 SIGAI 2018.6.2
[19] FlowNet到FlowNet2.0:基于卷积神经网络的光流预测算法 SIGAI 2018.6.4
[20] 理解主成分分析(PCA) SIGAI 2018.6.6
[21] 人体骨骼关键点检测综述 SIGAI 2018.6.8
[22] 理解决策树 SIGAI 2018.6.11
[23] 用一句话总结常用的机器学习算法 SIGAI 2018.6.13
[24] 目标检测算法之YOLO SIGAI 2018.6.15
[25] 理解过拟合 SIGAI 2018.6.18
[26] 理解计算:从√2到AlphaGo ——第1季 从√2谈起 SIGAI 2018.6.20
[27] 场景文本检测——CTPN算法介绍 SIGAI 2018.6.22
[28] 卷积神经网络的压缩和加速 SIGAI 2018.6.25
[29] k近邻算法 SIGAI 2018.6.27
[30] 自然场景文本检测识别技术综述 SIGAI 2018.6.27
[31] 理解计算:从√2到AlphaGo ——第2季 神经计算的历史背景 SIGAI 2018.7.4
[32] 机器学习算法地图 SIGAI2018.7.6
[33] 反向传播算法推导-全连接神经网络 SIGAI2018.7.9
[34] 生成式对抗网络模型综述 SIGAI0709.
[35] 怎样成为一名优秀的算法工程师SIGAI0711.
[36] 理解计算:从根号2到AlphaGo——第三季 神经网络的数学模型 SIGAI0716
[38] 基于深度负相关学习的人群计数方法
[39] 流形学习概述
[40] 关于感受野的总结
[41] 随机森林概述
[44] 机器学习和深度学习中值得弄清楚的一些问题
[45]基于深度神经网络的自动问答系统概述 SIGAI0803
网友评论