detach操作相当于深度拷贝——返回一个不同内存空间的新变量充当叶子节点

pytorch.deatch()方法的结论与代码证明。

  • datach操作,相当于一个深度拷贝,操作后返回的变量和被detach的节点不属于同一个内存id,同时之后,被detach的节点的内容被修改后,返回的变量不会随之更改。
  • detach操作后返回的变量默认不进行梯度计算,因此如果希望计算该叶子节点,则需要指定其梯度计算属性。
import torch

A = torch.Tensor([1, 1., 2, 3])
B = torch.Tensor([1, 1, 1, 1])
A.requires_grad_(True)
B.requires_grad_(True)
C = A + B

E = C.detach()
F = C.detach()

E.requires_grad_(True)

D = C * A * E * F
print("C, E, F:\n", C, E, F)

D.sum().backward()
print(A.grad)
print(B.grad)

# EF的不同在于E被指定了计算梯度值,当作一个可计算梯度的叶子节点;
# 如果未指定,则就是作为一个标量,对计算有贡献,但是并不需要计算梯度。
print(E.grad)
print(F.grad)

# 1 非叶子节点不存在梯度值,特征X是,每一层的权重也是叶子;
# 2 deatch前后获得的数据是同id吗?不同;而这种detach是一种深拷贝,当然它因为是torch中的行为,因此还具有其他的功能。

C = A
# 如果输出与上面的EF值相同,且不同于变换后的C值,那就表明detach操作是一种深度拷贝。任何一方的操作不会引起另一方的数值变换。
print(id(C), id(E), id(F))
print("C, E, F:\n", C, E, F)
# ----------------------------
"""
C, E, F:
tensor([2., 2., 3., 4.], grad_fn=<AddBackward0>) tensor([2., 2., 3., 4.], requires_grad=True) tensor([2., 2., 3., 4.])
tensor([ 12.,  12.,  45., 112.])
tensor([ 4.,  4., 18., 48.])
tensor([ 4.,  4., 18., 48.])
None
-----------------------------
140374691657088 140380286141312 140380286141376
C, E, F:
 tensor([1., 1., 2., 3.], requires_grad=True) tensor([2., 2., 3., 4.], requires_grad=True) tensor([2., 2., 3., 4.])
"""
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值