Ejemplo n.º 1
0
        private void UpdatePopulation(object sender, EventArgs e)
        {
            double[][]      inputs                = new double[tests][];
            string[]        paths                 = new string[tests];
            double[][]      outputs               = new double[populationSize * tests][];
            NeuralNetwork[] functionPopulation    = population.Select(n => n).ToArray();
            double[][][][]  functionNeuronWeights = allNeuronWeights.Select(n => n).ToArray();
            Neuron[][][]    functionNeurons       = allNeurons.Select(n => n).ToArray();
            double[][][]    functionInputs        = allInputs.Select(n => n).ToArray();
            int[]           values                = new int[tests];
            for (int i = 0; i < tests; i++)
            {
                int place = R.Next(allDigits.Length);
                values[i] = allDigits[place].value;
                inputs[i] = allDigits[place].pixelValues;
                for (int j = 0; j < populationSize; j++)
                {
                    outputs[i * populationSize + j] = new double[10];
                }
            }
            Gpu.Default.For(0, population.Length * tests, i =>
            {
                outputs[i] = functionPopulation[i / tests].GetOutputs(inputs[i % tests], functionNeuronWeights, functionNeurons, functionInputs);
            }
                            );
            for (int i = 0; i < populationSize * tests; i++)
            {
                NeuralNetwork nn = functionPopulation[i / tests];
                nn.sumCost = nn.sumCost + nn.GetCost(values[i % tests], outputs[i]);
                nn.testsDone++;
                if (nn.MostConfidentOutput(outputs[i]) == values[i % tests])
                {
                    nn.correct++;
                }
                functionPopulation[i / tests] = nn;
            }
            population       = functionPopulation.Select(n => n).ToArray();
            allNeuronWeights = functionNeuronWeights.Select(n => n).ToArray();
            allNeurons       = functionNeurons.Select(n => n).ToArray();
            allInputs        = functionInputs.Select(n => n).ToArray();
            double[][][][] newNeuronWeights = new double[allNeuronWeights.Length][][][];
            Neuron[][][]   newNeurons       = new Neuron[allNeurons.Length][][];
            double[][][]   newInputs        = new double[allInputs.Length][][];
            List <double>  grades           = new List <double>();

            foreach (NeuralNetwork n in population)
            {
                grades.Add(n.sumCost);
            }
            Array.Sort(grades.ToArray(), population);
            //population = population.Reverse().ToArray();
            List <NeuralNetwork> topScorers = new List <NeuralNetwork>();
            List <int>           order      = Randomize(Enumerable.Range(0, populationSize / 2).ToList(), R);
            int numRemaining = populationSize / 2;

            for (int i = populationSize - 1; i >= 0; i--)
            {
                if (R.Next(populationSize) >= i || numRemaining == 0)
                {
                    topScorers.Add(population[i]);
                }
                else
                {
                    numRemaining--;
                }
            }
            topScorers.RemoveRange(0, numRemaining);
            List <NeuralNetwork> newPopulation = new List <NeuralNetwork>();

            for (int i = 0; newPopulation.Count < populationSize; i++)
            {
                for (int j = 0; j < 7 && newPopulation.Count < populationSize; j++)
                {
                    if (j >= 2)
                    {
                        if (R.Next(order[i]) == 0)
                        {
                            newPopulation.Add(new NeuralNetwork(topScorers[order[i]], topScorers[order[(i + j) % order.Count]], newPopulation.Count, newNeuronWeights, newNeurons, newInputs, allNeuronWeights, allNeurons, allInputs));
                        }
                        else
                        {
                            newPopulation.Add(new NeuralNetwork(topScorers[order[i]], topScorers[order[(i + j) % order.Count]], newPopulation.Count, newNeuronWeights, newNeurons, newInputs, allNeuronWeights, allNeurons, allInputs));
                        }
                    }
                }
            }
            best             = new NeuralNetwork(population[0], 0, newNeuronWeights, newNeurons, newInputs, allNeuronWeights, allNeurons, allInputs);
            newPopulation[0] = best;
            population       = newPopulation.ToArray();
            Array.Copy(newNeuronWeights, allNeuronWeights, 0);
            Array.Copy(newNeurons, allNeurons, 0);
            Array.Copy(newInputs, allInputs, 0);
            scores.Add(((double)best.correct / best.testsDone) * 100);
            Invalidate();
        }