torch.detach()、torch.detach_()

训练网络的时候希望保持一部分网络参数不变,只对其中一部分的参数进行调整;或训练部分分支网络,并不让其梯度对主网络的梯度造成影响,这时可以使用detach()切断一些分支的反向传播。



1. tensor.detach()

返回一个新的 tensor,从当前计算图中分离下来,但仍指向原 tensor 的存放位置,不同之处是requires_grad参数为 False,得到的这个 tensor 永远不需要计算梯度。不具有 grad

注意:

  • 即使之后将requires_grad设置为 True ,也不会具有梯度。
  • 使用detach返回的 tensor 和原始的 tensor 共同一个内存,即一个修改另一个也会跟着改变。

示例:参数为requires_grad=True,不具有梯度;反向传播 backward() 有梯度。

import torch

a = torch.tensor([1, 2, 3.], requires_grad=True)
print(a.grad)

out = a.sigmoid()
out.sum().backward()
print(a.grad)
None

tensor([0.1966, 0.1050, 0.0452])

示例:使用detach()分离 tensor, 原始 tensor 可进行 backward()

import torch

a = torch.tensor([1, 2, 3.], requires_grad=True)
print(a.grad)

out = a.sigmoid()
print(out)

# 添加 detach(), c 的 requires_grad 为 False
c = out.detach()
print(c)

# c 是添加 detach() 后的,不影响 out 的 backward()
out.sum().backward()
print(a.grad)
None

tensor([0.7311, 0.8808, 0.9526], grad_fn=<SigmoidBackward0>)

tensor([0.7311, 0.8808, 0.9526])

tensor([0.1966, 0.1050, 0.0452])

示例:使用detach()分离 tensor,新的 tensor 不能进行 backward()

cout 的区别是 c 没有梯度,out 有梯度。

#使用 c 进行反向传播
c.sum().backward()
print(a.grad)
RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn

示例:使用detach()分离 tensor,对新的 tensor 更改,原始 tensor 也会更改,两者都不能进行 backward()

import torch

a = torch.tensor([1, 2, 3.], requires_grad=True)
print(a.grad)

out = a.sigmoid()
print(out)

# 添加 detach(), c 的 requires_grad 为 False
c = out.detach()
print(c)

# 对 c 进行更改,会影响 out
c.zero_()
print(c)
print(out)

# 对 c 进行更改,会影响 out 进行 backward()
out.sum().backward()
print(a.grad)
None

tensor([0.7311, 0.8808, 0.9526], grad_fn=<SigmoidBackward0>)

tensor([0.7311, 0.8808, 0.9526])

tensor([0., 0., 0.])
tensor([0., 0., 0.], grad_fn=<SigmoidBackward0>)

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


2. tensor.detach_()

detach()detach_()的区别:detach_()对本身的更改,detach()则生成新的的 tensor,后面想反悔只需对原来的计算图进行操作即可。



posted @   做梦当财神  阅读(348)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
历史上的今天:
2019-03-06 Jupyter Notebook插入图片的4种方法
2018-03-06 Python with as 的用法
点击右上角即可分享
微信分享提示