public ConvNet(ConvNet original) { mutationRandom = new Random(); inputs = original.inputs; fullyConnectedInputs = original.fullyConnectedInputs; featureMaps = original.featureMaps; fullyConnected = original.fullyConnected; testsDone = 0; correct = 0; avgCost = 0; current = new Bitmap(28, 28); outputs = original.outputs; }
public Form1() { InitializeComponent(); typeof(Form1).InvokeMember("floatBuffered", BindingFlags.SetProperty | BindingFlags.Instance | BindingFlags.NonPublic, null, this, new object[] { true }); string[] files = Directory.GetFiles(Path.Combine(Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, @"..\..\..")), @"Images\"), "*.bmp", SearchOption.AllDirectories); allDigits = new Digit[files.Length]; for (int i = 0; i < files.Length; i++) { allDigits[i] = new Digit(files[i]); } layersizes = new[] { 137, 57, 24, 10 }; allNeuronWeights = new float[populationSize][][][]; allNeurons = new Neuron[populationSize][][]; allInputs = new float[populationSize][][]; for (int i = 0; i < populationSize; i++) { allNeuronWeights[i] = new float[layersizes.Length][][]; for (int j = 0; j < layersizes.Length; j++) { allNeuronWeights[i][j] = new float[layersizes[j]][]; allNeuronWeights[i][j][0] = new float[784]; for (int k = 1; k < layersizes[j]; k++) { allNeuronWeights[i][j][k] = new float[layersizes[k - 1]]; } } } R = new Random(); population = new ConvNet[populationSize]; for (int i = 0; i < populationSize; i++) { population[i] = new ConvNet(i, allNeuronWeights, allNeurons, allInputs); } updatePopulationTimer = new Timer() { Enabled = true, Interval = 1 }; updatePopulationTimer.Tick += UpdatePopulation; scores.Add(10); }
private void UpdatePopulation(object sender, EventArgs e) { float[][] inputs = new float[tests][]; string[] paths = new string[tests]; float[][] outputs = new float[populationSize * tests][]; ConvNet[] functionPopulation = population.Select(n => n).ToArray(); float[][][][] functionNeuronWeights = allNeuronWeights.Select(n => n).ToArray(); Neuron[][][] functionNeurons = allNeurons.Select(n => n).ToArray(); float[][][] 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 float[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++) { ConvNet 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(); float[][][][] newNeuronWeights = new float[allNeuronWeights.Length][][][]; Neuron[][][] newNeurons = new Neuron[allNeurons.Length][][]; float[][][] newInputs = new float[allInputs.Length][][]; List <float> grades = new List <float>(); foreach (ConvNet n in population) { grades.Add(n.sumCost); } Array.Sort(grades.ToArray(), population); //population = population.Reverse().ToArray(); List <ConvNet> topScorers = new List <ConvNet>(); 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 <ConvNet> newPopulation = new List <ConvNet>(); 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 ConvNet(topScorers[order[i]], topScorers[order[(i + j) % order.Count]], newPopulation.Count, newNeuronWeights, newNeurons, newInputs, allNeuronWeights, allNeurons, allInputs)); } else { newPopulation.Add(new ConvNet(topScorers[order[i]], topScorers[order[(i + j) % order.Count]], newPopulation.Count, newNeuronWeights, newNeurons, newInputs, allNeuronWeights, allNeurons, allInputs)); } } } } best = new ConvNet(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(((float)best.correct / best.testsDone) * 100); Invalidate(); }
public ConvNet(ConvNet parentA, ConvNet parentB) { mutationRandom = new Random(); inputs = new List <List <Bitmap> >(); fullyConnectedInputs = new List <List <float> >(); featureMaps = new List <List <ConvNeuron> >(); fullyConnected = new List <List <Neuron> >(); testsDone = 0; correct = 0; avgCost = 0; current = new Bitmap(28, 28); outputs = new List <float>(); for (int i = 0; i < parentA.fullyConnected[1].Count; i++) { outputs.Add(0); } int prevLayerSize = 1; for (int i = 0; i < parentA.featureMaps.Count; i++) { featureMaps.Add(new List <ConvNeuron>()); int layerSize = parentA.featureMaps[i].Count; prevLayerSize *= layerSize; for (int j = 0; j < layerSize; j++) { string neuronADNA = parentA.featureMaps[i][j].DNA; string neuronBDNA = parentB.featureMaps[i][j].DNA; string crossoveredDNA = string.Empty; for (int k = 0; k < neuronADNA.Length; k++) { crossoveredDNA += (mutationRandom.Next(2) == 0 ? neuronADNA : neuronBDNA)[k]; if (mutationRandom.Next(100 / mutationFrequency) == 0) { crossoveredDNA = crossoveredDNA.Substring(0, k) + mutationRandom.Next(10); } } featureMaps[i].Add(new ConvNeuron(crossoveredDNA)); } } for (int i = 0; i < fullyConnectedLayers; i++) { fullyConnected.Add(new List <Neuron>()); int layerSize = parentA.fullyConnected[i].Count; for (int j = 0; j < layerSize; j++) { string neuronADNA = parentA.fullyConnected[i][j].DNA; string neuronBDNA = parentB.fullyConnected[i][j].DNA; string crossoveredDNA = string.Empty; for (int k = 0; k < neuronADNA.Length; k++) { crossoveredDNA += (mutationRandom.Next(2) == 0 ? neuronADNA : neuronBDNA)[k]; if (mutationRandom.Next(100 / mutationFrequency) == 0) { crossoveredDNA = crossoveredDNA.Substring(0, k) + mutationRandom.Next(10); } } fullyConnected[i].Add(new Neuron(crossoveredDNA)); } prevLayerSize = layerSize; } }