pytorch自动求导详解

涉及知识点

Tensor属性:.grad,.grad_fn, .requires_grad

Tensor函数:.backward(),.detach(),,retain_grad()

函数:.zero_grad()

求梯度函数backward()以及其参数gradient

计算图

雅各比矩阵

前向传播过程

接下来的内容都以下面的两段代码为例:

import torch
# 假设我们有一个可微的Tensor
x = torch.tensor([1, 2, 3], requires_grad=True,dtype=float)

# 执行一个可微操作
y = x * 2

z = y.mean()
z.backward()

# 查看Tensor的梯度信息
print(z.grad) #输出None

print(y.grad) #输出None

print(x.grad) #输出[0.6667,0.6667,0.6667]
import torch
# 假设我们有一个可微的Tensor
x = torch.tensor([1, 2, 3], requires_grad=True,dtype=float)

# 执行一个可微操作
y = x * 2

v = torch.tensor([2,1,1],dtype=float)

y.backward(v)

# 查看Tensor的梯度信息

print(y.grad) #输出None

print(x.grad) #输出[4.,2.,2.]
计算图,grad_fn,requires_grad

先看第一段代码。pytorch在前向传播的时候,如果经过的是可微操作(比如一个nn.Module中的层,或者是一个torch.autograd中的函数(如矩阵乘法)),那么将该操作并入计算图中。同时会记录对应tensor的grad_fn属性。方便后续进行反向传播计算。

在第一段代码里,x.grad_fn为None(x是人为创建的),y.grad_fn为MultiBackward,z.grad_fn为MeanBackward。

另外要注意requires_grad参数。只有tensor的requires_grad为True时,pytorch才会保留梯度信息。一般来说requires_grad默认是False(为了省空间)。但是神经网络中网络参数的requires_grad默认为True。

若一个tensor A 的requires_grad为True,则在计算图中与它相关的,涉及到计算该tensor的变量,requires_grad都会被设定为True(不然就无法计算A的梯度了)

grad,backward()以及其参数gradient

仅仅是前向传播计算,变量的grad仍然为None。只有调用了backward()函数,变量的grad才会被计算出来。

但是这里有好几个注意点:

  1. 所谓的grad就是导数。例如 y = x ∗ 2 y = x*2 y=x2,那么x的grad就是2(单变量,多变量下面会谈到)可以看看第一段代码的输出,自己计算一下
  2. 由于pytorch的内存管理机制,计算图中非叶子节点变量的grad是不保留的。这就是为什么第一段代码中z,y的grad都为None。如果要保留,就要使用retain_grad函数
  3. pytorch中基本都是处理的多变量的梯度计算。所以调用backward时,pytorch底层是使用雅各比矩阵来计算梯度的。由于雅各比矩阵计算方式的原因,如果想要按照第一段代码中 z . b a c k w a r d ( ) z.backward() z.backward()的方式调用,则要求 z z z为标量。否则就需要像第二段代码中的方式,人为提供 g r a d i e n t gradient gradient参数。(具体原因各位可以去看看雅各比矩阵的原理雅可比矩阵 Jacobian & 海塞矩阵 Hessian - 知乎 (zhihu.com)
  • 30
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值