引言
主要介绍一些关于backpropagation(反向传播)的知识,反向传播主要就是利用chain rule(链式法则)计算关于weights的梯度,通过梯度计算的结果对网络进行梯度下降的优化。这对于我们设计和debug神经网络都很有用处。
值得注意的是,通常情况下我们计算对于W的梯度以便根据梯度下降进行参数更新,但是在一些特殊情况下,我们也有可能计算关于输入x的梯度,目的是解释和可视化神经网络的过程。
概念
当我们使用前馈神经网络接收输入x并产生输出y时,信息通过网络向前流动。输入x提供初始信息,然后传播到每一层的隐藏单元,最后产生输出y。这叫做 前向传播(forward prapagation)。而在训练过程中,前向传播可以持续向前知道计算出代价函数。反向传播算法则允许来自代价函数的信息通过网络向后流动,以便于计算梯度。
简单的解释和举例
实际上,每个变量的导数反映了整个表达式对这个变量的变化的敏感程度。其定义如下:
比较常见的有以下3种函数。
以上这些是针对简单的情况,针对复杂的复合函数的情况,往往需要使用链式法则来求解梯度。
一种比较直观的理解是:反向传播可以看做一组彼此之间通过梯度信号通信的门,每个门可以选择让通过自己的信号增加或者减小,并且可以决定增加或者减小的幅度。最后的目的是通过改变输入,经过这一系列门之后使得总的输出最大或者最小。
模块化操作
在实际计算反向传播的时候,我们可以通过一些模块化的操作使得计算和理解都更为简便直观。
如下面所示的一个例子:
通过将此函数分解为一系列函数的复合:
最后的一个计算过程如下:
可以看出这个流程还是比较复杂,但是通过将其中的一个sigmoid函数模块化之后,我们会得到更加简明的结果。
最后编程实现如下:
实践中的一些技巧
1、在实践中,我们需要根据实际情况对整个函数进行拆分,分成便于计算梯度的函数的一个复合。
2、为了反向计算方便,通常在正向计算的时候需要保存一些中间结果,便于反向计算梯度的时候使用它们。
3、前向计算需要使用x,y变量多次,在反向传播的时候应该用+=而不是=来累加结果。
扩展到矢量计算梯度
对矢量计算梯度的方法和上面所提及的并无二致,但是在处理时可能需要加入转置运算以便维数匹配。
计算矩阵相乘的梯度
下面这个例子里面就是根据维数匹配的原则对表达式加入一些转置的操作。
而对于一些一时难以看出梯度表达式的情况,可以利用实际的比较小的矩阵手动演算,根据结果推理出合适的表达式。
参考
1、cs231n 2017 lecture4 slides
2、cs231n 2017 backpropagation notes