如何在pytorch中手动应用渐变

时间:2018-03-07 14:38:44

标签: mathematical-optimization pytorch autograd

开始学习pytorch并尝试做一些非常简单的事情,尝试将大小为5的随机初始化向量移动到目标向量值[1,2,3,4,5]。

但我的距离并没有减少!!我的矢量import torch import numpy as np from torch.autograd import Variable # regress a vector to the goal vector [1,2,3,4,5] dtype = torch.cuda.FloatTensor # Uncomment this to run on GPU x = Variable(torch.rand(5).type(dtype), requires_grad=True) target = Variable(torch.FloatTensor([1,2,3,4,5]).type(dtype), requires_grad=False) distance = torch.mean(torch.pow((x - target), 2)) for i in range(100): distance.backward(retain_graph=True) x_grad = x.grad x.data.sub_(x_grad.data * 0.01) 变得疯狂了。不知道我错过了什么。

=SUMPRODUCT((ISNUMBER(FIND("," & E2 & "," , "," & $D$2:$D$4 & ",")))*($C$2:$C$4))

1 个答案:

答案 0 :(得分:1)

代码中有两个错误会阻止您获得所需的结果。

第一个错误是您应该将距离计算放在循环中。因为距离是这种情况下的损失。所以我们必须在每次迭代中监控它的变化。

第二个错误是您应该手动将x.grad归零,因为pytorch won't zero out the grad in variable by default

以下是按预期工作的示例代码:

import torch
import numpy as np
from torch.autograd import Variable
import matplotlib.pyplot as plt

# regress a vector to the goal vector [1,2,3,4,5]

dtype = torch.cuda.FloatTensor # Uncomment this to run on GPU

x = Variable(torch.rand(5).type(dtype), requires_grad=True)
target = Variable(torch.FloatTensor([1,2,3,4,5]).type(dtype), 
requires_grad=False)

lr = 0.01 # the learning rate

d = []
for i in range(1000):
  distance = torch.mean(torch.pow((x - target), 2))
  d.append(distance.data)
  distance.backward(retain_graph=True)

  x.data.sub_(lr * x.grad.data)
  x.grad.data.zero_()

print(x.data)

fig, ax = plt.subplots()
ax.plot(d)
ax.set_xlabel("iteration")
ax.set_ylabel("distance")
plt.show()

以下是距离w.r.t迭代的图表

enter image description here

我们可以看到模型在大约600次迭代时收敛。如果我们将学习率设置得更高(例如,lr = 0.1),模型将更快地收敛(需要大约60次迭代,见下图)

enter image description here

现在,x变成类似下面的内容

  

0.9878    1.9749    2.9624    3.9429    4.9292

非常接近[1,2,3,4,5]的目标。