为什么这个 PyTorch 回归程序通过周期性振荡达到零损失?
Why this PyTorch regression program reaches zero loss with periodic oscillations?
有一个 x 和一个 t,尺寸为 3x1。我试图找到 w (3x3) 和 b (3,1) 以便他们可以取悦这个等式:
t = w*x + b
下面的程序确实会振荡。我试图调试它但没有成功。其他人可以看看吗?我错过了什么?
class fit():
def __init__(self, w, b):
self.w = w
self.b = b
def forward(self, x):
return torch.mm(self.w, x) + self.b
w = torch.tensor([[1., 1.1, 1.2],
[1., 1.1, 1.2],
[1., 1.1, 1.2]], requires_grad=True)
b = torch.tensor([[10.], [11.], [12.]], requires_grad=True)
x = torch.tensor([[1.], [2.], [3.]], requires_grad=False)
t = torch.tensor([[0.], [0.9], [0.1]], requires_grad=False)
model = fit(w, b)
alpha = 0.001
loss = []
arange = np.arange(200)
for i in arange:
z = model.forward(x)
l = (z - t)**2
l = l.sum()
loss.append(l)
l.backward()
model.w.data = model.w.data - alpha * model.w.grad
model.b.data = model.b.data - alpha * model.b.grad
plt.plot(arange, loss)
如果我使用 PyTorch 的其他工具 (torch.nn.Linear, torch.optim.sgd, torch.nn.smeloss
),一切都会按预期进行。
您需要在每次反向传播后将梯度重置为 0。默认情况下,pytorch 在调用 loss.backward()
.
时会累积梯度
用以下行替换循环的最后 2 条指令应该可以解决问题:
with torch.no_grad():
model.w.data = model.w.data - alpha * model.w.grad
model.b.data = model.b.data - alpha * model.b.grad
model.w.grad.zero_()
model.b.grad.zero_()
有一个 x 和一个 t,尺寸为 3x1。我试图找到 w (3x3) 和 b (3,1) 以便他们可以取悦这个等式:
t = w*x + b
下面的程序确实会振荡。我试图调试它但没有成功。其他人可以看看吗?我错过了什么?
class fit():
def __init__(self, w, b):
self.w = w
self.b = b
def forward(self, x):
return torch.mm(self.w, x) + self.b
w = torch.tensor([[1., 1.1, 1.2],
[1., 1.1, 1.2],
[1., 1.1, 1.2]], requires_grad=True)
b = torch.tensor([[10.], [11.], [12.]], requires_grad=True)
x = torch.tensor([[1.], [2.], [3.]], requires_grad=False)
t = torch.tensor([[0.], [0.9], [0.1]], requires_grad=False)
model = fit(w, b)
alpha = 0.001
loss = []
arange = np.arange(200)
for i in arange:
z = model.forward(x)
l = (z - t)**2
l = l.sum()
loss.append(l)
l.backward()
model.w.data = model.w.data - alpha * model.w.grad
model.b.data = model.b.data - alpha * model.b.grad
plt.plot(arange, loss)
如果我使用 PyTorch 的其他工具 (torch.nn.Linear, torch.optim.sgd, torch.nn.smeloss
),一切都会按预期进行。
您需要在每次反向传播后将梯度重置为 0。默认情况下,pytorch 在调用 loss.backward()
.
用以下行替换循环的最后 2 条指令应该可以解决问题:
with torch.no_grad():
model.w.data = model.w.data - alpha * model.w.grad
model.b.data = model.b.data - alpha * model.b.grad
model.w.grad.zero_()
model.b.grad.zero_()