public override IList <ScatterInfo> SolveProblem(IPerceptronProblem problem) { _problem = problem; problem.Initialize(); Random r = new Random(); double[] weights = InitializeWeights(problem, r); List <double> trainingErrors; List <double> testErrors; Train(weights, problem.TrainingPoints, problem.TestPoints, out trainingErrors, out testErrors); return(Test(weights, problem.TestPoints, trainingErrors, testErrors)); }
public IList <ScatterInfo> SolveProblem(IPerceptronProblem problem) { problem.Initialize(); Random r = new Random(); List <Neuron> middleNeurons = new List <Neuron>(); // Neurons and initial weight for (int i = 0; i < _middleNeuronCount; i++) { double[] randomWeight = GetRandomWeight(problem.Dimensions + 1, r); middleNeurons.Add(new Neuron(randomWeight)); } List <Neuron> outputNeurons = new List <Neuron>(); for (int i = 0; i < problem.OutputDimensions; i++) { double[] randomWeight = GetRandomWeight(_middleNeuronCount + 1, r); outputNeurons.Add(new Neuron(randomWeight)); } List <double> trainingErrors = new List <double>(); List <double> testErrors = new List <double>(); for (int epoch = 0; epoch < _maxEpochs; epoch++) { // Calculate training and test error var trainingError = CalculateTotalError(problem.TrainingPoints, middleNeurons, outputNeurons); var testError = CalculateTotalError(problem.TestPoints, middleNeurons, outputNeurons); trainingErrors.Add(trainingError); testErrors.Add(testError); for (int inputIndex = 0; inputIndex < problem.TrainingPoints.Count; inputIndex++) { var middleOutput = new double[middleNeurons.Count]; for (int i = 0; i < middleNeurons.Count; i++) { middleOutput[i] = middleNeurons[i].CalculateOutput(problem.TrainingPoints[inputIndex].Input); } var output = new double[outputNeurons.Count]; for (int i = 0; i < outputNeurons.Count; i++) { output[i] = outputNeurons[i].CalculateOutput(middleOutput); } // Backward pass // First the output neurons double[] decOutErrorTotals = new double[outputNeurons.Count]; double[] decOutNets = new double[outputNeurons.Count]; for (int neuronIndex = 0; neuronIndex < outputNeurons.Count; neuronIndex++) { outputNeurons[neuronIndex].Edit(); decOutErrorTotals[neuronIndex] = -(problem.TrainingPoints[inputIndex].ExpectedOutput[neuronIndex] - output[neuronIndex]); decOutNets[neuronIndex] = output[neuronIndex] * (1 - output[neuronIndex]); for (int neuronInputIndex = 0; neuronInputIndex < middleNeurons.Count; neuronInputIndex++) { var diffw5 = middleOutput[neuronInputIndex]; var diffw5Total = decOutErrorTotals[neuronIndex] * decOutNets[neuronIndex] * diffw5; outputNeurons[neuronIndex].nextWeights[neuronInputIndex] -= diffw5Total * _learningRate; } } // Now middle neurons // Calculate total error diff double[] totalErrorForNeurons = new double[middleNeurons.Count]; for (int neuronIndex = 0; neuronIndex < middleNeurons.Count; neuronIndex++) { double totalErrorForNeuron = 0; for (int neuronInputIndex = 0; neuronInputIndex < outputNeurons.Count; neuronInputIndex++) { var weight = outputNeurons[neuronInputIndex].weights[neuronIndex]; var derErrorOutIntermedio = decOutErrorTotals[neuronInputIndex] * decOutNets[neuronInputIndex] * weight; totalErrorForNeuron += derErrorOutIntermedio; } totalErrorForNeurons[neuronIndex] = totalErrorForNeuron; } // Apply the weight fix for (int neuronIndex = 0; neuronIndex < middleNeurons.Count; neuronIndex++) { middleNeurons[neuronIndex].Edit(); for (int neuronInputIndex = 0; neuronInputIndex < problem.Dimensions; neuronInputIndex++) { double diffMidOutNet = middleOutput[neuronIndex] * (1 - middleOutput[neuronIndex]); double intermediateResult = diffMidOutNet * totalErrorForNeurons[neuronIndex] * problem.TrainingPoints[inputIndex].Input[neuronInputIndex]; middleNeurons[neuronIndex].nextWeights[neuronInputIndex] -= _learningRate * intermediateResult; } } // Commit for (int neuronIndex = 0; neuronIndex < outputNeurons.Count; neuronIndex++) { outputNeurons[neuronIndex].Commit(); } for (int neuronIndex = 0; neuronIndex < middleNeurons.Count; neuronIndex++) { middleNeurons[neuronIndex].Commit(); } //if (inputIndex % 5 == 0) //{ // Console.WriteLine(totalError); //} } } return(new List <ScatterInfo>() { new ScatterInfo($"MultilayerPerceptron {problem.Name} LearningRate {_learningRate} Epochs {_maxEpochs} IntermediateNeuronCount {_middleNeuronCount}", "TotalError", "Iteration", new List <Series>() { new Series(trainingErrors, "Training"), new Series(testErrors, "Test") }) }); }