PyTorch自动求导机制

从后向传播中排除子图

每一个tensor都有一个requires_grad标志,利用该标志可以精确地从计算图中排除子图,并且可以提高效率。

requires_grad

如果一个计算的输入需要计算梯度,则它的输出也需要计算梯度。相反,只有当所有的输入都不需要计算梯度时,输出才不需要计算梯度。如果子图中所有的tensor都不需要计算梯度,则不会在此子图上进行反向传播计算。
在这里插入图片描述
当你想要冻结模型的一部分,或者提前知道不需要计算某些参数的梯度时,上述这点非常有用。例如,对一个预训练过的CNN进行微调时,只需在冻结的基础上改变requires_grad,并且不会保存中间的缓冲区,直到计算到达最后一层,其中的仿射变换利用的权重需要计算梯度,神经网络的输出也需要计算梯度。
在这里插入图片描述

autograd如何编码过程

autograd是自动微分的反向系统。从概念上讲,autograd记录了一个图,这个图记录了生成结果的所有的运算,由此形成一个有向无环图,图的叶结点为输入的tensor,根结点为输出的tensor。沿着从根结点到叶结点的路径,利用链式法则就可以自动计算所有的梯度。

就内部而言,autograd将此图表示为关于Function对象(实际上是表达式)的图,Function可用于计算评估图的结果。当执行前向传播时,autograd同时运行所要求的计算,并且生成一个图,该图表示计算梯度的function(每个tensor.grad_fn属性是该图的入口点)。当前向传播完成时,我们在后向传播中评估此图以计算梯度。

需要注意的一点是,在每次迭代时都会重新生成此图,这正是允许使用任意的Python控制流语句的原因,使用这些语句可以改变计算图的形状和大小。在进行训练前,不需要编码所有可能的路径,所运行的就是所要微分的。

autograd下的原地操作

autograd中支持原地操作是一件困难的事,多数情况下,我们不鼓励使用。autograd激进的缓冲释放和重用使其非常高效,原地操作大幅降低内存使用的情况非常少见。除非在非常大的内存压力下运行,否则永远不需要使用它们。

限制原地操作适用性的原因主要有两个:

  • 原地操作可能会覆盖需要计算梯度的值

  • 实际上,每个原地操作要求实现重写计算图。非原地操作版本简单地分配新的对象并保留对旧的计算图的引用,然而原地操作需要将所有输入的creator更改为表示此操作的Function。这可能很困难,特别是当有许多的tensor引用相同的存储(例如通过索引或转置生成),实际上,如果被修改输入的存储被其他tensor引用时,原地操作会引发错误。

原地错误检查

每个tensor保留一个版本计数器,在任何操作中,如果被标记为脏(dirty),则需要递增。当Function保存tensor以便后向传播时,也会保存每个tensor的版本号。每当访问self.saved_tensors时,便会检查,若它大于保存的值,则会引发错误。这可以确保,如果使用原地操作并且没有发生任何错误,那么计算的梯度是正确的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值