Neural network 为什么我的神经网络在第一个时代之后仍停留在高损失值

Neural network 为什么我的神经网络在第一个时代之后仍停留在高损失值,neural-network,deep-learning,regression,pytorch,skorch,Neural Network,Deep Learning,Regression,Pytorch,Skorch,我在用神经网络做回归。对于NN来说,这应该是一个简单的任务,我有10个特性和1个输出,我想预测。我在我的项目中使用pytorch,但我的模型学习不好。损失从一个非常高的值(40000)开始,然后在最初的5-10个时期之后,损失迅速减少到6000-7000,然后它一直停留在那里,无论我做什么。我甚至尝试改为skorch而不是pytorch,这样我就可以使用交叉验证功能,但这也没有帮助。我尝试了不同的优化器,并向网络中添加了层和神经元,但这没有帮助,它停留在6000,这是一个非常高的损失值。我在这里

我在用神经网络做回归。对于NN来说,这应该是一个简单的任务,我有10个特性和1个输出,我想预测。我在我的项目中使用pytorch,但我的模型学习不好。损失从一个非常高的值(40000)开始,然后在最初的5-10个时期之后,损失迅速减少到6000-7000,然后它一直停留在那里,无论我做什么。我甚至尝试改为skorch而不是pytorch,这样我就可以使用交叉验证功能,但这也没有帮助。我尝试了不同的优化器,并向网络中添加了层和神经元,但这没有帮助,它停留在6000,这是一个非常高的损失值。我在这里做回归,我有10个特征,我试图预测一个连续值。这应该很容易做到,这就是为什么我更困惑的原因

这是我的网络: 我在这里尝试了所有的可能性,从创建更复杂的体系结构,如添加层和单元到批量标准化、更改激活等。。什么都没用

class BearingNetwork(nn.Module):
    def __init__(self, n_features=X.shape[1], n_out=1):
        super().__init__()
        self.model = nn.Sequential(

            nn.Linear(n_features, 512), 
            nn.BatchNorm1d(512),
            nn.LeakyReLU(),
            nn.Linear(512, 64),
            nn.BatchNorm1d(64),
            nn.LeakyReLU(),
            nn.Linear(64, n_out),
#             nn.LeakyReLU(),
#             nn.Linear(256, 128),
#             nn.LeakyReLU(),
#             nn.Linear(128, 64),
#             nn.LeakyReLU(),
#             nn.Linear(64, n_out)
        )

    def forward(self, x):
        out = self.model(x)
        return out
以下是我的设置: 使用skorch比pytorch更容易。在这里,我还监视R2指标,并且我将RMSE作为一个自定义指标来监视我的模型的性能。我也为亚当试过阿姆斯格勒,但没用

R2 = EpochScoring(r2_score, lower_is_better=False, name='R2')
explained_var_score = EpochScoring(EVS, lower_is_better=False, name='EVS Metric')
custom_score = make_scorer(RMSE)
rmse = EpochScoring(custom_score, lower_is_better=True, name='rmse')

bearing_nn = NeuralNetRegressor(

    BearingNetwork,
    criterion=nn.MSELoss,
    optimizer=optim.Adam,
    optimizer__amsgrad=True,
    max_epochs=5000,
    batch_size=128,
    lr=0.001,
    train_split=skorch.dataset.CVSplit(10),
    callbacks=[R2, explained_var_score, rmse, Checkpoint(), EarlyStopping(patience=100)],
    device=device

)
我还将输入值标准化

我的输入具有以下形状:

torch.Size([39006, 10])
输出的形状为:

torch.Size([39006, 1])
我使用128作为批处理大小,但我也尝试了其他值,如32、64、512甚至1024。虽然没有必要对输出进行规范化,但我也尝试过,而且在预测值时,它不起作用,损失很高。请有人在这方面帮助我,我将感谢每一个有用的建议。我还将添加我的培训和val损失的屏幕截图,以及各个时期的指标,以可视化损失在前5个时期是如何减少的,然后它将永远保持在6000,这是一个非常高的损失值


考虑到您的培训和开发人员损失随着时间的推移而减少,您的模型似乎正在正确地进行培训。关于您对培训和开发损失值的担忧,这完全取决于目标值的规模(目标值有多大?)以及用于计算培训和开发损失的指标。如果您的目标值较大,并且您想要较小的train和dev损耗值,则可以将目标值标准化


从我收集到的关于你的实验以及你的R2分数的信息来看,你似乎在错误的领域寻找解决方案。在我看来,考虑到R2分数较低,您的功能似乎不够强大,这可能意味着您存在数据质量问题。这也解释了为什么架构优化没有改善模型的性能,因为问题不在于模型。因此,如果我是你,我会考虑我可以添加哪些新的有用功能,看看这是否有帮助。在机器学习中,一般规则是,模型的好坏取决于它们所训练的数据。我希望这有帮助

您应该查看的度量是R^2,而不是损失函数的大小。损失函数的目的只是让优化器知道它是否朝着正确的方向发展——它不是一种适合的度量,在不同的数据集和学习设置中是可比较的。这就是R^2的作用

你的R^2分数表明你解释了输出中总方差的三分之一左右,对于只有10个特征的数据集来说,这通常是一个非常好的结果。实际上,考虑到数据的形状,隐藏层很可能比需要的要大得多,并且存在过度拟合的风险

要真正评估该模型,您需要知道(1)R^2分数与OLS等更简单的回归方法相比如何,(2)为什么您应该对输入变量捕获30%以上的输出方差有信心


对于#1,至少R^2不应该更糟。关于α2,考虑典型的数字分类例子。我们知道,识别数字所需的所有信息都非常准确(即R^2接近1),因为人类可以做到这一点。其他数据集不一定如此,因为有一些重要的方差来源没有被记录在源数据中。

随着损失从40000减少到6000,这意味着你的NN模型已经了解了普遍的关系,但不是所有的关系。您可以通过转换预测变量,然后将它们作为派生变量输入到您的模型中,来帮助学习,看看这是否有帮助。您可以尝试通过先添加最有影响力的预测值,逐步向NN模型添加功能。在每次迭代中,评估模型性能(即培训损失)


如果第一步不起作用,并且您对其他方法持开放态度,假定数据的动态性,高斯过程回归或分位数回归应该会有所帮助,因为这些方法不受线性回归技术等假设的影响。此外,它还应有助于探索自变量和因变量之间关系的不同方面。

列车和开发人员的损失正在减少,但当他们达到6000时,即使在5000个时代之后,他们仍然停留在那里,当他们改善时,速度非常缓慢。标准化的目标是没有必要的,我会得到相同的损失值,但在其他规模。那将毫无改善!我的R2分数很低,因为我的模型没有拟合数据,也许你是对的,我的数据没有很强的相关性,但据我所知,神经网络也可以拟合如此复杂的非线性,还是我错了?我不能添加功能,这是我在这个项目中拥有的唯一数据集,我必须接受它。你是对的,标准化不会改善你的模型。但这不是我提出来的原因。我提到这一点是因为你多次表示你的训练损失很高。