public void Train(IReadOnlyList <TrainingDataSet> trainingDataSets, double learningRate, double learningDataPercentage) { if (learningDataPercentage > 1 || learningDataPercentage < 0) { throw new ArgumentException("Percentage of training data must be a value between 0 and 1.", nameof(learningDataPercentage)); } foreach (var dataSet in trainingDataSets) { if (dataSet.Inputs.Length != InputLayer.Neurons.Length) { throw new ArgumentException($"Data set's number of input values ({dataSet.Inputs.Length}) does not match size of input layer ({InputLayer.Neurons.Length})", nameof(trainingDataSets)); } if (dataSet.Outputs.Length != OutputLayer.Neurons.Length) { throw new ArgumentException($"Data set's number of output values ({dataSet.Outputs.Length}) does not match size of output layer ({OutputLayer.Neurons.Length})", nameof(trainingDataSets)); } } var learningDataCount = (int)Math.Floor(trainingDataSets.Count * learningDataPercentage); for (int i = 0; i < learningDataCount; i++) { InputLayer.InsertValues(trainingDataSets[i].Inputs); HiddenLayer.Compute(); OutputLayer.Compute(); OutputLayer.ComputeDelta(trainingDataSets[i].Outputs); HiddenLayer.ComputeDelta(); InputLayer.ComputeDelta(); HiddenLayer.UpdateWeights(learningRate); OutputLayer.UpdateWeights(learningRate); } var total = 0d; for (int i = learningDataCount; i < trainingDataSets.Count; i++) { var outcome = Predict(trainingDataSets[i].Inputs); for (int j = 0; j < outcome.Length; j++) { total += Math.Abs(trainingDataSets[i].Outputs[j] + outcome[j]) / 2; } } Accuracy = total / ((trainingDataSets.Count - learningDataCount) * OutputLayer.Neurons.Length); }