梯度,我们先简单认为就是函数的导数
比如 y=x*2,y'=2*x
代入x1 = 3,则此时梯度为 6
代码1
import torch
x = torch.tensor([3.0], requires_grad=True)
print(x.grad) # None,因为还没有进行反向传播,所以梯度是None
# 例1、y=x^2
y = x * x # y = x^2
y.backward() # 反向传播,计算梯度
print(x.grad) # 因为 y = x^2, 求导后 y' = 2x。代入3,梯度为6
# 例2、z=x^3
y = x * x * x # z = x^3,再求导后 z' = 3x^2。导入3,梯度为27
y.backward()
print(x.grad) # 6 + 27 = 33,因为前面没有清空梯度,梯度会累加
# 例3、清空梯度
x.grad.data.zero_()
print(x.grad) # tensor(0.),梯度清空
# 例4、y = x + 2
y = x + 2
y.backward()
print(x.grad) # 1,因为y=x+2,y'=1
每次对x张量进行操作后,进行反向传播后,会计算梯度,并进行累积,需要清空才能获得当前操作的梯度。
即求 dy / dx
运行结果1
None
tensor([6.])
tensor([33.])
tensor([0.])
tensor([1.])
再上一个二维的张量例子
代码2
import torch
# requires_grad,设置为True则表示该Tensor需要求导
# grad_fn,记录了创建该Tensor的操作,如果用户创建的Tensor,则grad_fn为None;如果是通过某个操作创建的,则grad_fn记录了这个操作
# is_leaf,表示该Tensor是否是叶子节点,叶子节点是指用户创建的,而非通过某个操作创建的
# grad,保存了该Tensor的梯度,如果该Tensor不是叶子节点,则梯度是None
# x = torch.ones(2, 2, requires_grad=True) # requires_grad=True表示需要求导
x = torch.tensor([[1.0, 1.0], [1.0, 1.0]], requires_grad=True)
print(x.is_leaf) # True,x是叶子节点,因为它是用户创建的
print()
y = x + 2
print(y)
print(y.grad_fn) # y是通过一个加法操作创建的,所以grad_fn是<AddBackward0 object at 0x0000020D3D3D3A90>
print()
z = y * y * 3 # z = 3(y^2) = 3(x+2)^2
out = z.mean() # 求z的均值
print(z)
print(out) # out = (3(x+2)^2)/4,out求导 = 3*2(x+2)/4
out.backward() # 反向传播,计算梯度
print(x.grad)
即求 d(out) / dx
运行结果2
True
tensor([[3., 3.],
[3., 3.]], grad_fn=<AddBackward0>)
<AddBackward0 object at 0x7fde240893d0>
tensor([[27., 27.],
[27., 27.]], grad_fn=<MulBackward0>)
tensor(27., grad_fn=<MeanBackward0>)
tensor([[4.5000, 4.5000],
[4.5000, 4.5000]])
您可以选择一种方式赞助本站
支付宝扫一扫赞助
微信钱包扫描赞助
赏