/// <summary> /// IBlackBox can't be directly deserialized, so it takes a village of properties to construct it /// </summary> private static (IBlackBox phenome, NeatGenome genome)? DeserializeBrain(BrainNEATDNA dna) { if (dna == null) { return(null); } else if (string.IsNullOrEmpty(dna.Genome) || dna.Activation == null) { return(null); } List <NeatGenome> genomeList = null; try { // Deserialize the genome (sharpneat library has a custom serialize/deserialize) if (dna.Hyper == null) { genomeList = ExperimentNEATBase.LoadPopulation(dna.Genome, dna.Activation, dna.NEATPositions_Input.Length, dna.NEATPositions_Output.Length); } else { genomeList = ExperimentNEATBase.LoadPopulation(dna.Genome, dna.Activation, dna.Hyper); } if (genomeList == null || genomeList.Count == 0) { return(null); } // Construct the phenome (the actual instance of a neural net) IBlackBox phenome = ExperimentNEATBase.GetBlackBox(genomeList[0], dna.Activation, dna.Hyper); return(phenome, genomeList[0]);
private void BrainNEAT_Click(object sender, RoutedEventArgs e) { try { if (_experiment == null || _ea == null) { //NOTE: Just doing this for laziness. I don't want to write a bunch of logic to train a phenome up front MessageBox.Show("Need to have a running experiment", this.Title, MessageBoxButton.OK, MessageBoxImage.Warning); return; } // Get a genome NeatGenome genome = _ea.CurrentChampGenome; // Create a phenome IBlackBox phenome = ExperimentNEATBase.GetBlackBox(genome, _experimentArgs.Activation, _hyperneatArgs); // Instantiate a BrainNEAT EditorOptions options = new EditorOptions(); ItemOptions itemOptions = new ItemOptions(); Container energy = new Container() { QuantityMax = 1000, QuantityCurrent = 1000, }; BrainNEATDNA dnaBrain = new BrainNEATDNA() { PartType = BrainNEAT.PARTTYPE, Position = new Point3D(0, 0, 0), Orientation = Quaternion.Identity, Scale = new Vector3D(1, 1, 1) }; BrainNEAT brain = new BrainNEAT(options, itemOptions, dnaBrain, energy); brain.SetPhenome(phenome, genome, _experimentArgs.Activation, _hyperneatArgs); for (int cntr = 0; cntr < 100; cntr++) { foreach (INeuron neuron in brain.Neruons_Writeonly) { neuron.SetValue(StaticRandom.NextDouble(-2.5, 2.5)); } brain.Update_AnyThread(1); } #region save/load test2 // let BrainNEAT do the save/load BrainNEATDNA dna2 = (BrainNEATDNA)brain.GetNewDNA(); string dna2Text = XamlServices.Save(dna2).Replace('"', '\''); BrainNEAT brain2 = new BrainNEAT(options, itemOptions, dna2, energy); for (int cntr = 0; cntr < 100; cntr++) { foreach (INeuron neuron in brain2.Neruons_Writeonly) { neuron.SetValue(StaticRandom.NextDouble(-2.5, 2.5)); } brain2.Update_AnyThread(1); } BrainNEATDNA dna3 = (BrainNEATDNA)brain2.GetNewDNA(); BrainNEAT brain3 = new BrainNEAT(options, itemOptions, dna3, energy); for (int cntr = 0; cntr < 100; cntr++) { foreach (INeuron neuron in brain3.Neruons_Writeonly) { neuron.SetValue(StaticRandom.NextDouble(-2.5, 2.5)); } brain3.Update_AnyThread(1); } #endregion #region save/load test1 // initial test, building minimum necessary dna BrainNEATDNA brainDNA = new BrainNEATDNA() { Activation = _experimentArgs.Activation, Hyper = _hyperneatArgs, NEATPositions_Input = brain.Neruons_Readonly.Select(o => o.Position).ToArray(), NEATPositions_Output = brain.Neruons_Writeonly.Select(o => o.Position).ToArray(), Genome = ExperimentNEATBase.SavePopulation(new[] { genome }), }; // Make sure this can be serialized/deserialized string testString = XamlServices.Save(brainDNA); brainDNA = UtilityCore.Clone(brainDNA); List <NeatGenome> genomeList = null; if (_hyperneatArgs == null) { genomeList = ExperimentNEATBase.LoadPopulation(brainDNA.Genome, brainDNA.Activation, brainDNA.NEATPositions_Input.Length, brainDNA.NEATPositions_Output.Length); } else { genomeList = ExperimentNEATBase.LoadPopulation(brainDNA.Genome, brainDNA.Activation, _hyperneatArgs); } #endregion } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }
private void Timer_Tick_REAL(object sender, EventArgs e) { // This uses actual time elapsed, and runs continuously, grabbing a new neural net every 10 seconds try { imageInput.Source = null; canvasMain.Children.Clear(); DateTime now = DateTime.UtcNow; if (_harness == null) { _prevTick = now; return; } // Tell the harness to go _harness.Tick((now - _prevTick).TotalSeconds); var prevPosition = _harness.GetPreviousPosition(_harness.Time - _evalArgs.Delay_Seconds); var currentPosition = _harness.Item; if (_experiment != null && (_winningBrain == null || (now - _winningBrainTime).TotalSeconds > 10)) { NeatGenome winner = _ea.CurrentChampGenome; _genomeViewer.RefreshView(winner); _winningBrain = _experiment.GetBlackBox(winner); _winningBrainTime = now; } #region draw input double[] inputArr = new double[_harness.InputSizeXY * _harness.InputSizeXY]; AntPos_Evaluator.ClearArray(inputArr); if (prevPosition != null) { double dotRadius = (_harness.VisionSize / _harness.InputSizeXY) * Math.Sqrt(2); AntPos_Evaluator.ApplyPoint(inputArr, _harness.InputCellCenters, dotRadius, prevPosition.Item2, true); } imageInput.Source = UtilityWPF.GetBitmap(inputArr, _harness.InputSizeXY, _harness.InputSizeXY, invert: true); #endregion #region draw expected output double[] expectedOutput = null; if (currentPosition == null) { expectedOutput = AntPos_Evaluator.GetExpectedOutput(null, _harness, _evalArgs); } else { var currentPos = Tuple.Create(currentPosition, currentPosition.Position, currentPosition.Velocity); expectedOutput = AntPos_Evaluator.GetExpectedOutput(currentPos, _harness, _evalArgs); } imageExpectedOutput.Source = UtilityWPF.GetBitmap(expectedOutput, _harness.OutputSizeXY, _harness.OutputSizeXY, invert: true); #endregion #region draw nn output double[] nnOutput = null; if (_winningBrain != null) { nnOutput = new double[_harness.OutputSizeXY * _harness.OutputSizeXY]; // Brain.Tick _winningBrain.InputSignalArray.CopyFrom(inputArr, 0); _winningBrain.Activate(); _winningBrain.OutputSignalArray.CopyTo(nnOutput, 0); imageNNOutput.Source = UtilityWPF.GetBitmap(nnOutput, _harness.OutputSizeXY, _harness.OutputSizeXY, invert: true); } else { imageNNOutput.Source = null; } #endregion #region draw error (nn - expected) double[] error = null; if (nnOutput != null) { error = Enumerable.Range(0, nnOutput.Length). Select(o => Math.Abs(nnOutput[o] - expectedOutput[o])). ToArray(); imageError.Source = UtilityWPF.GetBitmap(error, _harness.OutputSizeXY, _harness.OutputSizeXY, invert: true); } else { imageError.Source = null; } #endregion #region draw actual // Vision Rectangle Rectangle visionRect = new Rectangle() { Stroke = Brushes.Silver, StrokeThickness = .3, Width = _harness.VisionSize, Height = _harness.VisionSize, }; Canvas.SetLeft(visionRect, _harness.VisionSize / -2); Canvas.SetTop(visionRect, _harness.VisionSize / -2); canvasMain.Children.Add(visionRect); // Dot Previous if (prevPosition != null) { Ellipse dot = new Ellipse() { Fill = new SolidColorBrush(prevPosition.Item1.Color), Stroke = Brushes.Black, StrokeThickness = .3, Width = 2, Height = 2, }; Canvas.SetLeft(dot, prevPosition.Item2.X - 1); Canvas.SetTop(dot, prevPosition.Item2.Y - 1); canvasMain.Children.Add(dot); } // Dot Current if (currentPosition != null) { Ellipse dot = new Ellipse() { Fill = new SolidColorBrush(currentPosition.Color), Stroke = Brushes.White, StrokeThickness = .3, Width = 2, Height = 2, }; Canvas.SetLeft(dot, currentPosition.Position.X - 1); Canvas.SetTop(dot, currentPosition.Position.Y - 1); canvasMain.Children.Add(dot); } // Transform TransformGroup transform = new TransformGroup(); transform.Children.Add(new ScaleTransform(canvasMain.ActualWidth / _harness.MapSize, canvasMain.ActualHeight / _harness.MapSize)); transform.Children.Add(new TranslateTransform(canvasMain.ActualWidth / 2, canvasMain.ActualHeight / 2)); canvasMain.RenderTransform = transform; #endregion _prevTick = now; } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }