神经网络只能对测试数据做出 50% 的正确预测
Neural network gets only 50% good prediction on test data
我制作了一个神经网络,我想将输入数据(每个输入数据 400 个特征)分类为五种阿拉伯方言之一。我在 "train data"、"validation data" 和 "test date" 中使用 net.divideFcn = 'dividerand';
潜水训练数据。我使用 trainbr
作为训练函数,这导致了长时间的训练,那是因为我在训练数据中有 9000 个元素。
对于网络架构,我使用了两层,第一层有 10 个感知器,第二层有 5 个,5 个是因为我使用的是 one vs all 策略。
网络训练通常以达到最小梯度结束,而不是 minimux 错误。
我怎样才能让网络预测得更好?可能是泛化问题(网络很好地学习了训练数据,但对新数据的测试往往会失败?
我应该在第一层添加更多感知器吗?我问这个是因为当我在第一层有 10 个感知器时我需要大约一个小时来训练网络,所以时间会增加。
这是我的网络的代码:
[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
并手动划分数据。
- 有时我试图改变激活函数的类型。但是在这里你使用感知器......所以这个想法 - 尝试使用西格玛或线性神经元而不是感知器。这很少会带来重大改进,但会有所帮助。
- 如果所有这些步骤都不能满足您的需求,您必须更改网络架构。而第一层的神经元数量是你首先要做的。通常当我在神经网络上工作时,我不仅会花很多时间尝试不同数量的神经元,还会尝试不同类型的网络。
例如,我发现关于您的主题 文章 很有趣:link at Alberto Simões article。他们就是这么说的:
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% 的正确值,然后在测试数据集上尝试网络。
我制作了一个神经网络,我想将输入数据(每个输入数据 400 个特征)分类为五种阿拉伯方言之一。我在 "train data"、"validation data" 和 "test date" 中使用 net.divideFcn = 'dividerand';
潜水训练数据。我使用 trainbr
作为训练函数,这导致了长时间的训练,那是因为我在训练数据中有 9000 个元素。
对于网络架构,我使用了两层,第一层有 10 个感知器,第二层有 5 个,5 个是因为我使用的是 one vs all 策略。
网络训练通常以达到最小梯度结束,而不是 minimux 错误。
我怎样才能让网络预测得更好?可能是泛化问题(网络很好地学习了训练数据,但对新数据的测试往往会失败? 我应该在第一层添加更多感知器吗?我问这个是因为当我在第一层有 10 个感知器时我需要大约一个小时来训练网络,所以时间会增加。
这是我的网络的代码:
[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
并手动划分数据。 - 有时我试图改变激活函数的类型。但是在这里你使用感知器......所以这个想法 - 尝试使用西格玛或线性神经元而不是感知器。这很少会带来重大改进,但会有所帮助。
- 如果所有这些步骤都不能满足您的需求,您必须更改网络架构。而第一层的神经元数量是你首先要做的。通常当我在神经网络上工作时,我不仅会花很多时间尝试不同数量的神经元,还会尝试不同类型的网络。 例如,我发现关于您的主题 文章 很有趣:link at Alberto Simões article。他们就是这么说的:
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% 的正确值,然后在测试数据集上尝试网络。