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()\)

\(c\)\(out\) 的区别是 \(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 @ 2023-03-06 23:14  做梦当财神  阅读(232)  评论(0编辑  收藏  举报