576 字
3 分钟
pytorch学习12:自动求导
autograd.grad
示例:
使用损失函数为均方差
原函数形式为:
import torch.nn.functional as Fimport torch
x = torch.tensor(2)# 可以在初始化时声明需要参数# 即设置 requires_grad=True# 若此时不声明,则需要执行 w.requires_grad_() 声明w = torch.full([1], 2, requires_grad=True, dtype=torch.float)b = torch.tensor([1], dtype=torch.float)
# 需要执行 requires_grad_() 方法表示需要梯度# 否则会报错# RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn# w.requires_grad_()b.requires_grad_()
# 想要获得梯度,必须在计算误差之间声明需要梯度y_ = x*w+b# 这里 data 表示只输出数据# 若不加,则会输出 tensor([5.], grad_fn=<AddBackward0>)print("x*w+b = ", y_.data)
# 假设真实 y = 1mse = F.mse_loss(torch.ones(1), y_)print("mse:", mse.data)
w_grad, b_grad = torch.autograd.grad(mse, [w, b])print("w_grad:", w_grad)print("b_grad:", b_grad)
loss.backward
backward方法会将梯度直接应用在变量上,通过 .grad 来获得梯度
示例:
import torch.nn.functional as Fimport torch
x = torch.tensor(2)w = torch.full([1], 2, requires_grad=True, dtype=torch.float)b = torch.tensor([1], dtype=torch.float)
b.requires_grad_()
y_ = x*w+bprint("x*w+b = ", y_.data)
mse = F.mse_loss(torch.ones(1), y_)print("mse:", mse.data)
# 使用backword来自动求导mse.backward()
# 通过 .grad 获得梯度print("w_grad:", w.grad)print("b_grad:", b.grad)
其他操作
使用 .requires_gard_() 可以改变张量的 requires_gard 属性。
import torch
a = torch.randn(2, 2)a = ((a * 3) / (a - 1))print(a.requires_grad)a.requires_grad_(True)print(a.requires_grad)
一些其他示例
softmax自动求导
import torch.nn.functional as Fimport torch
x = torch.tensor([2, 1, 0.1], requires_grad=True)print("x:", x)output_ = F.softmax(x, dim=0)print("output_:", output_)
# 会报错,显示:只能为标量输出隐式创建梯度# o.backward()
# 会报错,显示:只能为标量输出隐式创建梯度# 不能直接写 torch.autograd.grad(output_, x)
# 对 softmax[0] 求梯度# 因为 x 有三个数,所以会有 3 个梯度o0_grad = torch.autograd.grad(output_[0], x)print(o0_grad)print("p0 * (1 - p0) = ", (output_[0] * (1 - output_[0])).data)print("-(p0 * p1) = ", (- output_[0] * output_[1]).data)print("-(p0 * p2) = ", (- output_[0] * output_[2]).data)
链式法则
import torch.nn.functional as Fimport torch
x = torch.tensor(3)b1 = torch.tensor(1)w1 = torch.tensor(2., requires_grad=True)b2 = torch.tensor(1)w2 = torch.tensor(2., requires_grad=True)
u = x*w1 + b1y = u*w2 + b2
def d(y, x): # retain_graph=True 表示可以反复求导,否则只能求一次 return torch.autograd.grad(y, x, retain_graph=True)
# 通过 pytorch 直接求导print("dy_dw1 = ", d(y, w1))# 通过链式法则求导print("dy_du * du_dw1 = %s * %s" % (d(y, u), d(u, w1)))
原文链接:CSDN
pytorch学习12:自动求导
https://blog.homura.work/posts/csdn/119742227/