在卷积神经网络(CNN)前向传播算法中,我们对CNN的前向传播算法做了总结,基于CNN前向传播算法的基础,我们下面就对CNN的反向传播算法做一个总结。在阅读本文前,建议先研究DNN的反向传播算法:深度神经网络(DNN)反向传播算法(BP)

1. 回顾DNN的反向传播算法

    我们首先回顾DNN的反向传播算法。在DNN中,我们是首先计算出输出层的$\delta^L$:$$\delta^L = \frac{\partial J(W,b)}{\partial z^L} = \frac{\partial J(W,b)}{\partial a^L}\odot \sigma^{'}(z^L)$$

    利用数学归纳法,用$\delta^{l+1}$的值一步步的向前求出第l层的$\delta^l$,表达式为:$$\delta^{l} = \delta^{l+1}\frac{\partial z^{l+1}}{\partial z^{l}} = (W^{l+1})^T\delta^{l+1}\odot \sigma^{'}(z^l)$$

    有了$\delta^l$的表达式,从而求出$W,b$的梯度表达式:$$\frac{\partial J(W,b)}{\partial W^l} = \frac{\partial J(W,b,x,y)}{\partial z^l} \frac{\partial z^l}{\partial W^l} = \delta^{l}(a^{l-1})^T$$$$\frac{\partial J(W,b,x,y)}{\partial b^l} = \frac{\partial J(W,b)}{\partial z^l} \frac{\partial z^l}{\partial b^l} = \delta^{l}$$

    有了$W,b$梯度表达式,就可以用梯度下降法来优化$W,b$,求出最终的所有$W,b$的值。

    现在我们想把同样的思想用到CNN中,很明显,CNN有些不同的地方,不能直接去套用DNN的反向传播算法的公式。

2. CNN的反向传播算法思想

    要套用DNN的反向传播算法到CNN,有几个问题需要解决:

    1)池化层没有激活函数,这个问题倒比较好解决,我们可以令池化层的激活函数为$\sigma(z) = z$,即激活后就是自己本身。这样池化层激活函数的导数为1.

    2)池化层在前向传播的时候,对输入进行了压缩,那么我们现在需要向前反向推导$\delta^{l-1}$,这个推导方法和DNN完全不同。

    3) 卷积层是通过张量卷积,或者说若干个矩阵卷积求和而得的当前层的输出,这和DNN很不相同,DNN的全连接层是直接进行矩阵乘法得到当前层的输出。这样在卷积层反向传播的时候,上一层的$\delta^{l-1}$递推计算方法肯定有所不同。

    4)对于卷积层,由于$W$使用的运算是卷积,那么从$\delta^l$推导出该层的所有卷积核的$W,b$的方式也不同。

    从上面可以看出,问题1比较好解决,但是问题2,3,4就需要好好的动一番脑筋了,而问题2,3,4也是解决CNN反向传播算法的关键所在。另外大家要注意到的是,DNN中的$a_l,z_l$都只是一个向量,而我们CNN中的$a_l,z_l$都是一个张量,这个张量是三维的,即由若干个输入的子矩阵组成。

    下面我们就针对问题2,3,4来一步步研究CNN的反向传播算法。

    在研究过程中,需要注意的是,由于卷积层可以有多个卷积核,各个卷积核的处理方法是完全相同且独立的,为了简化算法公式的复杂度,我们下面提到卷积核都是卷积层中若干卷积核中的一个。

3. 已知池化层的$\delta^l$,推导上一隐藏层的$\delta^{l-1}$   

    我们首先解决上面的问题2,如果已知池化层的$\delta^l$,推导出上一隐藏层的$\delta^{l-1}$。

    在前向传播算法时,池化层一般我们会用MAX或者Average对输入进行池化,池化的区域大小已知。现在我们反过来,要从缩小后的误差$\delta^l$,还原前一次较大区域对应的误差。

    在反向传播时,我们首先会把$\delta^l$的所有子矩阵矩阵大小还原成池化之前的大小,然后如果是MAX,则把$\delta^l$的所有子矩阵的各个池化局域的值放在之前做前向传播算法得到最大值的位置。如果是Average,则把$\delta^l$的所有子矩阵的各个池化局域的值取平均后放在还原后的子矩阵位置。这个过程一般叫做upsample。

    用一个例子可以很方便的表示:假设我们的池化区域大小是2x2。$\delta^l$的第k个子矩阵为:$$\delta_k^l =
\left( \begin{array}{ccc}
2& 8 \\
4& 6 \end{array} \right)$$

    由于池化区域为2x2,我们先讲$\delta_k^l$做还原,即变成:$$
