protected virtual double[] InitializeWeights(IPerceptronProblem problem, Random r)
 {
     double[] weights = new double[problem.Dimensions + 1];
     for (int index = 0; index < weights.Length; index++)
     {
         weights[index] = r.NextDouble();
     }
     return(weights);
 }
        protected override double[] InitializeWeights(IPerceptronProblem problem, Random r)
        {
            var originalweights = base.InitializeWeights(problem, r);

            _optimalWeights = new double[originalweights.Length];
            for (int i = 0; i < originalweights.Length; i++)
            {
                _optimalWeights[i] = originalweights[i];
            }

            return(originalweights);
        }
        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));
        }
Example #4
0
 public abstract IList <ScatterInfo> SolveProblem(IPerceptronProblem problem);
Example #5
0
        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")
                })
            });
        }
 public PerceptronProblemPair(IPerceptron perceptron, IPerceptronProblem problem)
 {
     Perceptron = perceptron;
     Problem    = problem;
 }