反向传播

好久不见. 提交于 2019-12-23 19:50:13

说明

学习深度学习的过程中,遇到了一个用例子讲解反向传播算法的博文,简单粗暴容易理解,很适合我这种小白,所以打算翻译一下分享,英文水平有限,翻译不对的地方请告知。原文地址在这。下面是译文。

背景

反向传播在神经网络的训练中是一种经常被用到的算法。关于反向传播算法网上有很多讲解,但是很少有用真实的数字为大家举例子来解释的。在本篇博文中,我将努力用一个具体的例子来解释反向传播是怎样工作的,为了确定自己理解的是否正确,大家可以先按照自己的理解算一下。
如果这篇博文吸引到了你,你可以注册我的时事通讯,在里面会张贴一些我正在研究的人工智能相关的博文。

在Python中使用反向传播

你也可以用我写的Python脚本玩一玩,程序已经实现了反向传播算法。

反向传播算法可视化

对于展示一个神经网络训练的交互式可视化,大家可以来我的神经网络可视化看一下。

一些其他的资源

如果你觉得这个教程对你是有用的且想继续学习关于神经网络的知识和它们的应用,我强烈推荐Adrian Rosebrock的教程,Getting Started with Deep Learning and Python.

总览

这个教程,我们打算用两个输入节点、两个隐藏节点和两个输出节点。另外,输出节点和隐藏节点将会包含一个偏置。(这个地方,我感觉应该是输入节点和输出节点,但是还是按照原文翻译了。)
下面是一个基本的架构:
这里写图片描述
为了有些数可以算,下面标注了初始化权重、偏置量和训练集的输入输出:
这里写图片描述
反向传播算法的目标是优化权重,使神经网络能够学习到怎样正确地在任意的输入输出之间映射。
教程的其他部分都会围绕一个单一样本进行,给定的输入时0.05和0.10,我们想让这个神经网络能够分别对应输出0.01和0.99。

先走一遍前向传播

一开始,先让我们看一下在当前给定值的情况下神经网络预测的怎么样。所以我们先把输入数据喂给神经网络。
我们每个隐藏层节点的总净输入,用一个激活函数(这里使用的逻辑回归)压缩这个总净输入,然后对输出节点重复这个过程。

总净出入也被称为净输入,参考了某些资料

下面我们计算h1h1的总净输入

这里写图片描述

然后我们再用逻辑回归函数去获得输出h1h1的输出:

这里写图片描述

对于h2h2执行同样的过程:

这里写图片描述

我们将会对输出层的节点重复这个过程,用隐藏层的输出作为输入。
下面是这个输出o1o1:

这里写图片描述

并且对o2o2执行同样的过程:

outo2=0.772928465outo2=0.772928465

计算总误差

我们现在可以用平方误差函数来计算每个输出节点的误差,并且把它们加起来得到总误差。

Etotal=12(targetoutput)2Etotal=∑12(target−output)2

一些资料把目标值也叫作理想值,把输出值叫做实际值。

比如说,o1o1的目标输出是0.01,但是神经网络的输出是0.75136507,因此误差是:

Eo1=12(targeto1outo1)2=12(0.010.75136507)2=0.274811083Eo1=12(targeto1−outo1)2=12(0.01−0.75136507)2=0.274811083

o2o2重复这个过程(记住目标值为0.99),

Eo2=0.023560026Eo2=0.023560026

整个神经网络的总误差是这些误差的和:

Etotal=Eo1+Eo2=0.274811083+0.023560026=0.298371109Etotal=Eo1+Eo2=0.274811083+0.023560026=0.298371109

走一遍反向传播

反向传播算法的目标是更新神经网络中的每一个权重,以便得到实际输出和目标输出更接近,因此要最小化输出节点和整个网络的误差。

输出层

看一下w5w5
通过应用我们熟知的链式法则,有:

这里写图片描述

可视化我们正在做的工作:

这里写图片描述

我们需要计算出这个方程式的每块。
首先,总误差相对于输出的梯度是多少呢?

这里写图片描述

(targetout)−(target−out)

当我们取总误差相对于outo1outo1不会影响它。

接下来,输出o1o1相对于总净输入的偏导是多少呢?
逻辑回归的偏导是输出乘以1减去输出:

这里写图片描述

最后,总净输入相对于w5w5的偏导是多少呢?

这里写图片描述

把它们组织起来:

这里写图片描述

你会经常看到以delta法则组织计算的式子

Etotalw5=(tageto1outo1)outo1(1outo1)outh1∂Etotal∂w5=−(tageto1−outo1)∗outo1∗(1−outo1)∗outh1

另外,我们可以让Etotalouto1outo1neto1∂Etotal∂outo1∗∂outo1∂neto1。我们可以用这个重写上面的计算式:

δo1=Etotalouto1outo1neto1=Etotalneto1δo1=∂Etotal∂outo1∗∂outo1∂neto1=∂Etotal∂neto1

δo1=(tageto1outo1)outo1(1outo1)δo1=−(tageto1−outo1)∗outo1∗(1−outo1)

因此:

Etotalw5=δo1outh1∂Etotal∂w5=δo1outh1

一些资料抽象出了负号:

Etotalw5=δo1outh1∂Etotal∂w5=−δo1outh1

为了减少总误差,我们用当前的权重值减去这个值(可以乘以学习效率,eta,在这里我们设为0.5):

这里写图片描述

一些资料用αα(epsilon).

我们可以重复这个过程得到w6,w7,w8w6,w7,w8的新权重:

这里写图片描述

我们在神经网络中实际执行更新的操作是在隐藏层中所有的权重都有更新的动作之后(也就是说,在下面的反向传播过程中,我们使用的是开始的权重,而不是更新后的权重)。此处翻译不确定!

隐藏层

接下来,我们将会计算w1,w2,w3,w4w1,w2,w3,w4的新值,继续完成这个后向传播算法。
看一下大图,这里面有我们要计算的:

Etotalw1=Etotalouth1outh1neth1neth1w1∂Etotal∂w1=∂Etotal∂outh1∗∂outh1∂neth1∗∂neth1∂w1

可视化如下:

这里写图片描述

我们将会用一个相似的过程来计算,就像对输出层做的那样,但是也会有一些不同, 那就是每个隐藏节点的输出都会对多个输出神经元和误差有影响。我们知道outh1outh1需要被考虑进去。

这里写图片描述

Etotalouth1∂Etotal∂outh1的计算开始:

这里写图片描述

我们可以用之前计算出的值来计算Eo1neto1∂Eo1∂neto1

这里写图片描述

neto1outh1∂neto1∂outh1:

这里写图片描述

插进去:

这里写图片描述

接下来对Eo2outh1∂Eo2∂outh1执行同样的过程:

Eo2outh1=0.019049119∂Eo2∂outh1=−0.019049119

因此:

这里写图片描述

既然我们已经算出了Etotalouth1∂Etotal∂outh1,接下来再对每一个权重计算neth1w

说明

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!