为未遇到的输入创建神经网络
Creating Neural Network for un-encountered inputs
我正在使用 AForge.net NN 库创建一个简单的多层前馈神经网络。我的 NN 是一个 3 层激活网络,通过使用反向传播学习算法的监督学习方法进行训练。
以下是我的初始设置:
//learning rate
learningRate=0.1;
//momentum value
momentum=0;
//alpha value for bipolar sigmoid activation function
sigmoidAlphaValue=2.0;
//number of inputs to network
inputSize=5;
//number of outputs from network
predictionSize=1;
//iterations
iterations=10000;
// create multi-layer neural network
ActivationNetwork network = new ActivationNetwork(new BipolarSigmoidFunction
(sigmoidAlphaValue), 5, 5 + 1, 3, 1);
//5 inputs
//6 neurons in input layer
//3 neurons in hidden layer
//1 neuron in output layer
// create teacher
BackPropagationLearning teacher = new BackPropagationLearning(network);
// set learning rate and momentum
teacher.LearningRate = learningRate;
teacher.Momentum = momentum;
现在我有一些看起来像这样的输入系列,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20
使用window滑动方法(如here所述)作为时间序列输入,我的输入和
预期的输出数组看起来像这样
//Iteration #1
double input[][] = new input[0][5] {1,2,3,4,5};
double output[][] = new output[0][0] {6};
//Iteration #2
double input[][] = new input[1][5] {2,3,4,5,6};
double output[][] = new output[1][0] {7};
//Iteration #3
double input[][] = new input[2][5] {3,4,5,6,7};
double output[][] = new output[2][0] {8};
.
.
.
//Iteration #n
double input[][] = new input[n][5] {15,16,17,18,19};
double output[][] = new output[n][0] {20};
经过 10k 次迭代后使用
teacher.RunEpoch(input, output);
我的网络已针对给定的训练集成功训练。所以现在,如果我使用输入作为 4、5、6、7、8 进行计算,网络会成功给出 9 作为答案太棒了!
但是,当输入为 21,22,23,24,25 时,NN 无法生成 26!
我的问题:
我如何训练我的网络接受这种未遇到的这种方式的输入,以产生在学习过程中训练集中发现的正确序列模式?
正如@runDOSrun 所说,您的模型似乎过度拟合(训练)数据。为避免此问题,您可以将集合(时间序列)分成 3 个部分。
训练集
第一个可能是训练网络的训练集。
验证集
第二个是验证集,对于训练的每个时期,您在验证集上测试神经网络并获取错误并将此错误存储在变量和神经网络副本(克隆)中.在下一个时期,您必须测试(修改后的)神经网络,如果验证集上的新错误低于您测试的最后一个错误,您将存储一个新的 "validation neural network"。它将为您提供一个神经网络,该网络可以在不是训练集的集合中更好地概括。因此,您可以避免过度拟合训练集。
训练结束时,您有两个神经网络。 训练神经网络是最好的训练集神经网络和验证神经网络,可以为您提供泛化更好的神经网络超出训练集。
测试集
最后一部分,您只需在未见过的集合中测试您的模型并检查错误。测试集的建议是检查神经网络在看不见的测试中的行为。真正的考验。
一般来说,您可以将整个集合分成 3 个相等的部分,或者对于示例
- 60% 用于培训
- 20% 用于验证
- 20% 用于测试
示例,请看下图:
伪代码示例 其实现方式:
int epochs = 1;
double error = 0;
double validationError = 10000;
object validationNetwork;
do
{
// train your network
error = getError(trainingSet);
//validation part...
var currentValidationError = getError(validationSet);
if (currentValidationError < validationError)
{
validationError = currentValidationError;
validationNeuralNetwork = neuralNetwork.Clone();
}
} while (epochs < 2000 && error < 0.001);
时间序列的交叉验证
另一方面,您也可以尝试对时间序列进行交叉验证。首先,您将集合分成 6 个部分(或更多)并训练神经网络来验证模型,如下所示:
- 1:训练 [1]、验证 [2]、测试 [3]
- 2:训练 [2]、验证 [3]、测试 [4]
- 3 : 训练 [3], 验证 [4], 测试 [5]
- 4 : 训练 [4], 验证 [5], 测试 [6]
如果你愿意,你可以分成更多的部分。
我正在使用 AForge.net NN 库创建一个简单的多层前馈神经网络。我的 NN 是一个 3 层激活网络,通过使用反向传播学习算法的监督学习方法进行训练。
以下是我的初始设置:
//learning rate
learningRate=0.1;
//momentum value
momentum=0;
//alpha value for bipolar sigmoid activation function
sigmoidAlphaValue=2.0;
//number of inputs to network
inputSize=5;
//number of outputs from network
predictionSize=1;
//iterations
iterations=10000;
// create multi-layer neural network
ActivationNetwork network = new ActivationNetwork(new BipolarSigmoidFunction
(sigmoidAlphaValue), 5, 5 + 1, 3, 1);
//5 inputs
//6 neurons in input layer
//3 neurons in hidden layer
//1 neuron in output layer
// create teacher
BackPropagationLearning teacher = new BackPropagationLearning(network);
// set learning rate and momentum
teacher.LearningRate = learningRate;
teacher.Momentum = momentum;
现在我有一些看起来像这样的输入系列, 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20
使用window滑动方法(如here所述)作为时间序列输入,我的输入和
预期的输出数组看起来像这样
//Iteration #1
double input[][] = new input[0][5] {1,2,3,4,5};
double output[][] = new output[0][0] {6};
//Iteration #2
double input[][] = new input[1][5] {2,3,4,5,6};
double output[][] = new output[1][0] {7};
//Iteration #3
double input[][] = new input[2][5] {3,4,5,6,7};
double output[][] = new output[2][0] {8};
.
.
.
//Iteration #n
double input[][] = new input[n][5] {15,16,17,18,19};
double output[][] = new output[n][0] {20};
经过 10k 次迭代后使用
teacher.RunEpoch(input, output);
我的网络已针对给定的训练集成功训练。所以现在,如果我使用输入作为 4、5、6、7、8 进行计算,网络会成功给出 9 作为答案太棒了!
但是,当输入为 21,22,23,24,25 时,NN 无法生成 26!
我的问题: 我如何训练我的网络接受这种未遇到的这种方式的输入,以产生在学习过程中训练集中发现的正确序列模式?
正如@runDOSrun 所说,您的模型似乎过度拟合(训练)数据。为避免此问题,您可以将集合(时间序列)分成 3 个部分。
训练集
第一个可能是训练网络的训练集。
验证集
第二个是验证集,对于训练的每个时期,您在验证集上测试神经网络并获取错误并将此错误存储在变量和神经网络副本(克隆)中.在下一个时期,您必须测试(修改后的)神经网络,如果验证集上的新错误低于您测试的最后一个错误,您将存储一个新的 "validation neural network"。它将为您提供一个神经网络,该网络可以在不是训练集的集合中更好地概括。因此,您可以避免过度拟合训练集。
训练结束时,您有两个神经网络。 训练神经网络是最好的训练集神经网络和验证神经网络,可以为您提供泛化更好的神经网络超出训练集。
测试集
最后一部分,您只需在未见过的集合中测试您的模型并检查错误。测试集的建议是检查神经网络在看不见的测试中的行为。真正的考验。
一般来说,您可以将整个集合分成 3 个相等的部分,或者对于示例
- 60% 用于培训
- 20% 用于验证
- 20% 用于测试
示例,请看下图:
伪代码示例 其实现方式:
int epochs = 1;
double error = 0;
double validationError = 10000;
object validationNetwork;
do
{
// train your network
error = getError(trainingSet);
//validation part...
var currentValidationError = getError(validationSet);
if (currentValidationError < validationError)
{
validationError = currentValidationError;
validationNeuralNetwork = neuralNetwork.Clone();
}
} while (epochs < 2000 && error < 0.001);
时间序列的交叉验证
另一方面,您也可以尝试对时间序列进行交叉验证。首先,您将集合分成 6 个部分(或更多)并训练神经网络来验证模型,如下所示:
- 1:训练 [1]、验证 [2]、测试 [3]
- 2:训练 [2]、验证 [3]、测试 [4]
- 3 : 训练 [3], 验证 [4], 测试 [5]
- 4 : 训练 [4], 验证 [5], 测试 [6]
如果你愿意,你可以分成更多的部分。