前向求导与反向求导
前向求导:一个输入对所有结点的影响
反向求导:所有结点对一个输出的影响
前向求导
y
1
=
2
x
1
+
x
2
y
2
=
3
x
3
z
=
2
y
1
+
y
2
y_1=2x_1+x_2\\ y_2 = 3x_3\\ z=2y_1+y_2
y1=2x1+x2y2=3x3z=2y1+y2
1 前向求导求z对x1的导数
2 前向求导求z对x2的导数
上述两次前向求导才能求得z对x1,x2的导数,若希望一次求得z对x1,x2的导数,需要反向求导。
反向求导
从z开始反向求导(所有结点对一个输出的影响):
总结
多次前向求导才能求得z对x1,x2,x3的导数;一次反向求导即可求得z对x1,x2,x3的导数
求导实现
上面手工求得z对x1,x2,x3的导数:4,2,3
x1 = torch.tensor([1.0,2.0,3.0], requires_grad=True)
x2 = torch.tensor([1.0,2.0,3.0], requires_grad=True)
x3 = torch.tensor([1.0,2.0,3.0], requires_grad=True)
y1=2*x1+x2
y2=3*x3
z=2*y1+y2
由于输入的x1,x2,x3不是标量,不是一个数,是向量,所以可以按如下2种方式求导。
求导方式1:
# 输入x1等 是3维向量,所以输出z是3维向量->因此需要给一个初始梯度
z.backward(torch.tensor([1.0,1.0,1.0]))
x1.grad, x2.grad, x3.grad
(tensor([4., 4., 4.]), tensor([2., 2., 2.]), tensor([3., 3., 3.]))
求导方式2:
z.sum().backward()
x1.grad,x2.grad,x3.grad
(tensor([4., 4., 4.]), tensor([2., 2., 2.]), tensor([3., 3., 3.]))