Mis*_*ead 1 python neural-network pytorch
我正在学习如何使用 PyTorch 构建神经网络。这个公式是我代码的目标:y =2 X^3 + 7 X^2 - 8*X + 120
这是一个回归问题。
我使用它是因为它很简单,并且可以计算输出,这样我就可以确保我的神经网络能够根据给定的输入预测输出。
但是,我在训练过程中遇到了一些问题。问题出现在这行代码中:
loss = loss_func(prediction, outputs)
Run Code Online (Sandbox Code Playgroud)
在这一行中计算的损失是 NAN(不是数字)
我使用 MSEloss 作为损失函数。100 个数据集用于训练 ANN 模型。输入 X_train 的范围从 -1000 到 1000。
我认为问题出在 X_train 和 MSEloss 的值上。X_train 应该缩放到 0 到 1 之间的一些值,以便 MSEloss 可以计算损失。
但是,在回归问题中,是否可以在不将输入缩放为 0 到 1 之间的值的情况下训练 ANN 模型?
这是我的代码,它不使用 MinMaxScaler 并使用 NAN 打印损失:
import torch
import torch.nn as nn
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import torch.nn.functional as F
from torch.autograd import Variable
#Load datasets
dataset = pd.read_csv('test_100.csv')
x_temp_train = dataset.iloc[:79, :-1].values
y_temp_train = dataset.iloc[:79, -1:].values
x_temp_test = dataset.iloc[80:, :-1].values
y_temp_test = dataset.iloc[80:, -1:].values
#Turn into tensor
X_train = torch.FloatTensor(x_temp_train)
Y_train = torch.FloatTensor(y_temp_train)
X_test = torch.FloatTensor(x_temp_test)
Y_test = torch.FloatTensor(y_temp_test)
#Define a Artifical Neural Network
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.linear = nn.Linear(1,1) #input=1, output=1, bias=True
def forward(self, x):
x = self.linear(x)
return x
net = Net()
print(net)
#Define a Loss function and optimizer
optimizer = torch.optim.SGD(net.parameters(), lr=0.2)
loss_func = torch.nn.MSELoss()
#Training
inputs = Variable(X_train)
outputs = Variable(Y_train)
for i in range(100): #epoch=100
prediction = net(inputs)
loss = loss_func(prediction, outputs)
optimizer.zero_grad() #zero the parameter gradients
loss.backward() #compute gradients(dloss/dx)
optimizer.step() #updates the parameters
if i % 10 == 9: #print every 10 mini-batches
#plot and show learning process
plt.cla()
plt.scatter(X_train.data.numpy(), Y_train.data.numpy())
plt.plot(X_train.data.numpy(), prediction.data.numpy(), 'r-', lw=2)
plt.text(0.5, 0, 'Loss=%.4f' % loss.data.numpy(), fontdict={'size': 10, 'color': 'red'})
plt.pause(0.1)
plt.show()
Run Code Online (Sandbox Code Playgroud)
谢谢你的时间。
神经网络中的回归问题是否需要归一化?
不。
但...
我可以告诉你 MSELoss 使用非标准化值。你可以说是因为:
>>> import torch
>>> torch.nn.MSELoss()(torch.randn(1)-1000, torch.randn(1)+1000)
tensor(4002393.)
Run Code Online (Sandbox Code Playgroud)
MSE 是一个表现非常好的损失函数,如果NaN
不给它一个NaN
. 我敢打赌你的模型正在给出NaN
输出。
导致 a 的两个最常见原因NaN
是:意外除以 0,以及异常大的权重/梯度。
我使用以下命令在我的机器上运行了您的代码的变体:
x = torch.randn(79, 1)*1000
y = 2*x**3 + 7*x**2 - 8*x + 120
Run Code Online (Sandbox Code Playgroud)
NaN
由于非常大的权重,它需要大约 20 个训练步骤。
如果学习率太大,模型可能会获得大得离谱的权重。您可能认为0.2
它不会太大,但这是人们用于规范化数据的典型学习率,这迫使他们的梯度相当小。由于您没有使用归一化数据,让我们计算一下您的梯度有多大(大致)。
首先,您的 x 的数量级为1e3
,您的预期输出 y 缩放为x^3
,然后 MSE 计算(pred - y)^2
。那么你的损失是1e3^3^2=1e18
。这会传播到您的梯度,并回想一下权重更新是+= gradient*learning_rate
,因此很容易理解为什么您的权重在浮点精度之外很快就会爆炸。
如何解决这个问题?那么你可以使用2e-7
. 或者你可以规范化你的数据。我建议规范化您的数据;它还有其他很好的训练属性,可以避免这些问题。
归档时间: |
|
查看次数: |
1219 次 |
最近记录: |