简单粗暴理解方向传播算法

说明

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

背景

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

在Python中使用反向传播

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

反向传播算法可视化

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

一些其他的资源

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

总览

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

先走一遍前向传播

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

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

下面我们计算的总净输入

简单粗暴理解方向传播算法

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

简单粗暴理解方向传播算法

对于执行同样的过程:

简单粗暴理解方向传播算法

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

简单粗暴理解方向传播算法

并且对执行同样的过程:

计算总误差

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

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

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

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

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

走一遍反向传播

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

输出层

看一下,我们想知道的改变是怎样影响总输出值的,也就是。 
通过应用我们熟知的链式法则,有:

简单粗暴理解方向传播算法

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

简单粗暴理解方向传播算法

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

简单粗暴理解方向传播算法

有时被表达为

当我们取总误差相对于的偏导时,将会为0,因为不会影响它。

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

简单粗暴理解方向传播算法

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

简单粗暴理解方向传播算法

把它们组织起来:

简单粗暴理解方向传播算法

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

另外,我们可以让写成,也就是。我们可以用这个重写上面的计算式:

因此:

一些资料抽象出了负号:

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

简单粗暴理解方向传播算法

一些资料用(alpha)来表示学习效率,有一些资料用(eta)来表示,还有一些用(epsilon).

我们可以重复这个过程得到的新权重:

简单粗暴理解方向传播算法

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

隐藏层

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

可视化如下:

简单粗暴理解方向传播算法

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

简单粗暴理解方向传播算法

以 的计算开始:

简单粗暴理解方向传播算法

我们可以用之前计算出的值来计算

简单粗暴理解方向传播算法

等于:

简单粗暴理解方向传播算法

插进去:

简单粗暴理解方向传播算法

接下来对执行同样的过程:

因此:

简单粗暴理解方向传播算法

既然我们已经算出了, 接下来我们需要计算出,接下来再对每一个权重计算:

简单粗暴理解方向传播算法

我们再计算对的净输入相对于的偏导,就像之前我们对输出节点做的那样:

简单粗暴理解方向传播算法

整合在一起:

简单粗暴理解方向传播算法

也能把上面写作:

现在我们就可以更新:

简单粗暴理解方向传播算法

重复这个过程:

简单粗暴理解方向传播算法

最终,我们已经将所有的权重更新了一遍!当我们一开始喂给神经网络初始的输入0.05和0.1之后,神经网络的误差是0.298371109。在第一遍反向传播之后,总误差将为了0.291027924。误差也许看起来没有减少地那么大,但是在重复这个过程10000次之后,比如说,这个误差将会跌到0.000035085。在这个时候,我们的0.05、0.1的输入,在两个输出节点上将会产生 0.015912196 (对比 0.01 的目标值) 和 0.984065734 (对比 0.99 的目标值)。


转载自:http://blog.****.net/BlockheadLS/article/details/54293714