深度学习反向传播简单流程

反向传播简单例子:

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的偏导(导数),这里可以看出a²求导结果为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)
#计算图在backward一次之后默认就消失,我们下面还要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)
#计算图在backward一次之后默认就消失,我们下面还要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

你可能感兴趣的:(科研,pytorch,深度学习,tensorflow,python)