autogard.Variable 是 Autograd 中的核心类,简单封装了Tensor。Tensor被封装为Variable之后,可以调用它的.backward实现反向传播,自动计算所有梯度。Variable数据结构如图所示:
Variable 主要包含三个属性。
data : 保存Variable所包含的Tensor
grad: 保存data对应的梯度。
grad_fn: 指向一个Function对象,这个Function用来反向传播计算输入的梯度
如果想要计算各个Variable的梯度,只需调用根节点variable的backward方法,autograd会自动沿着计算图反向传播,计算每一个叶子节点的梯度。
通过.requires_grad_()
来用in-place的方式改变requires_grad
属性:
a = torch.randn(2, 2) # 缺失情况下默认 requires_grad = False
a = ((a * 3) / (a - 1))
print(a.requires_grad) # False
a.requires_grad_(True)
print(a.requires_grad) # True
b = (a * a).sum()
print(b.grad_fn)
x = torch.ones(2, 2, requires_grad=True)
print(x)
print(x.grad_fn)
y = x + 2
z = y * y * 3
out = z.mean()
print(z, out)
out.backward()
print(x.grad) # out关于x的梯度、
# grad在反向传播过程中是累加的(accumulated),这意味着每一次运行反向传播,
# 梯度都会累加之前的梯度,所以一般在反向传播之前需把梯度清零。
# 再来反向传播一次,注意grad是累加的
out2 = x.sum()
out2.backward()
print(x.grad)
out3 = x.sum()
x.grad.data.zero_()
out3.backward()
print(x.grad)
x = torch.tensor([1.0, 2.0, 3.0, 4.0], requires_grad=True)
y = x * x
z = y.view(2, 2)
print(z)
# 现在z不是一个标量,所以在调用backward时需要传入一个和z同形的权重向量进行加权求和得到一个标量
v = torch.tensor([[1.0, 0.1], [0.01, 0.001]], dtype=torch.float)
z.backward(v)
print(x.grad)