我正在尝试使用 PyTorch 中的 ANN 来预测运动中燃烧的卡路里数
数据集可以在这里找到:https://www.kaggle.com/datasets/fmendes/fmendesdat263xdemos
我的问题是,我的模型输出的预测对于每一行都是相同的(我已在这篇文章中附加了图像)。我尝试过改变模型的学习率,看看这是否有帮助,但没有。我也尝试询问 ChatGPT 但它没有给我任何真正的解决方案。
这是我迄今为止使用过的代码:
import numpy as np
import pandas as pd
import torch
import torch.nn as nn
calories = pd.read_csv("calories.csv")
excercise = pd.read_csv("exercise.csv")
df = pd.concat(\[excercise,calories\],axis=1,join="outer")
df = df.drop('User_ID',axis=1)
df.head()
data = pd.get_dummies(df,drop_first=True)
X = torch.tensor(np.array(data.drop("Calories",axis=1))).float()
y = torch.tensor(data\['Calories'\],dtype=torch.float).reshape(-1,1)
class Ann_Predictor(nn.Module):
def __init__(self, n_layers, n_units):
super().__init__()
self.n_layers = n_layers
self.layers = nn.ModuleDict()
self.layers["input"] = nn.Linear(7,n_units)
for i in range(n_layers):
self.layers[f"hidden{i}"] = nn.Linear(n_units,n_units)
self.layers["output"] = nn.Linear(n_units,1)
def forward(self, x):
# forward pass
x = self.layers['input'](x)
for i in range(self.n_layers):
x = F.relu(self.layers[f"hidden{i}"](x))
x = self.layers["output"](x)
return x
def create_model():
ann = Ann_Predictor(3,8)
loss_func = nn.MSELoss()
learning_rate = 0.005
optimizer = torch.optim.SGD(ann.parameters(),lr=learning_rate)
return ann, loss_func, optimizer
numepochs = 500
losses = torch.zeros(numepochs)
ann, loss_func, optimizer = create_model()
for epoch in range(numepochs):
y_hat = ann(X)
loss = loss_func(y_hat, y)
losses\[epoch\] = loss
optimizer.zero_grad()
loss.backward()
optimizer.step()
# Predicting Using Model
predictions = ann(X)
print(predictions)
如前所述,我尝试过改变学习率并询问 ChatGPT,但没有找到问题的解决方案。
我面临着类似的问题,对我来说,将批量大小从 256 增加到 2048 避免了这个错误,所以我也相信这可能与超参数调整有关,并且像上面提到的那样尝试标准化。每个模型都取决于数据。
由于无论您向网络提供什么输入,您都会获得相同的输出,因此网络似乎已经学习了一个恒定值,该恒定值可以最小化所有输入的损失函数。换句话说,网络还没有“学到”任何东西。如果您还可以绘制损失曲线,那就很有用了。
此外,从您共享的代码片段和查看数据集来看,您似乎只是在对原始输入数据进行训练,而没有进行任何形式的预处理。您的网络现在接受 7 维输入,其原始值是不同的单位、范围等(例如,年龄和身高具有完全不同的值范围)。训练这样的神经网络将是非常困难的。您可以从将所有输入值标准化/标准化开始,使其处于公共范围内,例如。 [0,1] 或 [-1,1]。
使用 CNN 进行回归问题时遇到类似问题。它在 Keras 中有效,但在 Torch 中无效。遵循其他建议,例如学习率、批量大小、标准化等。
原来 Torch 默认使用 Lecun 初始化。 对于relu,最好使用Kaiming He初始化,它为我解决了问题。
self.conv1 = nn.Conv3d(in_channels, out_channels, kernel_size=kernel_size, padding=padding)
nn.init.kaiming_normal_(self.conv1.weight)
另请参阅: https://adityassrana.github.io/blog/theory/2020/08/26/Weight-Init.html