反向传播算法

为什么要使用反向传播

在监督学习中,比如线性回归、逻辑回归等问题中,在训练模型的过程中有很重要的一步就是对输入的权重(theta,又叫 W)不断的更新,以降低 Cost function 的输出值。在之前,我们都是通过是手动计算的方式去计算权重参数的偏导数。

在神经网络中,由于神经元的数目比较多,导致权重参数(theta)也会非常的多,在这样的情况下,手动计算权重参数的偏导数的方式已经不太适用了,并且由于函数的复杂性也很可能会导致计算出错。

那我们该怎么去计算所有权重参数的偏导数呢?

当然是利用我们今天要讲的「反向传播算法」啦!

概念

反向传播是利用链式法则递归计算表达式的梯度的方法。理解反向传播过程及其精妙之处,对于理解、实现、设计和调试神经网络非常关键。

详解

牢记导数的意义:函数变量在某个点周围的极小区域内变化,而导数就是变量变化导致的函数在该方向上的变化率。换句话说,函数关于每个变量的导数指明了整个表达式对于该变量的敏感程度。

使用链式法则计算复合表达式

simple backpropagation example

图中所示的函数非常简单,不能和我们平时遇到的非常庞大的 cost function 相提并论,在这里仅仅是为了方便介绍反向传播算法。

我们需要求的是函数关于 x、y、z 的导数,明眼人一眼就能看出来 x、y、z 的导数,但是我们要用反向传播的方法来计算。

如图所示,从尾部开始。首先我们会先计算 f 对 f 的导数,自己对自己求导,导数当然为 1。紧接着,我们会计算 f 对 z 的导数,很简单,导数是 3。同理 f 对 q 的导数是 -4。

重点来了,接下来我们想要求解 f 对 x 的导数,怎么求?我们先计算 q 对 x 的导数,因为 q = x + y ,所以可以很容易的得到 q 对 x 的导数为 1,然后将 q 对 x 的导数 与 f 对 q 的导数相乘,便得到了 f 对 x 的导数。即: -4 * 1 = -4

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 设置输入值
x = -2; y = 5; z = -4
# 进行前向传播
q = x + y # q becomes 3
f = q * z # f becomes -12
# 进行反向传播:
# 首先回传到 f = q * z
dfdz = q # df/dz = q, 所以关于z的梯度是3
dfdq = z # df/dq = z, 所以关于q的梯度是-4
# 现在回传到q = x + y
dfdx = 1.0 * dfdq # dq/dx = 1. 这里的乘法是因为链式法则
dfdy = 1.0 * dfdq # dq/dy = 1

image

上图的真实值计算线路展示了计算的视觉化过程。前向传播从输入计算到输出(绿色),反向传播从尾部开始,根据链式法则递归地向前计算梯度(显示为红色),一直到网络的输入端。可以认为,梯度是从计算链路中回流。

以上便是对反向传播最简单的一个解释,看完上述内容之后,应该就会有一个大概的印象了:反向传播是利用链式法则递归计算表达式的梯度的方法。

image

链式法则指出,门单元应该将回传的梯度乘以它对其的输入的局部梯度,从而得到整个网络的输出对该门单元的每个输入值的梯度。

反向传播的直观理解

节选一段斯坦福大学 CS231n 课程的笔记

反向传播是一个优美的局部过程。在整个计算线路图中,每个门单元都会得到一些输入并立即计算两个东西:1. 这个门的输出值,和2.其输出值关于输入值的局部梯度。门单元完成这两件事是完全独立的,它不需要知道计算线路中的其他细节。然而,一旦前向传播完毕,在反向传播的过程中,门单元门将最终获得整个网络的最终输出值在自己的输出值上的梯度。链式法则指出,门单元应该将回传的梯度乘以它对其的输入的局部梯度,从而得到整个网络的输出对该门单元的每个输入值的梯度。

这里对于每个输入的乘法操作是基于链式法则的。该操作让一个相对独立的门单元变成复杂计算线路中不可或缺的一部分,这个复杂计算线路可以是神经网络等。

下面通过例子来对这一过程进行理解。加法门收到了输入[-2, 5],计算输出是3。既然这个门是加法操作,那么对于两个输入的局部梯度都是+1。网络的其余部分计算出最终值为-12。在反向传播时将递归地使用链式法则,算到加法门(是乘法门的输入)的时候,知道加法门的输出的梯度是-4。如果网络如果想要输出值更高,那么可以认为它会想要加法门的输出更小一点(因为负号),而且还有一个4的倍数。继续递归并对梯度使用链式法则,加法门拿到梯度,然后把这个梯度分别乘到每个输入值的局部梯度(就是让-4乘以x和y的局部梯度,x和y的局部梯度都是1,所以最终都是-4)。可以看到得到了想要的效果:如果x,y减小(它们的梯度为负),那么加法门的输出值减小,这会让乘法门的输出值增大。

因此,反向传播可以看做是门单元之间在通过梯度信号相互通信,只要让它们的输入沿着梯度方向变化,无论它们自己的输出值在何种程度上升或降低,都是为了让整个网络的输出值更高。

扩展

下面给一些稍微复杂的例子,有兴趣的话可以自己使用反向传播动手计算梯度,对加深理解非常有帮助。

  • 带 sigmoid 函数的例子

image

image

  • 吴恩达教授机器学习课程中神经网络的例子

image

全文完

感谢阅读