Python 现代开发学习笔记

(九)计算图、clone 与 detach

# 项目文件:demos/detach_graph.py
import torch

x = torch.tensor([1.0, 2.0], requires_grad=True)
branch = x.square()
copied = branch.clone()
detached = branch.detach()
print("梯度联系", copied.requires_grad, detached.requires_grad)
copied.sum().backward()  # clone 仍保留通向原 x 的求导路径。
print("原 x 梯度", x.grad.tolist())
detached[0] = 9
print("detach 共用数据", branch.detach().tolist())
independent = branch.detach().clone()
independent[0] = -1
print("独立副本未改原值", branch.detach().tolist())

branch=x.square() 建立从 x 到平方结果的联系,branch.clone() 复制数据后仍保留这条求导联系。因此对副本求和再反向,原 x 得到梯度 [2, 4]。

branch.detach() 得到不再沿原计算图求导的张量,但数据仍与 branch 共用。将它的首项改为 9,原平方结果也变为 [9, 4]。detach().clone() 同时完成脱离计算图和独立复制,常用于保存一份不会跟着训练变化的数据快照。

clone 复制数据但保留求导箭头,detach 去掉求导箭头却共用数据,detach 后 clone 同时得到无梯度联系的独立副本

每次前向都会按本次实际执行的运算建立图。backward 使用图中的中间信息后会释放已用的求导资源;下一轮再执行模型前向。日志中的损失可以保存 loss.item(),这样记录的是数值,不会把一轮轮计算图一起保留。相关机制见 PyTorch 自动微分。

笔记正文与全部题解 · Ctrl / ⌘ K