/// <summary> /// Works correctly for approximation with single value output. /// Otherwise will just take first value from network output as function value. /// </summary> /// <param name="network"></param> private void CreateApproximationFunctionPoints(NeuralNetwork network) { ApproximationFunctionPoints = new Double[NumberOfPointForApproximationFunction, 2]; double maximum = 0, minimum = 0; foreach (var data in DataProvider.DataSet) // choose max and min { if (data.X.Max() > maximum) { maximum = data.X.Max(); } if (data.X.Min() < minimum) { minimum = data.X.Min(); } } double step = (maximum - minimum) / NumberOfPointForApproximationFunction; double xValue = minimum; var output = Vector <double> .Build.Dense(1); for (int index = 0; index < NumberOfPointForApproximationFunction; index++) { if (network.IsBiasExisting) { output = network.CalculateOutput(Vector <double> .Build.Dense(new double[2] { 1, xValue })); } else { output = network.CalculateOutput(Vector <double> .Build.Dense(new double[1] { xValue })); } ApproximationFunctionPoints[index, 0] = xValue; ApproximationFunctionPoints[index, 1] = output[0]; //Assumed approximation will have only single output xValue += step; } }
private void CreateResultMatrixForClassification(NeuralNetwork network) { var testSet = DataProvider.DataSet; //helper variable to shorten code and clarify; int numberOfClasses = network.Layers[Layers.Length - 1].Weights.ColumnCount; //neurons in last layer ClassificationFullResults = Matrix <double> .Build.Dense(numberOfClasses, numberOfClasses); for (int dataIndex = 0; dataIndex < testSet.Length; dataIndex++) { var output = network.CalculateOutput(testSet[dataIndex].X, CalculateMode.NetworkOutput); int chosenClassNumber = output.MaximumIndex(); int properClassNumber = testSet[dataIndex].D.MaximumIndex(); ClassificationFullResults[properClassNumber, chosenClassNumber] += 1; } }
/// <summary> /// Uses network on every data from test set and uses error calc to calc aggregated error /// </summary> /// <param name="network"></param> /// <returns></returns> public double TestNetwork(NeuralNetwork network, IDataProvider dataProvider) { var testSet = dataProvider.DataSet; //var to clarify and shorten var errors = Vector <double> .Build.Dense(testSet.Length, 0); Vector <double> currentOutput; for (int dataIndex = 0; dataIndex < testSet.Length; dataIndex++) { currentOutput = network.CalculateOutput(testSet[dataIndex].X); errors[dataIndex] = ErrorCalculator.CalculateErrorSum(currentOutput, testSet[dataIndex].D); } var totalError = ErrorCalculator.CalculateEpochError(errors); return(totalError); }
public void TrainNetwork(ref NeuralNetwork networkToTrain, int maxEpochs, double desiredErrorRate = 0) { var learnSet = DataProvider.LearnSet; //shorter var TempTestErrorHistory = Vector <double> .Build.Dense(maxEpochs + 1); Vector <double> TemporaryEpochErrorHistory = Vector <double> .Build.Dense(maxEpochs, 0); //place to temporary store epoch errors for all epochs TempTestErrorHistory[0] = Double.MaxValue; // assume error at beginning is maximal TemporaryEpochErrorHistory[0] = Double.MaxValue; // assume error at beginning is maximal int shuffleAmount = (int)Math.Round(Math.Log(learnSet.Length, 2)); // calculate how much should shuffle learn set depending on its size Vector <double> output; Vector <double> errorVector; int EpochIndex = 1; // epochs are counted starting from 1 while (EpochIndex < maxEpochs) { DataProvider.ShuffleDataSet(learnSet, shuffleAmount); // shuffle some data in learn set CurrentEpochErrorVector = Vector <double> .Build.Dense(learnSet.Length, 0); // init with 0s #region calculate epoch for (int dataIndex = 0; dataIndex < learnSet.Length; dataIndex++) { output = networkToTrain.CalculateOutput(learnSet[dataIndex].X, CalculateMode.OutputsAndDerivatives); errorVector = ErrorCalculator.CalculateErrorVector(output, learnSet[dataIndex].D); CurrentEpochErrorVector[dataIndex] = ErrorCalculator.CalculateErrorSum(output, learnSet[dataIndex].D); #region adapt weights LearningAlgorithm.AdaptWeights(networkToTrain, errorVector, CurrentEpochErrorVector[dataIndex], CurrentEpochErrorVector[dataIndex.Previous()]); #endregion } #endregion #region epoch error TemporaryEpochErrorHistory[EpochIndex] = ErrorCalculator.CalculateEpochError(CurrentEpochErrorVector); if (TemporaryEpochErrorHistory[EpochIndex] <= desiredErrorRate) //learning is done { return; } #endregion #region Adapt Learning Rate LearningAlgorithm.AdaptLearningRate(TemporaryEpochErrorHistory[EpochIndex], TemporaryEpochErrorHistory[EpochIndex.Previous()]); #endregion #region create and store test results var testError = tester.TestNetwork(networkToTrain, DataProvider); TempTestErrorHistory[EpochIndex] = testError; #endregion #region update best network state if (TempTestErrorHistory[EpochIndex] < BestError) { BestNetworkState = networkToTrain.DeepCopy(); BestError = TempTestErrorHistory[EpochIndex]; } #endregion EpochIndex++; } #region save errors for all epochs that actually were calculated TestErrorHistory = Vector <double> .Build.Dense(EpochIndex); EpochErrorHistory = Vector <double> .Build.Dense(EpochIndex); TemporaryEpochErrorHistory.CopySubVectorTo(EpochErrorHistory, 0, 0, EpochIndex); TempTestErrorHistory.CopySubVectorTo(TestErrorHistory, 0, 0, EpochIndex); #endregion //restore best network state ( on set for verifying) networkToTrain = BestNetworkState; }