1

我有两个已初始化的张量(矩阵):

sm=Var(torch.randn(20,1),requires_grad=True)
sm = torch.mm(sm,sm.t()) 
freq_m=Var(torch.randn(12,20),requires_grad=True)

我正在从这两个矩阵中的数据创建两个列表,并且我正在使用 spearmanr 来获取这两个列表之间的相关值。我如何创建列表并不重要,但目标是调整矩阵内的值,使计算出的相关值尽可能接近 1。

如果我要手动解决这个问题,我会每次将矩阵中的值调整 0.01(或一些小数字)并重新计算列表和相关分数。如果新的相关值高于前一个,我会保存 2 个矩阵并调整不同的值,直到我得到 2 个矩阵给我可能的最高相关分数。

PyTorch 是否能够自动执行此操作?我知道 PyTorch 可以根据方程式进行调整,但我想要调整矩阵值的方式不是针对方程式,而是针对我计算的相关值。非常感谢您对此的任何指导!

4

1 回答 1

1

Pytorch 有一个 autograd 包,这意味着如果你有变量并且你通过可微函数传递它们并获得标量结果,你可以执行梯度下降来更新变量以降低或增加标量结果。

所以你需要做的是定义一个在张量级别上工作的函数 f ,这样 f(sm, freq_m) 会给你所需的相关性。

然后,您应该执行以下操作:

lr = 1e-3
for i in range(100):
  # 100 updates
  loss = 1 - f(sm, freq_m)
  print(loss)
  loss.backward()
  with torch.no_grad():
    sm -= lr * sm.grad
    freq_m -= lr * freq_m.grad
    # Manually zero the gradients after updating weights
    sm.grad.zero_()
    freq_m.grad.zero_()

学习率基本上就是你做的步长的大小,学习率太高会导致损失爆炸,学习率太小会导致收敛慢,建议你实验一下。

编辑:回答以下评论loss.backward:对于任何可微函数 f,f 是多个张量的函数,t1, ..., tn因此requires_grad=True,您可以计算每个张量的损失梯度。当您这样做时loss.backward,它会计算这些梯度并将其存储在 t1.grad、...、tn.grad 中。然后t1, ..., tn使用梯度下降进行更新以降低 f 的值。此更新不需要计算图,因此这就是您使用with torch.no_grad(). 在循环结束时,将渐变归零,因为.backward不会覆盖渐变,而是将新渐变添加到其中。更多信息:https ://discuss.pytorch.org/t/why-do-we-need-to-set-the-gradients-manually-to-zero-in-pytorch/4903

于 2019-08-26T10:01:18.097 回答