backward怎么计算的是torch.tensor(2.0, requires_grad=True)变量的梯度
import torch
import torch.nn as nn
import torch.optim as optim# 一个参数 w = 2
w = torch.tensor(2.0, requires_grad=True)
# 预测值
y_pred = w * 3 # 6
# 真实值
y_true = torch.tensor(10.0)
# 损失 = (预测 - 真实)^2
loss = (y_pred - y_true) ** 2 # (6-10)^2 = 16loss.backward() # 反向传播print(w.grad) # 打印梯度
因为requires_grad=True,有了这个标记,loss就会把w看作参数,loss.backward就会求梯度,并保存到w.grad中
保存到w.grad中怎么实现的?python哪怕不输入w,也可以修改w的参数
class Param:def __init__(self, value):self.value = valueself.grad = 0# 可变对象,保存梯度
w = Param(2.0)# 定义 loss 函数,直接用 w
def compute_loss():y_pred = w.value * 3y_true = 10loss = (y_pred - y_true) ** 2return loss# 反向传播模拟
def backward(loss):# 直接访问 w 对象,修改 w.gradw.grad = 2 * 3 * (w.value*3 - 10) loss = compute_loss()
backward(loss)
print(w.grad) # 24
自定义的类想要直接计算乘法需要写函数
class Param:def __init__(self, value):self.value = valuedef __mul__(self, other):return self.value * other # 定义 w * 3 的行为def __rmul__(self, other):return other * self.value # 定义 3 * w 的行为w = Param(2.0)
print(w * 3) # 输出 6.0
print(3 * w) # 输出 6.0
更新参数也不用传入该参数
# 用梯度更新参数 wwith torch.no_grad(): # 禁止 autograd 跟踪w -= lr * w.grad # w = w - lr * grad# 梯度用完要清零,不然会累积w.grad.zero_()