(八)自动微分复现手算
# 项目文件:demos/autograd_step.py
import torch
w = torch.tensor(1.0, requires_grad=True)
b = torch.tensor(0.0, requires_grad=True)
z = w * 2
prediction = z + b
loss = (prediction - 5).square()
z.retain_grad() # 中间结果的梯度用于核对图中的回传值。
loss.backward()
print("前向", z.item(), prediction.item(), loss.item())
print("梯度", w.grad.item(), b.grad.item(), "中间", z.grad.item())
print("叶子", w.is_leaf, z.is_leaf)requires_grad=True 让浮点参数参与求导。乘法、加法和平方执行时,同时留下本次计算的联系,形成计算图;loss.backward() 从标量损失反向计算。结果写到参数的 .grad,所以输出为 w.grad=-12、b.grad=-6。
w 与 b 是直接创建的叶子张量,梯度默认累积到它们。z 是运算得到的中间结果,调用 retain_grad() 后也留下它的梯度,方便在这个演示里核对 -6。item() 把只含一个元素的结果取成普通 Python 数值,用来打印。
# 续写同一文件:demos/autograd_step.py
with torch.no_grad():
# 更新参数本身,不把优化动作接入下一次求导的计算图。
w -= 0.05 * w.grad
b -= 0.05 * b.grad
print("新参数", round(w.item(), 6), round(b.item(), 6))
print("新损失", round(((w * 2 + b - 5).square()).item(), 6))torch.no_grad() 让参数更新作为一次普通修改,随后重新前向得到新的计算图。输出的新参数为 1.6、0.3,新损失为 2.25。backward 负责求导,更新参数的代码负责改变模型,两个动作在这里分别执行。