反向传播简单例子:
import torch
a = torch.tensor([1.,2.,3.,4.], requires_grad=True)
b = a ** 2
print(b)
b.sum().backward()
print(a.grad)
tensor([ 1., 4., 9., 16.], grad_fn=<PowBackward0>)
tensor([2., 4., 6., 8.])
- 只有浮点数才能将requires_grad设置为True
- 只有标量值才能backward(),所以这里用了b.sum(),b.mean()也可以
- a.grad即a的梯度,就是b对a的偏导(导数),这里可以看出a2求导结果为2a。
zero_grad()
a = torch.tensor([1.,2.,3.,4.], requires_grad=True)
b = a ** 2
print(b)
c = b + 2
print(c)
b.sum().backward(retain_graph=True)
print(a.grad)
c.sum().backward()
print(a.grad)
tensor([ 1., 4., 9., 16.], grad_fn=<PowBackward0>)
tensor([ 3., 6., 11., 18.], grad_fn=<AddBackward0>)
tensor([2., 4., 6., 8.])
tensor([ 4., 8., 12., 16.])
这里可以看出,第1次a.grad为2a,是对的,但是在c反向传播后第2次a.grad的输出是4a是不对的,需要清零梯度。
a = torch.tensor([1.,2.,3.,4.], requires_grad=True)
b = a ** 2
print(b)
c = b + 2
print(c)
b.sum().backward(retain_graph=True)
print(a.grad)
a.grad.zero_()
c.sum().backward()
print(a.grad)
tensor([ 1., 4., 9., 16.], grad_fn=<PowBackward0>)
tensor([ 3., 6., 11., 18.], grad_fn=<AddBackward0>)
tensor([2., 4., 6., 8.])
tensor([2., 4., 6., 8.])
变量a相当于神经网络中的参数(需要求梯度并且更新),那些常量就相当于你的输入,不需要更新,所以不需要求梯度。
参考
https://zhuanlan.zhihu.com/p/416083478
|