使用 PyTorch 根据我从张量计算的数字调整张量矩阵值?
Use PyTorch to adjust Tensor matrix values based on numbers I calculate from the Tensors?
我有两个已初始化的张量(矩阵):
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 可以根据方程进行调整,但我想要调整矩阵值的方式不是针对方程,而是针对我计算的相关值。非常感谢任何指导!
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
我有两个已初始化的张量(矩阵):
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 可以根据方程进行调整,但我想要调整矩阵值的方式不是针对方程,而是针对我计算的相关值。非常感谢任何指导!
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