1. CNN卷积网络-初识

2. CNN卷积网络-前向传播算法

3. CNN卷积网络-反向更新

1. 前言

如果读者详细的了解了DNN神经网络的反向更新,那对我们今天的学习会有很大的帮助。我们的CNN卷机网络中有3种网络结构。1. 卷积层,2.池化层,3.全连接层。全连接层的反向传播的方式和DNN的反向传播的方式是一样的,因为DNN的所有层都是全连接的结构。卷机层和池化层下文会继续讲解。

2. 全连接反向更新

这里先回顾下DNN的反向更新,我们进行反向更新主要是计算每一层的\(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}
\]
我们现在的目标只要计算每层的\(\delta\),就可以算出每层的\(W,b\)的梯度。最后一层的\(\delta\)很好计算,即

\[
\delta^L = \frac{\partial J(W,b,x,y)}{\partial z^L} = (a^L-y)\odot \sigma^{'}(z^L)
\]

如果我们能够通过后一层的\(\delta\)推算出前一层的\(\delta\)那就把问题完全解决了。

\[
\delta^{l} = \delta^{l+1}\frac{\partial z^{l+1}}{\partial z^{l}} = (W^{l+1})^T\delta^{l+1}\odot \sigma^{'}(z^l)
\]
以上就是全连接层的反向更新的过程。需要明确的一点是以上的推到是有一个前提的:

\[
a^l = \sigma(z^l) = \sigma(W^la^{l-1} + b^l)
\]
这个是前向传播的公式。所以卷积层和池化层的前向传播的公式不一样,那在对反向更新中的参数求导的过程也会变化。

3. 卷积层的反向传播

首先我们看下卷积层的前向传播公式:
\[
a^l = \sigma(z^l) = \sigma(a^{l-1}*W^l + b)
\]
其中的\(W^l\)是不是一个矩阵,矩阵的定义是2维的,而我们的\(W^l\)是一个张量,可以理解为多个矩阵的组合,或者理解为矩阵的数组。

由于前向传播公式的改变,卷积层求每层的\(\delta^{l}\)递推方法肯定有所不同。又由于\(W\)用的运算是卷积,那么计算卷积核的\(W,b\)的方式也不同。

3.1 求\(\delta^l\)的递推公式

我们先求\(\delta^l\),它的递推公式还是DNN中的那个。

\[
\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}}\;\;\;\;\;\;(1)
\]
因此和DNN一样,计算\(\delta^l\)的任务就转化成了计算\(\frac{\partial z^{l+1}}{\partial z^{l}}\),那卷积层中的\(\frac{\partial z^{l+1}}{\partial z^{l}}\)怎么计算呢?

\[
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中这里只是矩阵的转置。

3.2 已知\(\delta^l\),求\(W,b\)的梯度

卷积层\(z\)和\(W,b\)的关系为:

\[
z^l = a^{l-1}*W^l +b
\]
则有带入(1)中得到:

\[
\frac{\partial J(W,b)}{\partial W^{l}} = \frac{\partial J(W,b)}{\partial z^{l}}\frac{\partial z^{l}}{\partial W^{l}} =a^{l-1} *\delta^l
\]
其中的运算符\(*\)和前向传播公式是一样的,是卷积的过程。可以把张量展开。

\[
\frac{\partial J(W,b)}{\partial W^{l}} =\left( \begin{array}{ccc} a^{l-1}_{11}&a^{l-1}_{12}&a^{l-1}_{13}&a^{l-1}_{14} \\ a^{l-1}_{21}&a^{l-1}_{22}&a^{l-1}_{23}&a^{l-1}_{24} \\ a^{l-1}_{31}&a^{l-1}_{32}&a^{l-1}_{33}&a^{l-1}_{34} \\ a^{l-1}_{41}&a^{l-1}_{42}&a^{l-1}_{43}&a^{l-1}_{44} \end{array} \right) * \left( \begin{array}{ccc} \delta^{l}_{11}& \delta^{l}_{12} \\ \delta^{l}_{21}&\delta^{l}_{22} \end{array} \right)
\]
把\(\delta^l\)当作卷积核,去扫描\(a^{l-1}\)的张量,就得出了\(\frac{\partial J(W,b)}{\partial W^{l}}\)的梯度。

而对于\(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}
\]

4. 池化层的反向更新

在前向传播算法时,池化层一般我们会用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^l_k\)做还原,即变成

\[
\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}}\)的值:

\[
\frac{\partial J(W,b)}{\partial a_k^{l-1}}= upsample(\delta_k^l)
\]
所以\(\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})
\]

5. 总结

以上就是CNN卷积网络的反向更新的过程,CNN卷积网络的更新和DNN还是有很大的不同,需要读者仔细思考这个过程,最好找个简单的例子能够手推一下整个过程,能够对整个过程有更深刻的理解。

