神经网络中用反向传播求偏导数的思想就相当于复合函数求偏导。
从头说起,在学生时代我们要求下面式子中,函数
e
(
a
,
b
)
e(a,b)
e(a,b)对a和b的偏导数:
e
=
(
a
+
b
)
∗
(
b
+
1
)
e=(a+b)*(b+1)
e=(a+b)∗(b+1)
∂ e ∂ a = ? \frac{\partial e}{\partial a}=? ∂a∂e=?
∂ e ∂ b = ? \frac{\partial e}{\partial b}=? ∂b∂e=?
传统的求偏导方法就是用解析式直接求偏导即可。
但如果随着函数复合的层数增多,对应的就是神经网络的层数增多,总体的解析式也会变得极其复杂,这个时候想一步求出偏导数是不可能的,只能通过反向传播法来求偏导数。
反向传播的核心就是计算图,其数学原理就是链式法则求偏导数
e = ( a + b ) ∗ ( b + 1 ) e=(a+b)*(b+1) e=(a+b)∗(b+1)的计算图如下表示,对应的就相当于神经网络图,每个节点都是原式中的一个小小的原子操作,也就是加减乘除等操作,对应的就相当于神经网络中每个结点的计算:
从结点a和结点b开始,顺着箭头计算,直到算出结果e,这就是前馈计算的过程,也就是前向传播计算。
其实,我们在前馈计算的过程中,完全可以计算每个中间结点对上一个节点的偏导数。
比如在前馈计算c=a+b时,我们可以顺道算出 ∂ c ∂ a \frac{\partial c}{\partial a} ∂a∂c和 ∂ c ∂ b \frac{\partial c}{\partial b} ∂b∂c;
在计算d=b+1时,逆着箭头计算出 ∂ d ∂ b \frac{\partial d}{\partial b} ∂b∂d( ∂ d ∂ 1 = 0 \frac{\partial d}{\partial 1}=0 ∂1∂d=0,所以可以省略);
在计算e=c*d时,逆着指向它的两个箭头计算出 ∂ e ∂ c \frac{\partial e}{\partial c} ∂c∂e和 ∂ e ∂ d \frac{\partial e}{\partial d} ∂d∂e。
最后,根据数学上的链式法则求偏导:
链式法则:路径上的偏导数做乘法,不同路径上的做加法。比如,从a到e的路径只有一条,其路径上的所有偏导数做乘法;从b到e上的路径有两条,每条路径上的偏导数做乘法,最后不同路径的结果做加法。如下所示:
∂ e ∂ a = ∂ e ∂ c ⋅ ∂ c ∂ a \frac{\partial e}{\partial a}=\frac{\partial e}{\partial c}·\frac{\partial c}{\partial a} ∂a∂e=∂c∂e⋅∂a∂c
∂ e ∂ b = ∂ e ∂ c ⋅ ∂ c ∂ b + ∂ e ∂ d ⋅ ∂ d ∂ b \frac{\partial e}{\partial b}=\frac{\partial e}{\partial c}·\frac{\partial c}{\partial b}+\frac{\partial e}{\partial d}·\frac{\partial d}{\partial b} ∂b∂e=∂c∂e⋅∂b∂c+∂d∂e⋅∂b∂d
至此,仅需在前馈计算的过程中,我们就能顺道求出复合函数e(a,b)的偏导数。
后续就是做函数优化等等了。