\left( \begin{array}{ccc}
0&0&0&0 \\ 0&2& 8&0 \\ 0&4&6&0 \\
0&0&0&0 \end{array} \right)$$

    如果是MAX,假设我们之前在前向传播时记录的最大值位置分别是左上,右下,右上,左下,则转换后的矩阵为:$$
\left( \begin{array}{ccc}
2&0&0&0 \\ 0&0& 0&8 \\ 0&4&0&0 \\
0&0&6&0 \end{array} \right)$$

    如果是Average,则进行平均:转换后的矩阵为:$$
\left( \begin{array}{ccc}
0.5&0.5&2&2 \\ 0.5&0.5&2&2 \\ 1&1&1.5&1.5 \\
1&1&1.5&1.5 \end{array} \right)$$

    这样我们就得到了上一层 $\frac{\partial J(W,b)}{\partial a_k^{l-1}} $的值,要得到$\delta_k^{l-1}$:$$\delta_k^{l-1} = \frac{\partial J(W,b)}{\partial a_k^{l-1}} \frac{\partial  a_k^{l-1}}{\partial z_k^{l-1}} = upsample(\delta_k^l) \odot \sigma^{'}(z_k^{l-1})$$

    其中,upsample函数完成了池化误差矩阵放大与误差重新分配的逻辑。

    我们概括下,对于张量$\delta^{l-1}$,我们有:$$\delta^{l-1} =  upsample(\delta^l) \odot \sigma^{'}(z^{l-1})$$

4. 已知卷积层的$\delta^l$,推导上一隐藏层的$\delta^{l-1}$  

    对于卷积层的反向传播,我们首先回忆下卷积层的前向传播公式:$$  a^l= \sigma(z^l) = \sigma(a^{l-1}*W^l +b^l) $$

    其中$n\_in$为上一隐藏层的输入子矩阵个数。

    在DNN中,我们知道$\delta^{l-1}$和$\delta^{l}$的递推关系为:$$\delta^{l} = \frac{\partial J(W,b)}{\partial z^l} = \frac{\partial J(W,b)}{\partial z^{l+1}}\frac{\partial z^{l+1}}{\partial z^{l}} = \delta^{l+1}\frac{\partial z^{l+1}}{\partial z^{l}}$$

    因此要推导出$\delta^{l-1}$和$\delta^{l}$的递推关系,必须计算$\frac{\partial z^{l}}{\partial z^{l-1}}$的梯度表达式。

    注意到$z^{l}$和$z^{l-1}$的关系为:$$z^l = a^{l-1}*W^l +b^l =\sigma(z^{l-1})*W^l +b^l  $$

    因此我们有:$$\delta^{l-1} =  \delta^{l}\frac{\partial z^{l}}{\partial z^{l-1}} = \delta^{l}*rot180(W^{l}) \odot  \sigma^{'}(z^{l-1}) $$

    这里的式子其实和DNN的类似,区别在于对于含有卷积的式子求导时,卷积核被旋转了180度。即式子中的$rot180()$,翻转180度的意思是上下翻转一次,接着左右翻转一次。在DNN中这里只是矩阵的转置。那么为什么呢?由于这里都是张量,直接推演参数太多了。我们以一个简单的例子说明为啥这里求导后卷积核要翻转。

    假设我们$l-1$层的输出$a^{l-1}$是一个3x3矩阵,第$l$层的卷积核$W^l$是一个2x2矩阵,采用1像素的步幅,则输出$z^{l}$是一个3x3的矩阵。我们简化$b^l都是0$,则有$$a^{l-1}W^l = z^{l}$$

    我们列出$a,W,z$的矩阵表达式如下:$$
\left( \begin{array}{ccc}
a_{11}&a_{12}&a_{13} \\ a_{21}&a_{22}&a_{23}\\
a_{31}&a_{32}&a_{33} \end{array} \right)    *  \left( \begin{array}{ccc}
w_{11}&w_{12}\\
w_{21}&w_{22} \end{array} \right) = \left( \begin{array}{ccc}
z_{11}&z_{12}\\
z_{21}&z_{22} \end{array} \right)$$

    利用卷积的定义,很容易得出:$$z_{11} = a_{11}w_{11} + a_{12}w_{12} + a_{21}w_{21} +   a_{22}w_{22} $$$$z_{12} = a_{12}w_{11} + a_{13}w_{12} + a_{22}w_{21} +   a_{23}w_{22} $$$$z_{21} = a_{21}w_{11} + a_{22}w_{12} + a_{31}w_{21} +   a_{32}w_{22} $$$$z_{22} = a_{22}w_{11} + a_{23}w_{12} + a_{32}w_{21} +   a_{33}w_{22} $$

    接着我们模拟反向求导:$$\nabla a^{l-1} = \frac{\partial J(W,b)}{\partial a^{l-1}} = \frac{\partial J(W,b)}{\partial z^{l}} \frac{\partial z^{l}}{\partial a^{l}} = \delta^{l} \frac{\partial z^{l}}{\partial a^{l}}$$

    从上式可以看出,对于$a^{l-1}$的梯度误差$\nabla a^{l-1}$,等于第$l$层的梯度误差乘以$\frac{\partial z^{l}}{\partial a^{l}}$,而$\frac{\partial z^{l}}{\partial a^{l}}$对应上面的例子中相关联的$w$的值。假设我们的$z$矩阵对应的反向传播误差是$\delta_{11}, \delta_{12}, \delta_{21}, \delta_{22}$组成的2x2矩阵,则利用上面梯度的式子和4个等式,我们可以分别写出$\nabla a^{l-1}$的9个标量的梯度。

    比如对于$a_{11}$的梯度,由于在4个等式中$a_{11}$只和$z_{11}$有乘积关系,从而我们有:$$ \nabla a_{11} = \delta_{11}w_{11}$$

    对于$a_{12}$的梯度,由于在4个等式中$a_{12}$和$z_{12},z_{11}$有乘积关系,从而我们有:$$ \nabla a_{12} = \delta_{11}w_{12} + \delta_{12}w_{11}$$

    同样的道理我们得到:$$ \nabla a_{13} = \delta_{12}w_{12} $$$$\nabla a_{21} = \delta_{11}w_{21} + \delta_{21}w_{11}$$$$\nabla a_{22} = \delta_{11}w_{22} + \delta_{12}w_{21} + \delta_{21}w_{12} + \delta_{22}w_{11}  $$$$ \nabla a_{23} = \delta_{12}w_{22} + \delta_{22}w_{12}$$$$ \nabla a_{31} = \delta_{21}w_{21}$$$$ \nabla a_{32} = \delta_{21}w_{22} + \delta_{22}w_{21}$$$$ \nabla a_{33} = \delta_{22}w_{22} $$

    这上面9个式子其实可以用一个矩阵卷积的形式表示,即:$$
\left( \begin{array}{ccc}
0&0&0&0 \\ 0&\delta_{11}& \delta_{12}&0 \\ 0&\delta_{21}&\delta_{22}&0 \\
0&0&0&0 \end{array} \right) * \left( \begin{array}{ccc}
w_{22}&w_{21}\\
w_{12}&w_{11} \end{array} \right)  = \left( \begin{array}{ccc}
\nabla a_{11}&\nabla a_{12}&\nabla a_{13} \\ \nabla a_{21}&\nabla a_{22}&\nabla a_{23}\\
\nabla a_{31}&\nabla a_{32}&\nabla a_{33} \end{array} \right)$$

    为了符合梯度计算,我们在误差矩阵周围填充了一圈0,此时我们将卷积核翻转后和反向传播的梯度误差进行卷积,就得到了前一次的梯度误差。这个例子直观的介绍了为什么对含有卷积的式子求导时,卷积核要翻转180度的原因。

    以上就是卷积层的误差反向传播过程。

5. 已知卷积层的$\delta^l$,推导该层的$W,b$的梯度    

    好了,我们现在已经可以递推出每一层的梯度误差$\delta^l$了,对于全连接层,可以按DNN的反向传播算法求该层$W,b$的梯度,而池化层并没有$W,b$,也不用求$W,b$的梯度。只有卷积层的$W,b$需要求出。

    注意到卷积层$z$和$W,b$的关系为:$$z^l = a^{l-1}*W^l +b$$

    因此我们有:$$\frac{\partial J(W,b)}{\partial W^{l}} = \frac{\partial J(W,b)}{\partial z^{l}}\frac{\partial z^{l}}{\partial W^{l}} = \delta^l * rot180( a^{l-1})$$

    由于我们有上一节的基础,大家应该清楚为什么这里求导后$ a^{l-1}$要旋转180度了。

    而对于b,则稍微有些特殊,因为$\delta^l$是三维张量,而$b$只是一个向量,不能像DNN那样直接和$\delta^l$相等。通常的做法是将$\delta^l$的各个子矩阵的项分别求和,得到一个误差向量,即为$b$的梯度:$$\frac{\partial J(W,b)}{\partial b^{l}} = \sum\limits_{u,v}(\delta^l)_{u,v}$$

6. CNN反向传播算法总结

    现在我们总结下CNN的反向传播算法,以最基本的批量梯度下降法为例来描述反向传播算法。

    输入:m个图片样本,CNN模型的层数L和所有隐藏层的类型,对于卷积层,要定义卷积核的大小K,卷积核子矩阵的维度F,填充大小P,步幅S。对于池化层,要定义池化区域大小k和池化标准(MAX或Average),对于全连接层,要定义全连接层的激活函数(输出层除外)和各层的神经元个数。梯度迭代参数迭代步长$\alpha$,最大迭代次数MAX与停止迭代阈值$\epsilon$

    输出:CNN模型各隐藏层与输出层的$W,b$

    1) 初始化各隐藏层与输出层的各$W,b$的值为一个随机值。

     2)for iter to 1 to MAX:

    2-1) for i =1 to m:

      a) 将CNN输入$a^1$设置为$x_i$对应的张量

      b) for $l$=2 to L-1,根据下面3种情况进行前向传播算法计算:

      b-1) 如果当前是全连接层:则有$a^{i,l} = \sigma(z^{i,l}) = \sigma(W^la^{i,l-1} + b^{i,l})$

      b-2) 如果当前是卷积层:则有$a^{i,l} = \sigma(z^{i,l}) = \sigma(W^l*a^{i,l-1} + b^{i,l})$

      b-3) 如果当前是池化层:则有$ a^{i,l}= pool(a^{i,l-1})$, 这里的pool指按照池化区域大小k和池化标准将输入张量缩小的过程。

      c) 对于输出层第L层: $ a^{i,L}= softmax(z^{i,L}) = softmax(W^{i,L}a^{i,L-1} +b^{i,L})$

      c) 通过损失函数计算输出层的$\delta^{i,L}$

      d) for $l$= L to 2, 根据下面3种情况进行进行反向传播算法计算:

      d-1)  如果当前是全连接层:$\delta^{i,l} =  (W^{l+1})^T\delta^{i,l+1}\odot \sigma^{'}(z^{i,l})$

      d-2) 如果当前是卷积层:$\delta^{i,l} = \delta^{i,l+1}*rot180(W^{l+1}) \odot  \sigma^{'}(z^{i,l}) $

      d-3) 如果当前是池化层:$\delta^{i,l} =  upsample(\delta^{i,l+1}) \odot \sigma^{'}(z^{i,l})$

    2-2) for $l$ = 2 to L,根据下面2种情况更新第$l$层的$W^l,b^l$:

      2-2-1) 如果当前是全连接层:$W^l = W^l -\alpha \sum\limits_{i=1}^m \delta^{i,l}(a^{i, l-1})^T $, $b^l = b^l -\alpha \sum\limits_{i=1}^m \delta^{i,l}$

      2-2-2) 如果当前是卷积层,对于每一个卷积核有:$W^l = W^l -\alpha \sum\limits_{i=1}^m \delta^{i,l}* rot180(a^{i, l-1}) $, $b^l = b^l -\alpha \sum\limits_{i=1}^m \sum\limits_{u,v}(\delta^{i,l})_{u,v}$

    2-3) 如果所有$W,b$的变化值都小于停止迭代阈值$\epsilon$,则跳出迭代循环到步骤3。

    3) 输出各隐藏层与输出层的线性关系系数矩阵$W$和偏倚向量$b$。