3. CNN卷积网络-反向更新的更多相关文章

  1. 2. CNN卷积网络-前向传播算法

    1. CNN卷积网络-初识 2. CNN卷积网络-前向传播算法 3. CNN卷积网络-反向更新 1. 前言 我们已经了解了CNN的结构,CNN主要结构有输入层,一些卷积层和池化层,后面是DNN全连接层 ...

  2. 1. CNN卷积网络-初识

    1. CNN卷积网络-初识 2. CNN卷积网络-前向传播算法 3. CNN卷积网络-反向更新 1. 前言 卷积神经网络是一种特殊的深层的神经网络模型,它的特殊性体现在两个方面, 它的神经元间的连接是 ...

  3. Deeplearning 两层cnn卷积网络详解

    https://blog.csdn.net/u013203733/article/details/79074452 转载地址: https://www.cnblogs.com/sunshineatno ...

  4. 用keras作CNN卷积网络书本分类(书本、非书本)

    本文介绍如何使用keras作图片分类(2分类与多分类,其实就一个参数的区别...呵呵) 先来看看解决的问题:从一堆图片中分出是不是书本,也就是最终给图片标签上:“书本“.“非书本”,简单吧. 先来看看 ...

  5. 基于孪生卷积网络(Siamese CNN)和短时约束度量联合学习的tracklet association方法

    基于孪生卷积网络(Siamese CNN)和短时约束度量联合学习的tracklet association方法 Siamese CNN Temporally Constrained Metrics T ...

  6. CNN卷积神经网络_深度残差网络 ResNet——解决神经网络过深反而引起误差增加的根本问题,Highway NetWork 则允许保留一定比例的原始输入 x。(这种思想在inception模型也有,例如卷积是concat并行,而不是串行)这样前面一层的信息,有一定比例可以不经过矩阵乘法和非线性变换,直接传输到下一层,仿佛一条信息高速公路,因此得名Highway Network

    from:https://blog.csdn.net/diamonjoy_zone/article/details/70904212 环境:Win8.1 TensorFlow1.0.1 软件:Anac ...

  7. 机器学习-计算机视觉和卷积网络CNN

    概述 对于计算机视觉的应用现在是非常广泛的,但是它背后的原理其实非常简单,就是将每一个像素的值pixel输入到一个DNN中,然后让这个神经网络去学习这个模型,最后去应用这个模型就可以了.听起来是不是很 ...

  8. PRML读书会第五章 Neural Networks(神经网络、BP误差后向传播链式求导法则、正则化、卷积网络)

    主讲人 网神 (新浪微博:@豆角茄子麻酱凉面) 网神(66707180) 18:55:06 那我们开始了啊,前面第3,4章讲了回归和分类问题,他们应用的主要限制是维度灾难问题.今天的第5章神经网络的内 ...

  9. Deep Learning论文笔记之(四)CNN卷积神经网络推导和实现(转)

    Deep Learning论文笔记之(四)CNN卷积神经网络推导和实现 zouxy09@qq.com http://blog.csdn.net/zouxy09          自己平时看了一些论文, ...

随机推荐

  1. 开源项目mark

    1. Apache的开源软件列表 http://www.oschina.net/project/apache 2. Java开源Apache项目 http://www.open-open.com/56 ...

  2. golang学习笔记 ----读写文件

    使用io/ioutil进行读写文件 ioutil包 其中提到了两个方法: func ReadFile func ReadFile(filename string) ([]byte, error) Re ...

  3. DrawItem

    原文链接: http://blog.csdn.net/jiftlixu/article/details/4893505 今天从CButton派生了一个类CUIButton,主要用于自绘,按照基本的流程 ...

  4. Java使用reids,以及redis与shiro集成

    什么是redis:redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(so ...

  5. (面试)写出下面switch语句的输出结果

    (1) public static void main(String[] as) { int a = 0;  switch (a)  { case 1:   System.out.println(&q ...

  6. mysql存储过程批量向表插入数据

    业务需要,往某个表中批量插入数据,使用存储过程插入 首先,要建立一张mysql表,表明为phone_number, 三个字段,id 自增,number 就是要插入的表格,is_used 表示十分已经使 ...

  7. java打印条形码Code128C

    生成编码类型为Code128C的条形码的javaCODE: package test; import java.awt.Color; import java.awt.Graphics; import ...

  8. python 并发编程(socketserver)

    下面的例子是简单的ssh 登录,其实也就是客户端把指令发送给服务器.服务器把结果返还给客户端,客户端再在终端展现 服务端代码: #Author:BigBao #Date:2018/7/18 # 我们之 ...

  9. HAproxy通过X-Forwarded-For 获取代理的上一层用户真实IP地址

    现在有一个场景就是我们的haproxy作为反向代理,但是我们接了一个抗DDoS设备.所以现在haproxy记录的IP都是抗DDoS设备的IP地址,获取不到用户的真实IP 这样,我们在haproxy 上 ...

  10. 两table水平滚动条级联滚动(同步滚动)。 table1放标题,table2放内容。

    //table1=head和table2=body水平滚动条级联滚动 $(document).ready(function () { $("#bodyPanel").scroll( ...