摘要
计算图应用非常广,例如,内存计算框架Spark的有向无环图(DAG),Neo4J图数据库、深度学习中的神经网络图,以及TensorBoard中的可视化图,都是计算图的应用场景。本文所讲的也是计算图的一个应用场景:计算神经网络的梯度,包括计算激活函数和典型神经结构(也叫卷积核)的梯度:
1、用计算图分解和解决 激活函数 的导数的计算
2、用计算图分解和解决 神经网络 在反向传播路径上梯度的计算。
回顾上一篇 利用BP神经网络逼近函数(Python)
引言
神经网络的学习过程就是优化目标函数,目标函数的优化需要不断的随着迭代步骤更新神经网络各层的权重和偏置,而更新的一个重要依据就是要计算反向传播路径上的各层的梯度,当神经网络层数很多时,计算和传递就更复杂。这是神经网络的一个核心问题,所以一种什么方式来理解和计算梯度就显得比较重要。
要正确理解和计算反向传播法上梯度,有两种方法:一种是基于数学式,常见于网上洋洋洒洒的公式推导;另一种是基于计算图(computational graph)的。 关于BP反向传播梯度推导,在网上和书上,笔者看了数次,但是当时觉得懂了,但是过了不久印象几乎消失殆尽,大概是东方人擅长具象思维,西方人擅长逻辑思维的缘故吧。不知读者是否有这样的感觉。本文讲述后者,计算图作为一种解决问题的方式,有着形象直观,易于理解和掌握的优势。关于什么是梯度参见我的文章 神经网络的数学基础:张量和梯度,
目录
- 什么是计算图
- 复合函数的计算图式求导
- 神经网络反向(BP)求导
- 小结
首先讲述如何拆解复合函数求导,然后讲述如何在神经网络中传导,然后,再结合实际的代码加深理解,相信大家看完会有一定会有种“原来如此!”的感觉。
什么是计算图
首先定义计算图的概念,计算图是有向图,神经网络是其特殊形式, 其中节点对应于操作或变量。变量可以将其值提供给操作,操作可以将其输出提供给其他操作。这样,图中的每个节点都定义了变量的函数。进入节点并从节点出来的值称为张量(多维数组的另一别称),它包含标量,向量和矩阵以及更高等级的张量。
计算图将计算过程用图形表示出来。这里说的图形是数据结构图,通过多个节点和边表示(连接节点的直线称为“边”)
“从左向右进行计算”是一种正方向上的传播,简称为正向传播(forward propagation)。正向传播是从计算图出发点到结束点的传播。既然有正向传播这个名称,当然也可以考虑反向(从图上看的话,就是从右向左)的传播。实际上,这种传播称为反向传播(backward propagation)。传播的是什么?传播的是线上的张量!
复合函数的计算图式求导
复合函数是由多个函数构成的函数。比如,函数 z = ( x + y ) 2 z = (x + y)^2 z=(x+y)2 是由下面两个函数式子组成的:
z = t 2 z = t^2 z=t2
t = x + y t = x + y t=x+y
复合函数的求导,遵循链式法则,规则是这样:如果某个函数是复合函数,则其导数可以用构成复合函数的各个函数的导数的乘积表示,例如上面公式对x的导数就可以由以下公式推导得出:
∂ z ∂ x = ∂ z ∂ t ∂ t ∂ x = 2 t . 1 = 2 ( x + y ) \frac {\partial z}{\partial x}=\frac {\partial z}{\partial t}\frac {\partial t}{\partial x}=2t.1=2(x+y) ∂x∂z=∂t∂z∂x∂t=2t.1=2(x+y)
可见,把复合函数分解为几个小的子函数,通过求子函数的导数,然后把它们乘起来,这样大大降低了求导数的难度,而且理解起来也很容易,复合函数求导,在神经网络中用的多场合是激活函数和损失函数,这里我们以 激活函数 s i g m o i d sigmoid sigmoid 为例说明, s i g m o i d sigmoid sigmoid 函数由以下公式表示:
y = 1 1 + e x p ( − x ) y=\frac {1}{1+exp(-x)} y=1+exp(−x)1
按照函数内进行的操作单元分解后,计算图表示如下:
我们可以把 x x <