RuntimeError: one of the variables needed for gradient computation has been modified by an inplace

部署运行你感兴趣的模型镜像

关于torch的with torch.no_grad()用法:

几行代码让你搞懂torch.no_grad - 知乎

leaf variable & with torch.no_grad & -=_爱编程的喵喵的博客-优快云博客

Python torch.no_grad用法及代码示例 - 纯净天空

RuntimeError: one of the variables needed for gradient computation 
has been modified by an inplace operation: [torch.FloatTensor [2]] 
is at version 1; expected version 0 instead.
解释:b = 0.5*a*a的梯度与变量a直接相关,如果是b = a*2,梯度与变量a无关则不回会报错

import torch
torch.autograd.set_detect_anomaly(True)
a = torch.ones(2,requires_grad=True)
b = 0.5*a*a
print(a,a.grad,a.requires_grad)
b.sum().backward(retain_graph = True)
print(a,a.grad,a.requires_grad)  # tensor([1., 1.])
with torch.no_grad():
    a += a.grad
    print(a,a.grad,a.requires_grad) # tensor([1., 1.]),打印缓存的梯度
#b.sum().backward(retain_graph = True)
'''
RuntimeError: one of the variables needed for gradient computation 
has been modified by an inplace operation: [torch.FloatTensor [2]] 
is at version 1; expected version 0 instead.
解释:b = 0.5*a*a的梯度与变量a直接相关,如果是b = a*2,梯度与变量a无关则不回会报错
'''
b = 0.5*a*a
b.sum().backward(retain_graph = True)
print(a,a.grad,a.requires_grad)  # tensor([3., 3.]),梯度累加了
b.sum().backward(retain_graph = True)
print(a,a.grad,a.requires_grad)  # tensor([5., 5.]),继续累加
a.grad.zero_()                   # 梯度清零
b.sum().backward(retain_graph = True)
print(a,a.grad,a.requires_grad)  # tensor([2., 2.])
输出:
tensor([1., 1.], requires_grad=True) None True
tensor([1., 1.], requires_grad=True) tensor([1., 1.]) True
tensor([2., 2.], requires_grad=True) tensor([1., 1.]) True
tensor([2., 2.], requires_grad=True) tensor([3., 3.]) True
tensor([2., 2.], requires_grad=True) tensor([5., 5.]) True
tensor([2., 2.], requires_grad=True) tensor([2., 2.]) True
torch.autograd.set_detect_anomaly(True)
a = torch.ones(2,requires_grad=True)
b = 0.5*a
print(a,a.grad,a.requires_grad)
b.sum().backward(retain_graph = True)
print(a,a.grad,a.requires_grad)  # tensor([0.5000, 0.5000])
with torch.no_grad():
    a += a.grad
    print(a,a.grad,a.requires_grad) # tensor([0.5000, 0.5000]),打印缓存的梯度
b.sum().backward(retain_graph = True)
print(a,a.grad,a.requires_grad)  # tensor([1., 1.]),梯度累加

输出:

tensor([1., 1.], requires_grad=True) None True
tensor([1., 1.], requires_grad=True) tensor([0.5000, 0.5000]) True
tensor([1.5000, 1.5000], requires_grad=True) tensor([0.5000, 0.5000]) True
tensor([1.5000, 1.5000], requires_grad=True) tensor([1., 1.]) True

您可能感兴趣的与本文相关的镜像

PyTorch 2.5

PyTorch 2.5

PyTorch
Cuda

PyTorch 是一个开源的 Python 机器学习库,基于 Torch 库,底层由 C++ 实现,应用于人工智能领域,如计算机视觉和自然语言处理

### 解决 PyTorch 中由原地操作引发的 RuntimeError 当遇到 `RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation` 错误时,这通常意味着某些张量在反向传播过程中被修改了其数据,而这些修改发生在计算图中的节点之后。这种情况下,PyTorch 无法正确追踪梯度的变化。 为了处理这种情况,可以采取以下几个措施: #### 启用异常检测 启用自动求导模块中的异常检测功能可以帮助定位具体在哪一步发生了问题。通过设置 `torch.autograd.set_detect_anomaly(True)` 可以让程序在每次前向传递后检查是否存在不合法的操作,并抛出更详细的错误信息以便调试[^1]。 ```python import torch # 开启anomaly detection模式来帮助查找问题所在 torch.autograd.set_detect_anomaly(True) # 继续执行训练循环... ``` #### 避免使用原地运算符 许多 PyTorch 的函数都有对应的原地版本(带有下划线 `_`),比如 `.add_()` 或者 `.relu_()`. 这些方法会直接改变输入张量的内容而不是创建新的对象返回。为了避免破坏计算图结构,在构建模型或者编写自定义层时应尽量避免使用这类原地操作[^2]。 例如,如果原本有如下代码片段: ```python output = F.relu(output, inplace=True) ``` 应该改为非inplace的形式: ```python output = F.relu(output) ``` #### 使用 detach 方法分离不需要跟踪的历史记录 对于那些确实需要做原地更新但是又不想影响到整个计算图的情况,可以通过调用 `.detach()` 来切断当前张量与其历史之间的联系,从而允许对其进行安全的原地更改而不干扰后续的梯度计算过程[^3]。 ```python detached_output = output.detach() detached_output.add_(some_value) # 对 detached_output 执行原地加法不会影响原始 tensor 的 history ``` #### 修改网络架构设计 有时,特定类型的神经元激活函数可能会更容易触发此类错误,特别是像 ReLU 和 Tanh 这样的饱和型激活函数。考虑调整使用的激活函数种类或是重新审视整体网络的设计逻辑是否合理[^4]。 综上所述,针对此 Runtime Error 主要策略包括开启 anomaly detection 辅助排查、禁用所有可能引起冲突的原地操作以及适当运用 .detach() 技巧等手段相结合的方式来进行修复工作。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值