【问题标题】:Why Pytorch autograd need another vector to backward instead of computing Jacobian?为什么 Pytorch autograd 需要另一个向量来向后而不是计算雅可比?
【发布时间】:2020-12-28 03:54:05
【问题描述】:

要在 Pytorch 中执行backward,我们可以使用可选参数y.backward(v) 来计算雅可比矩阵乘以v

x = torch.randn(3, requires_grad=True)
y = x * 2

v = torch.tensor([0.1, 1.0, 0.0001], dtype=torch.float)
y.backward(v)

print(x.grad)

我认为计算雅可比矩阵的成本相同,因为 AD 图中计算雅可比矩阵所需的每个节点仍会被计算。那么为什么 Pytorch 不想给我们雅可比矩阵呢?

【问题讨论】:

  • 欢迎来到 Stack Overflow!
  • @GilPinsky 谢谢!

标签: python optimization pytorch backpropagation automatic-differentiation


【解决方案1】:

当您调用backward() 时,PyTorch 会将每个可学习参数的grad 更新为带有某个损失函数L w.r.t 的梯度到该参数。它的设计考虑了梯度下降 [GD](及其变体)。计算出梯度后,您可以使用x = x - learning_rate * x.grad 更新每个参数。实际上,必须在后台计算雅可比行列式,但这不是应用 GD 优化时(通常)需要的。向量[0.1, 1.0, 0.0001] 允许您将输出减少为标量,以便 x.grad 将是一个向量(而不是矩阵,以防您不减少),因此 GD 定义明确。但是,您可以使用带有 one-hot 向量的反向来获得雅可比行列式。例如,在这种情况下:

x = torch.randn(3, requires_grad=True)
y = x * 2
J = torch.zeros(x.shape[0],x.shape[0])
for i in range(x.shape[0]):
    v = torch.tensor([1 if j==i else 0 for j in range(x.shape[0])], dtype=torch.float)
    y.backward(v, retain_graph=True)
    J[:,i] = x.grad
    x.grad.zero_()
print(J)

【讨论】:

  • 注解:x.grad 是简化情况下的向量而不是矩阵。
  • 另一个问题:retain_graph=True 会减少大部分重复计算吗?
  • 是的,你是对的。对于您的第二个问题,它将使您免于重复前向传播。 retain_graph 将保存表示计算梯度的函数的图,梯度是在你完成前向传播后计算的。在内部,每个 torch.Tensor 都是该图的入口点,并且有一个 grad_fn 属性,用于计算反向传播,但在您向后调用后仍需要对其进行评估。
猜你喜欢
  • 2021-10-02
  • 2021-01-23
  • 1970-01-01
  • 1970-01-01
  • 2011-04-21
  • 2019-04-02
  • 1970-01-01
  • 2020-05-01
  • 1970-01-01
相关资源
最近更新 更多