[英]The loss value does not decrease
我正在使用 Pytorch 實現一個簡單的前饋神經網絡,並且損失 function 似乎沒有減少。 由於我已經完成了一些其他測試,問題似乎出在我為計算pred所做的計算中,因為如果我稍微改變網絡以便它為每個條目吐出一個二維向量並將其保存為 pred,一切完美運行。
你看到這里定義 pred 的問題了嗎? 謝謝
import torch
import numpy as np
from torch import nn
dt = 0.1
class Neural_Network(nn.Module):
def __init__(self, ):
super(Neural_Network, self).__init__()
self.l1 = nn.Linear(2,300)
self.nl = nn.Tanh()
self.l2 = nn.Linear(300,1)
def forward(self, X):
z = self.l1(X)
z = self.nl(z)
o = self.l2(z)
return o
N = 1000
X = torch.rand(N,2,requires_grad=True)
y = torch.rand(N,1)
NN = Neural_Network()
criterion = torch.nn.MSELoss(reduction='sum')
optimizer = torch.optim.Adam(NN.parameters(), lr=1e-5)
epochs = 200
for i in range(epochs): # trains the NN 1,000 times
HH = torch.mean(NN(X))
gradH = torch.autograd.grad(HH, X)[0]
XH= torch.cat((gradH[:,1].unsqueeze(0),-gradH[:,0].unsqueeze(0)),dim=0).t()
pred = X + dt*XH
#Optimize and improve the weights
loss = criterion(pred, y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
print (" Loss: ", loss.detach().numpy()) # mean sum squared loss
PS 有了這些 X 和 y,預計 go 的損失不會為零,為了簡單起見,我在這里像它們一樣添加了它們。 我將把這個架構應用到預期滿足這個 model 的數據點上。 但是,我只是對看到損失減少感興趣。
我的目標是用神經網絡近似一個向量場的哈密頓量,其中只有一些軌跡是已知的。 例如,僅針對某些點的選擇更新x(t)\rightarrow x(t+\Delta t)
。 所以向量X
包含點x(t)
,而y
包含 $x(t+\Delta t)$。 我上面的網絡以簡單的方式近似於哈密頓量 function H(x)
,為了優化它,我需要找到與這個哈密頓量相關的軌跡。
特別是XH
旨在成為與近似哈密頓量相關的哈密頓矢量場。 時間更新pred = X + dt*XH
只是向前歐拉的一步。
但是,我在這里的主要問題可以抽象為:如何在損失 function 中涉及網絡相對於其輸入的梯度?
可能是因為NN
的梯度流圖被gradH
步驟破壞了。 (檢查HH.grad_fn
與gradH.grad_fn
)
因此,您的pred
張量(以及隨后的損失)不包含通過NN
網絡的必要梯度流。
loss
包含輸入X
的梯度流,但不包含NN.parameters()
。 因為優化器只對那些NN.parameters()
采取step()
() ,所以網絡NN
沒有被更新,並且由於X
沒有被更新,損失不會改變。
您可以通過在loss.backward()
之后檢查loss.grad_fn
來檢查損失如何向后發送它的梯度,這是一個整潔的 function (在 Stackoverflow 上找到)來檢查它:
def getBack(var_grad_fn):
print(var_grad_fn)
for n in var_grad_fn.next_functions:
if n[0]:
try:
tensor = getattr(n[0], 'variable')
print(n[0])
print('Tensor with grad found:', tensor)
print(' - gradient:', tensor.grad)
print()
except AttributeError as e:
getBack(n[0])
在getBack(loss.grad_fn)
loss.backward()
檢查它(雖然之前可能會減少批次 N 的大小)
編輯:它通過改變gradH = torch.autograd.grad(HH, X, create_graph=True)[0]
來工作
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.