news 2026/7/23 18:23:55

【PyTorch】with torch.no_grad() 详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【PyTorch】with torch.no_grad() 详解

在阅读以下内容前,请务必先大致了解计算图机制,特别是叶子节点:pytorch——计算图与动态图机制

with torch.no_grad()在 PyTorch官网 中的定义为:

Context-manager that disables gradient calculation.

意思是with torch.no_grad()是一个用于禁用梯度的上下文管理器。禁用梯度计算对于推理是很有用的,当我们确定不会调用Tensor.backward()时,它将减少计算的内存消耗。
需要注意:它并不会直接修改张量自身的requires_grad属性;本质上在其内部执行的所有运算,不会构建计算图节点,也不会跟踪依赖。所以即便输入张量requires_grad=True,运算生成的新张量无法继承梯度依赖,默认requires_grad=False


除此之外,with torch.no_grad()还通常与原地操作(in-place operation)组合在一起。原地操作有明确定义:

当计算图追踪处于开启状态时,对于 requires_grad=True 的叶子张量(leaf tensor)不能使用 inplace operation

因为原地操作会直接覆盖张量内存中的原始数值。若仍在计算图构建阶段,叶子张量原始值是反向传播求导必需的数据;一旦原值被覆盖,梯度与张量数值之间的依赖关系断裂,求导无法正常进行,因此框架提前抛出异常。

withtorch.no_grad():forparaminparams:param-=lr*param.grad/batch_size param.grad.zero_()# 清空当前梯度

我们针对以上操作进行探究,以更好理解该情况下with torch.no_grad()的作用。

  1. 不使用with torch.no_grad(),直接进行原地操作
forparaminparams:param-=lr*param.grad/batch_size param.grad.zero_()# 清空当前梯度

运行上面的代码会报错,错误信息为RuntimeError: a leaf Variable that requires grad is being used in an in-place operation.意思是在原地操作中使用了需要梯度的叶子节点。

如果打印验证可以发现:无论是否包裹with torch.no_grad()param.requires_grad始终为True。这与前文的定义是吻合的,在计算图追踪关闭时,即使是叶子节点并具requires_grad属性也可以进行就地操作。
与原地操作无关的,补充两点客观现象:

  1. lr * param.grad / batch_size运算生成临时张量,该临时张量的requires_grad = False
  2. param.grad作为参数附属的梯度张量,本身requires_grad恒为False,该性质与是否启用with torch.no_grad()无关。
  1. 不使用with torch.no_grad()进行赋值操作
forparaminparams:param=param-lr*param.grad/batch_sizeprint(param.is_leaf)# Falseparam.grad.zero_()# 清空当前梯度

运行上面的代码会报错,错误信息为AttributeError: 'NoneType' object has no attribute 'zero_'。我们都知道赋值操作会新创建一块内存以存放数据,所以根据计算图理论,此时的param是中间节点,不再是叶子节点,不具有grad属性了。

  1. 使用with torch.no_grad()进行赋值操作
withtorch.no_grad():forparaminparams:print(param.requires_grad)# Trueparam=param-lr*param.grad/batch_sizeprint(param.is_leaf)# Trueprint(param.requires_grad)# Falseparam.grad.zero_()# 清空当前梯度

运行上面的代码同样会报错,错误信息为AttributeError: 'NoneType' object has no attribute 'zero_'

torch.no_grad()上下文内不再构建计算图。执行param = param - lr * param.grad / batch_size依旧生成一块全新张量:

  1. 该张量在无梯度追踪环境下创建,不存在运算依赖,因此is_leaf=True
    上下文内运算不会继承梯度标记,故requires_grad=False
  2. requires_grad=False的张量不会分配梯度缓冲区,.grad恒为None,因此调用.zero_()报错。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/23 18:17:23

如何基于小型工控机与openwrt打造家用软路由

前言 何为软路由?顾名思义,区别于一般的家用路由器,软路由由软件实现家用路由器的一系列功能,目前最常见软路由软件就是openwrt了,本质上openwrt不是一个应有软件,而是类似于centos/suse等的基于linux内核的…

作者头像 李华
网站建设 2026/7/23 18:16:25

麒麟信安登录央视, 深度展现为中国信息安全铸“魂”之路

近日,麒麟信安登录央视频道,《麒麟信安——为中国信息安全铸“魂”》在CCTV-4中文国际频道、CCTV-7国防军事频道、CCTV-10 科教频道、CCTV-12社会与法频道、CCTV-17农业农村频道,向亿万观众深度展现麒麟信安为中国信息安全铸“魂”之路。 麒麟…

作者头像 李华
网站建设 2026/7/23 18:14:47

【模拟IC学习笔记】 PSS和Pnoise仿真

目录 PSS Engine Beat frequency Number of harmonics Accuracy Defaults Run tranisent?的3种设置 Pnoise type noise Timeaverage sampled(jitter) Edge Crossing Edge Delay Sampled Phase sample Ratio 离散时间网络(开关电容电路)的噪声仿真方法 PSS PSS…

作者头像 李华
网站建设 2026/7/23 18:14:14

PairLIE论文阅读笔记

PairLIE论文阅读笔记 已转博客园和知乎,文章均无需VIP免费看。博客园主页:https://www.cnblogs.com/RunfarAI。知乎主页:https://www.zhihu.com/people/liu-he-ting-yu-47。 兴趣:Low Level Vision,图像恢复,大模型 论文为2023CVPR的Learning a Simple Low-light Image E…

作者头像 李华
网站建设 2026/7/23 18:10:59

Qt 定时器放在线程中执行,支持随时开始和停止定时器。

前言:因为项目需要定时检查网络中设备是否能连通,需要定时去做ping操作,若是网络不通,则ping花费时间比较久(局域网大概4秒钟才能结束,当然如果设置超时时间啥的,也能很快返回,就是会…

作者头像 李华