private void Reset2_Click(object sender, RoutedEventArgs e) { try { // If not hyperneat, just replace with a new net // If hyperneat, compare other args and retain genomes if the only change is input/output resolution string prevGenomeXML = null; if (chkHyperNEAT.IsChecked.Value && _experiment != null && _ea != null) { //_ea.Stop(); // currently, Stop just calls RequestPause, so don't use it. There needs to be a dispose that removes the underlying thread _ea.RequestPauseAndWait(); prevGenomeXML = ExperimentNEATBase.SavePopulation(_ea.GenomeList); } RemoveExistingExperiment(); // My stuff #region harness args _harnessArgs = new HarnessArgs( trkMapSize.Value, trkVisionSize.Value, trkOutputSize.Value, trkInputPixels.Value.ToInt_Round(), trkOutputPixels.Value.ToInt_Round(), trkDelayBetweenInstances.Value); #endregion #region eval args if (chkRandomStartingConditions.IsChecked.Value) { _evalArgs = new EvaluatorArgs( trkEvalIterations.Value.ToInt_Round(), trkDelay.Value, trkEvalElapsedTime.Value, trkMaxSpeed.Value, chkBounceOffWalls.IsChecked.Value, new[] { (TrackedItemType)cboTrackedItemType.SelectedValue }, trkNewItemDuration.Value, trkNewItemErrorMultiplier.Value, (ScoreLeftRightBias)cboErrorBias.SelectedValue); } else { Point position = Math3D.GetRandomVector(_harnessArgs.MapSize / 2).ToPoint2D(); Vector velocity = Math3D.GetRandomVector_Circular(trkMaxSpeed.Value).ToVector2D(); // Don't let the velocity be in the same quadrant as the position (otherwise, you could have something spawn next to a wall, heading // toward the wall). These if statements force it to cross the x,y axiis if (Math.Sign(position.X) == Math.Sign(velocity.X)) { velocity = new Vector(-velocity.X, velocity.Y); } if (Math.Sign(position.Y) == Math.Sign(velocity.Y)) { velocity = new Vector(velocity.X, -velocity.Y); } _evalArgs = new EvaluatorArgs( trkEvalIterations.Value.ToInt_Round(), trkDelay.Value, trkEvalElapsedTime.Value, new[] { Tuple.Create((TrackedItemType)cboTrackedItemType.SelectedValue, position, velocity, chkBounceOffWalls.IsChecked.Value) }, trkNewItemDuration.Value, trkNewItemErrorMultiplier.Value, (ScoreLeftRightBias)cboErrorBias.SelectedValue); } #endregion // SharpNEAT #region experiment args _experimentArgs = new ExperimentInitArgs() { Description = "Input is a pixel array. Output is a pixel array. The NN needs to watch the object and anticipate where it will be at some fixed time in the future", InputCount = _harnessArgs.InputSizeXY * _harnessArgs.InputSizeXY, OutputCount = _harnessArgs.OutputSizeXY * _harnessArgs.OutputSizeXY, IsHyperNEAT = chkHyperNEAT.IsChecked.Value, PopulationSize = trkPopulationSize.Value.ToInt_Round(), SpeciesCount = trkSpeciesCount.Value.ToInt_Round(), Activation = new ExperimentInitArgs_Activation_CyclicFixedTimesteps() { TimestepsPerActivation = trkTimestepsPerActivation.Value.ToInt_Round(), FastFlag = true }, Complexity_RegulationStrategy = ComplexityCeilingType.Absolute, Complexity_Threshold = trkComplexityThreshold.Value.ToInt_Round(), }; #endregion #region hyperneat args _hyperneatArgs = null; if (chkHyperNEAT.IsChecked.Value) { // Use two square sheets var hyperPoints = HyperNEAT_Args.GetSquareSheets(trkVisionSize.Value, trkOutputSize.Value, _harnessArgs.InputSizeXY, _harnessArgs.OutputSizeXY); _hyperneatArgs = new HyperNEAT_Args() { InputPositions = hyperPoints.inputs, OutputPositions = hyperPoints.outputs, }; } #endregion #region create harness _harness = new TrackedItemHarness(_harnessArgs); _harness.ItemRemoved += (s1, e1) => { _harness.SetItem(AntPos_Evaluator.GetNewItem(_harness, _evalArgs)); }; _harness.SetItem(AntPos_Evaluator.GetNewItem(_harness, _evalArgs)); #endregion #region create evaluator AntPos_Evaluator evaluator = new AntPos_Evaluator(_harnessArgs, _evalArgs); //FitnessInfo score = evaluator.Evaluate(new RandomBlackBoxNetwork(_harness.InputSizeXY * _harness.InputSizeXY, _harness.OutputSizeXY * _harness.OutputSizeXY, true)); // this is a good place to unit test the evaluator #endregion #region create experiment _experiment = new ExperimentNEATBase(); _experiment.Initialize("anticipate position", _experimentArgs, evaluator); #endregion #region create evolution algorithm if (prevGenomeXML == null) { if (chkHyperNEAT.IsChecked.Value) { _ea = _experiment.CreateEvolutionAlgorithm(_hyperneatArgs); } else { _ea = _experiment.CreateEvolutionAlgorithm(); } } else { List <NeatGenome> genomeList; if (_hyperneatArgs == null) { genomeList = ExperimentNEATBase.LoadPopulation(prevGenomeXML, _experimentArgs.Activation, _experimentArgs.InputCount, _experimentArgs.OutputCount); } else { genomeList = ExperimentNEATBase.LoadPopulation(prevGenomeXML, _experimentArgs.Activation, _hyperneatArgs); } // The factory is the same for all items, so just grab the first one NeatGenomeFactory genomeFactory = genomeList[0].GenomeFactory; _ea = _experiment.CreateEvolutionAlgorithm(genomeFactory, genomeList, _hyperneatArgs); } _ea.UpdateEvent += EA_UpdateEvent; _ea.PausedEvent += EA_PausedEvent; #endregion ShowBestGenome(); // this ensures the neural viewer is created _winningBrainTime = DateTime.UtcNow - TimeSpan.FromDays(1); // put it way in the past so the first tick will request a new winner _winningBrain = null; //_winningBrain = new RandomBlackBoxNetwork(_harness.InputSizeXY * _harness.InputSizeXY, _harness.OutputSizeXY * _harness.OutputSizeXY, true); _tickCounter = _evalArgs.TotalNumberEvaluations * 2; // force the timer to get the winning NN right away (otherwise it will do a round before refreshing) _ea.StartContinue(); // this needs to be done last } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }
private void Timer_Tick(object sender, EventArgs e) { // This uses the eval's duration, and uses a neural net for the trial tick count. This is to recreate what the training actually sees try { imageInput.Source = null; canvasMain.Children.Clear(); DateTime now = DateTime.UtcNow; if (_harness == null || _evalArgs == null) { _prevTick = now; return; } // Reset if (_tickCounter >= _evalArgs.TotalNumberEvaluations) { #region reset if (_experiment != null) { NeatGenome winner = _ea.CurrentChampGenome; _genomeViewer.RefreshView(winner); if (winner == null) { _prevTick = now; return; } bool showedHyper = false; if (_experiment.IsHyperNEAT) { var decoder = _experiment.CreateGenomeDecoder(_hyperneatArgs); if (decoder is HyperNeatDecoder hyperDecoder) { //NOTE: There is a flaw. The INetworkDefinition that this method returns is acyclic, but the method that generates the IBlackBox is CreateSubstrateNetwork_FastCyclicNetwork. //So that INetworkDefinition seems to be limited or incorrect // //Actually, that might not be a flaw. The FastCyclic may be processing the CPPN which is cyclic var finalPhenome = hyperDecoder.Decode2(winner); _genomeViewer2.RefreshView(finalPhenome.Item2); nnViewerHost2.Visibility = Visibility.Visible; showedHyper = true; } } if (!showedHyper) { nnViewerHost2.Visibility = Visibility.Collapsed; } if (_experiment.IsHyperNEAT) { _winningBrain = _experiment.GetBlackBox(winner, _hyperneatArgs); } else { _winningBrain = _experiment.GetBlackBox(winner); } _winningBrainTime = now; _harness.ClearItem(); _harness.SetItem(AntPos_Evaluator.GetNewItem(_harness, _evalArgs)); _tickCounter = -1; } #endregion } // Tell the harness to go _harness.Tick(_evalArgs.ElapsedTime_Seconds); _tickCounter++; var prevPosition = _harness.GetPreviousPosition(_harness.Time - _evalArgs.Delay_Seconds); var currentPosition = _harness.Item; #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); } }