Python 损失值不会减少
我正在用Pytork实现一个简单的前馈神经网络,损失函数似乎没有减少。由于我做了一些其他测试,问题似乎在于我计算pred的计算,因为如果我稍微改变网络,使它为每个条目吐出一个二维向量,并将其保存为pred,那么一切都会完美地工作 你看到这里定义pred的问题了吗?谢谢Python 损失值不会减少,python,neural-network,pytorch,loss-function,Python,Neural Network,Pytorch,Loss Function,我正在用Pytork实现一个简单的前馈神经网络,损失函数似乎没有减少。由于我做了一些其他测试,问题似乎在于我计算pred的计算,因为如果我稍微改变网络,使它为每个条目吐出一个二维向量,并将其保存为pred,那么一切都会完美地工作 你看到这里定义pred的问题了吗?谢谢 import torch import numpy as np from torch import nn dt = 0.1 class Neural_Network(nn.Module): def __init__(s
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
另外,有了这些X和y,预计损失不会为零,我在这里添加了它们,就像它们一样,只是为了简单。我将把这种体系结构应用于期望满足此模型的数据点。然而,我只想看到损失的减少
我的目标是用一个神经网络来近似向量场的哈密顿量,其中只有一些轨迹是已知的。例如,对于某些点的选择,仅更新
x(t)\rightarrow x(t+\Delta t)
。因此向量X
包含点X(t)
,而y
包含$X(t+\Delta t)$。我上面的网络以一种简单的方式近似哈密顿函数H(x)
,为了优化它,我需要找到与这个哈密顿函数相关的轨迹
特别是XH
旨在成为与近似哈密顿量相关联的哈密顿量向量场。时间更新pred=X+dt*XH
只是向前的一步
然而,我这里的主要问题可以抽象为:如何将网络相对于其输入的梯度包含在损失函数中?可能是因为
NN
的梯度流图在gradH
步骤中被破坏了。(检查HH.grad\u fn
vsgradH.grad\u fn
)
因此,你的pred
张量(以及随后的损失)不包含通过NN
网络的必要梯度流
loss
包含输入X
的梯度流,但不包含NN.parameters()
的梯度流。因为优化器只对那些NN.parameters()
执行step()
,所以网络NN
没有更新,而且X
也没有更新,所以丢失不会改变
您可以通过在loss.backward()之后检查loss.grad\fn
这里有一个简洁的函数(可以在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\u fn)
在loss.backward()之后进行检查(但之前可能会减小批次N的大小)
编辑:它的工作原理是更改gradH=torch.autograd.grad(HH,X,create\u graph=True)[0]
是的,谢谢。在这一步中,有关NN.parameters的信息似乎丢失了。你对如何解决这个问题有什么建议吗?我是PytorchI的新手,我不太确定你想用gradH做什么,所以如果你有任何材料(tf代码或方程式),也许我可以帮你。根据,我猜使用gradH=torch.autograd.grad(HH,X,create_graph=True)[0]
可以完成这个任务(取决于你想要什么)我已经添加了一个更新的问题,我解释了我想做什么,我希望这能让你帮助它现在工作@DannyBoi,非常感谢你添加create_graph=True