pytorch的计算图和自动求导机制

1. 自动求导机制

pytorch会根据就算过程自动生成动态图,然后可以根据动态图的创建过程进行反向传播,计算得到每个节点的梯度。在创建张量的时候设置requires_grad=True可以将该张量加入到计算图中。torch.autograd为pytorch的自动求导包,有torch.autograd.backward函数和torch.autograd.grad函数,其中torch.autograd.backward函数通过传入根节点张量,以及初始梯度张量(形状和当前张量相同),可以计算产生该该根节点所有对应的叶子节点的梯度。

2. 自动求导机制实例

反向传播函数

t1 = torch.randn(3, 3, requires_grad=True)
print(t1)
print('=' * 50)
t2 = t1.pow(2).sum()  # 计算张量的所有分量平方和
t2.backward()  # 反向传播
print(t1.grad)  # 梯度是张量原始分量的2倍
print('=' * 50)
t2 = t1.pow(2).sum()  # 再次计算张量的所有分量平方和
t2.backward()  # 再次反向传播
print(t1.grad)  # 梯度累积
print('=' * 50)
print(t1.grad.zero_())  # 单个梯度清零

在这里插入图片描述

3. 梯度函数的使用

如果不需要求出当前张量对所有产生该张量的叶子节点的梯度,可以使用torch.autograd.grad函数。该函数的参数为两个张量,第一个张量是计算图的数据结果张量(或张量列表),第二个张量是需要对计算图求导的张量(或张量列表)。最后的输出结果是第一个张量对第二个张量求导的结果,且梯度会累加。

t1 = torch.randn(3, 3, requires_grad=True)
t2 = t1.pow(2).sum()  # 根据t1张量计算t2张量
print(torch.autograd.grad(t2, t1))  # t2张量对t1张量求导

在这里插入图片描述

4. 计算图构建的启用和禁用

计算图的构建需要消耗内存和计算资源,但其并不是必要的,比如神经网络的推导。此时可以使用torch.no_grad上下文管理器,在这个管理器的作用域里进行的神经网络计算不会构建任何计算图。另外,对于一个张量,我们在反向传播的时候可能不需要让梯度通过这个张量的节点,也就是新建的计算图要和原来的计算图分离。此时就可以使用detach方法,通过调用这个方法返回一个新的张量,该张量会成为一个新的计算图的叶子节点,新的计算图和旧的计算图相互分离,互不影响。

t1 = torch.randn(3, 3, requires_grad=True)
t2 = t1.sum()
print(t2)  # t2的计算构建了计算图,输出结果带有grad_fn
with torch.no_grad():
    t3 = t1.sum()
print(t3)  # t3的计算没有构建计算图,输出结果没有grad_fn
print(t1.sum())  # 保持原来的计算图
print(t1.sum().detach())  # 和原来的计算图分离

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

饕餮&化骨龙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值