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. Android一些小技巧

    1:设置选中图片的背景颜色 this.gridviewToolbar = (GridView) super.findViewById(R.id.gridviewbar); this.gridviewT ...

  2. 【C#】C#创建Windows Service服务

    目录结构: contents structure [+] 创建Windows服务 配置 安装Windows服务 在Visual Studio中调试 常见问题 最近写了一个TCP连接的程序,由于这种通信 ...

  3. log4j(五)——如何控制不同目的地的日志输出?

    一:测试环境与log4j(一)——为什么要使用log4j?一样,这里不再重述 二:老规矩,先来个栗子,然后再聊聊感受 import org.apache.log4j.*; import java.io ...

  4. numpy 切片

    numpy 中的切片与数组中的切片类似. 数组 [ 起始:终止:步长, 起始:终止:步长, ... ] 所有的切片操作(无论是步长为+的正序,还是步长为 - 的逆序)都是开始位置包含,结束位置不包含( ...

  5. 在JSP中如何使用JavaBean

    在JSP中使用JavaBean以后,可以实现HTML代码和Java代码的分离,是JSp更易于开发和维护.因此JavaBean成了JSP程序员必备的利器.虽然javaBean是java类,但是它也有自己 ...

  6. CentOS 7.3 系统安装配置图解教程

    一.安装CentOS 7.3 CentOS 7.x系列只有64位系统,没有32位.生产服务器建议安装CentOS-7-x86_64-Minimal-1611.iso版本 成功引导系统后,会出现下面的界 ...

  7. Python 文件 next() 方法

    描述 Python 3 中的 文件 对象不支持 next() 方法. Python 3 的内置函数 next() 通过迭代器调用 __next__() 方法返回下一项. 在循环中,next()方法会在 ...

  8. android中碰撞屏幕边界反弹问题

    其实碰撞问题只是涉及到一点小算法而已,但在实际应用,尤其游戏中有可能会遇到,下面给出一个小示例,代码如下: MainActivity: package com.lovo; import android ...

  9. pthread编译时报错的解决方法

    最近在学习POSIX thread编程,今天编译一个程序报如下错误: /tmp/ccXH8mJy.o:在函数‘main’中:deadlock.c:(.text+0xbb):对‘pthread_crea ...

  10. [转]同步对象Event的用法

    同步对象Event的用法  首先介绍CreateEvent是创建windows事件的意思,作用主要用在判断线程退出,线程锁定方面.  CreateEvent函数功能描述:创建或打开一个命名的或无名的事 ...