梯度与反向传播
1.对于一个二元函数f(x, y),有 \(\nabla f = [\frac{\partial f}{\partial x} , \frac{\partial f}{\partial y}]\) 因此可知,梯度是一个向量而不是一个标量
2.利用链式法则解释何为反向传播:
f(x,y,z)=(x+y)z, q = x+y。如果我们对f求x的偏导。实际为\(\frac{\partial f}{\partial x} = \frac{\partial f}{\partial q} \frac{\partial q}{\partial x}\)。此时,我们使用代码来复现这一过程,借此来讲反向传播:
# 设置输入值
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
我们通过上述代码得到了梯度\([\frac{\partial f}{\partial x} , \frac{\partial f}{\partial y}, \frac{\partial f}{\partial z}]\)我们的计算过程如下图所示:
前向传播从输入计算到输出(绿色),反向传播从尾部开始,根据链式法则递归地向前计算梯度(显示为红色。比如说我想得到f关于z的反向传播,就对z求梯度),一直到网络的输入端。可以认为,梯度是从计算链路中回流。
下面举一个如何利用这种思想求一个复杂函数梯度的例子:
\(f = \frac{1}{1 + exp(-(w_{0}x_{0} + w_{1}x_{1} + w{2}))}\)
在这里我们使用sigmod函数求导的思想
\(\sigma(x) = \frac{1}{1 + exp(-x)}\)
我们通过以下的代码求出对x和w的梯度:
w = [2,-3,-3] # 假设一些随机数据和权重
x = [-1, -2]
# 前向传播
dot = w[0]*x[0] + w[1]*x[1] + w[2]
f = 1.0 / (1 + math.exp(-dot)) # sigmoid函数
# 对神经元反向传播
ddot = (1 - f) * f # 点积变量的梯度, 使用sigmoid函数求导
dx = [w[0] * ddot, w[1] * ddot] # 回传到x
dw = [x[0] * ddot, x[1] * ddot, 1.0 * ddot] # 回传到w
# 完成!得到输入的梯度
上述代码先完成了对dot=\(w_{0}x_{0} + w_{1}x_{1} + w{2}\)的求导,然后再令dot对x和w的分量求导