关于matlab:神经网络在测试数据上只能得到50%的好预测

Neural network gets only 50% good prediction on test data

我创建了一个神经网络,我想将输入数据(每个输入数据 400 个特征)分类为五种阿拉伯语方言之一。我使用 net.divideFcn = 'dividerand'; 深入研究了"训练数据"、"验证数据"和"测试日期"中的训练数据。我使用 trainbr 作为训练函数,这导致训练时间很长,这是因为我在训练数据中有 9000 个元素。
对于网络架构,我使用了两层,第一层有 10 个感知器,第二层有 5、5 个,因为我使用的是 one vs all 策略。
网络训练通常以达到最小梯度结束,而不是 minimux 误差。

我怎样才能让网络预测得更好?泛化是否有问题(网络对训练数据学习得很好,但对新数据的测试往往会失败?
我应该在第一层添加更多感知器吗?我这样问是因为当我在第一层有 10 个感知器时,我需要大约一个小时来训练网络,所以时间会增加。

这是我的网络的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[Test] = load('testData.mat');
[Ex] = load('trainData.mat');

Ex.trainVectors = Ex.trainVectors';
Ex.trainLabels = Ex.trainLabels';

net = newff(minmax(Ex.trainVectors),[10 5] ,{'logsig','logsig'},'trainlm','learngdm','sse');
net.performFcn = 'mse';
net.trainParam.lr = 0.01;
net.trainParam.mc = 0.95;
net.trainParam.epochs = 1000;
net.trainParam.goal = 0;
net.trainParam.max_fail = 50;

net.trainFcn = 'trainbr';  

net.divideFcn = 'dividerand';
net.divideParam.trainRatio = 0.7;
net.divideParam.valRatio = 0.15;
net.divideParam.testRatio = 0.15;

net = init(net);

net = train(net,Ex.trainVectors,Ex.trainLabels);

谢谢!


使用神经网络是一种创造性的工作。所以没有人能给你唯一真实的答案。但是我可以根据自己的经验给出一些建议。

  • 首先 - 在训练结束时检查网络错误(在训练和验证数据集上。在开始使用测试数据集之前)。你说它是最小值,但它的实际值是多少?如果它也是 50%,那么我们有错误的数据或错误的网络架构。
  • 如果训练数据集的错误是可以的。下一步 - 让我们检查您的网络系数在验证步骤中有多少变化。这里的错误是怎么回事。如果它们发生了巨大变化,那么我们的架构就错了:网络没有泛化能力,并且会在每个新数据集上重新训练。
  • 在改变架构之前我们还能做什么?我们可以改变 epoch 的数量。有时我们可以获得很好的结果,但它是某种类型的随机 - 我们必须确保在训练的最后步骤中系数的变化很小。但是我记得 nntool 会自动检查它,所以也许我们可以跳过这一步。
  • 我想向您推荐的另一件事-更改火车数据集。也许你知道 rand 在 matlab 开始时总是给你相同的数字,所以如果你只创建一次数据集,你就可以总是使用相同的数据集。这个问题也与非同质数据有关。您的数据的某些部分可能比其他部分更重要。因此,如果一些不同的随机集会给出大约相同的错误数据是可以的,我们可以走得更远。如果不是 - 我们需要处理数据并更仔细地拆分它。有时我避免使用 dividerand 并手动划分数据。
  • 有时我试图改变激活函数的类型。但是在这里你使用感知器......所以这个想法 - 尝试使用 sigma 或线性神经元而不是感知器。这很少会导致显着的改进,但可以提供帮助。
  • 如果所有这些步骤都不能给你足够的,你必须改变网络架构。而第一层的神经元数量是你首先要做的。通常,当我研究神经网络时,我会花很多时间尝试不仅不同数量的神经元,而且还要尝试不同类型的网络。
    例如,我发现了关于您的主题的有趣文章:Alberto Sim?es 文章的链接。这就是他们所说的:
  • Regarding the number of units in the hidden layers, there are some
    rules of thumb: use the same number of units in all hidden layers, and
    use at least the same number of units as the maximum between the
    number of classes and the number of features. But there can be up to
    three times that value. Given the high number of features we opted to
    keep that same number of units in the hidden layer.

    评论中的一些建议:
    数据拆分方法(用于训练和测试数据集)取决于您的数据。例如,我处理行业数据,发现数据集的最后一部分技术参数(某些设备的压力)发生了变化。所以我必须获取两种操作模式的数据来训练数据集。但是对于您的情况,我不认为存在相同的问题...我建议您尝试几个随机集(只需检查它们是否真的不同!)。

    为了测量净误差,我通常会计算完整的误差向量 - 我训练网络,然后检查它是否适用于所有值以获得整个误差向量。获得一些有用的视图(如直方图等)很有用,我可以看到我的网络哪里出错了。使 sse(或 mse)接近于零是没有必要的,甚至是有害的——通常这意味着你已经过度训练了网络。对于第一个近似值,我通常尝试在训练数据集上获得 80-95% 的正确值,然后在测试数据集上尝试网络。