(欢迎转载,转载请注明出处。欢迎沟通交流: pinard.liu@ericsson.com)

参考资料:

1) Neural Networks and Deep Learning by By Michael Nielsen

2) Deep Learning, book by Ian Goodfellow, Yoshua Bengio, and Aaron Courville

3) UFLDL Tutorial

4)CS231n Convolutional Neural Networks for Visual Recognition, Stanford

卷积神经网络(CNN)反向传播算法的更多相关文章

  1. 神经网络之反向传播算法(BP)公式推导(超详细)

    反向传播算法详细推导 反向传播(英语:Backpropagation,缩写为BP)是"误差反向传播"的简称,是一种与最优化方法(如梯度下降法)结合使用的,用来训练人工神经网络的常见 ...

  2. (3)Deep Learning之神经网络和反向传播算法

    往期回顾 在上一篇文章中,我们已经掌握了机器学习的基本套路,对模型.目标函数.优化算法这些概念有了一定程度的理解,而且已经会训练单个的感知器或者线性单元了.在这篇文章中,我们将把这些单独的单元按照一定 ...

  3. 神经网络(NN)+反向传播算法(Backpropagation/BP)+交叉熵+softmax原理分析

    神经网络如何利用反向传播算法进行参数更新,加入交叉熵和softmax又会如何变化? 其中的数学原理分析:请点击这里.

  4. CNN反向传播算法过程

    主模块 规格数据输入(加载,调格式,归一化) 定义网络结构 设置训练参数 调用初始化模块 调用训练模块 调用测试模块 画图 初始化模块 设置初始化参数(输入通道,输入尺寸) 遍历层(计算尺寸,输入输出 ...

  5. 深度学习之反向传播算法(BP)代码实现

    反向传播算法实战 本文仅仅是反向传播算法的实现,不涉及公式推导,如果对反向传播算法公式推导不熟悉,强烈建议查看另一篇文章神经网络之反向传播算法(BP)公式推导(超详细) 我们将实现一个 4 层的全连接 ...

  6. 卷积神经网络(CNN)前向传播算法

    在卷积神经网络(CNN)模型结构中,我们对CNN的模型结构做了总结,这里我们就在CNN的模型基础上,看看CNN的前向传播算法是什么样子的.重点会和传统的DNN比较讨论. 1. 回顾CNN的结构 在上一 ...

  7. 神经网络反向传播算法&&卷积神经网络

    听一遍课程之后,我并不太明白这个算法的奇妙之处?? 为啥? 神经网络反向传播算法 神经网络的训练依靠反向传播算法,最开始输入层输入特征向量,网络层计算获得输出,输出层发现输出和正确的类号不一样,这时就 ...

  8. 神经网络训练中的Tricks之高效BP(反向传播算法)

    神经网络训练中的Tricks之高效BP(反向传播算法) 神经网络训练中的Tricks之高效BP(反向传播算法) zouxy09@qq.com http://blog.csdn.net/zouxy09 ...

  9. 循环神经网络(RNN)模型与前向反向传播算法

    在前面我们讲到了DNN,以及DNN的特例CNN的模型和前向反向传播算法,这些算法都是前向反馈的,模型的输出和模型本身没有关联关系.今天我们就讨论另一类输出和模型间有反馈的神经网络:循环神经网络(Rec ...

随机推荐

  1. Sigmoid函数

    Sigmoid函数是一个S型函数. Sigmoid函数的数学公式为: 它是常微分方程 的一个解. Sigmoid函数具有如下基本性质: 定义域为 值域为, 为有界函数 函数在定义域内为连续和光滑函数 ...

  2. tomcat 安全文件夹(Java之负基础实战)

    tomcat 解析网站的时候,会寻找一个文件叫  WEB-INF 这些文件外部无法访问

  3. jQuery动画高级用法(上)——详解animation中的.queue()动画队列插队函数

    决定对animate方面做一些总结,希望能给大家一些启发和帮助 从一个实际应用谈起 今天不谈animate().fadeIn().fadeOut().slideUp().show().hide()诸如 ...

  4. 解决mysql 1864 主从错误

     从字面意思看了一下是因为slave_pending_jobs_size_max默认值为16777216(16MB),但是slave接收到的slave_pending_jobs_size_max为 ...

  5. 文本切换器(TextSwitcher)的功能和用法

    TextSwitcher继承了ViewSwitcher,因此它具有与ViewSwitcher相同的特征:可以在切换View组件的同时使用动画效果.与ImageSwitcher相似的是,使用TextSw ...

  6. HTML 5 服务器发送事件、Input 类型、表单元素、表单属性

    HTML5 服务器发送事件(server-sent event)允许网页获得来自服务器的更新. Server-Sent 事件 - 单向消息传递 Server-Sent 事件指的是网页自动获取来自服务器 ...

  7. Canvas rotate- 旋转

    Canvas rotate- 旋转 <!DOCTYPE html> <html lang="en"> <head> <meta chars ...

  8. Bootstrap入门(十八)组件12:徽章与巨幕

    Bootstrap入门(十八)组件12:徽章与巨幕 1.徽章 2.巨幕 1.徽章 给链接.导航等元素嵌套 <span class="badge"> 元素,可以很醒目的展 ...

  9. node源码详解 (一)

    本作品采用知识共享署名 4.0 国际许可协议进行许可.转载保留声明头部与原文链接https://luzeshu.com/blog/nodesource1 本博客同步在https://cnodejs.o ...

  10. POJ1144(割点)

    Network Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 12551   Accepted: 5771 Descript ...