private EvaluationInfo Test(IBlackBox phenome, int iterations)
        {
            Controller.NoveltySearch  = NoveltySearchInfo;
            Environment.NoveltySearch = NoveltySearchInfo;

            Controller.Phenome = phenome;

            // Deactivate novelty search for testing
            bool novelty = NoveltySearchInfo.ScoreNovelty;

            NoveltySearchInfo.ScoreNovelty = false;

            EvaluationInfo evaluation = new EvaluationInfo();

            evaluation.Iterations         = iterations;
            evaluation.ObjectiveFitnessIt = new double[iterations];

            EvaluateRecord(Controller, iterations, ref evaluation);

            CalculateTestStats(ref evaluation);

            TearDownTest();

            NoveltySearchInfo.ScoreNovelty = novelty;

            Controller.Phenome = null;

            return(evaluation);
        }
        /// <summary>
        /// Main evaluation loop. Called from EA. Runs on separate / multiple threads.
        /// </summary>
        public EvaluationInfo Evaluate(IBlackBox phenome)
        {
            Environment.NoveltySearch = NoveltySearchInfo;
            Controller.NoveltySearch  = NoveltySearchInfo;

            // Register the phenome
            Controller.Phenome = phenome;

            // Register controller to environment. Rarely used, since the environment usually does not need to know about the controller
            Environment.Controller = Controller;

            EvaluationInfo evaluation = new EvaluationInfo();

            // Notify subclasses that the objective evaluation is about to start
            OnObjectiveEvaluationStart();

            // Evaluate objective!
            EvaluateObjective(Controller, Iterations, ref evaluation);

            if (NoveltySearchEnabled)
            {
                // Notify subclasses that the novelty evaluation is about to start
                OnNoveltyEvaluationStart();

                // Evaluate novelty!
                EvaluateNovelty(Controller, ref evaluation);
            }

            // Unregister the phenome
            Controller.Phenome = null;

            // Increment evaluation count
            _evaluationCount++;

            // Check if the task has been solved
            if (evaluation.ObjectiveFitness >= MaxScore * .999f)
            {
                _logger.Info($"Max fitness reached: {evaluation.ObjectiveFitness:F4}");
                StopConditionSatisfied = true;
            }

            return(evaluation);
        }
        private void CalculateTestStats(ref EvaluationInfo info)
        {
            double total = 0;
            double min   = double.MaxValue;
            double max   = double.MinValue;

            for (int i = 0; i < info.Iterations; i++)
            {
                double fitness = info.ObjectiveFitnessIt[i];
                total += fitness;

                if (fitness < min)
                {
                    min = fitness;
                }
                if (fitness > max)
                {
                    max = fitness;
                }
            }

            double mean = total / info.Iterations;

            double sdTotal = 0;

            for (int i = 0; i < info.Iterations; i++)
            {
                double fitness = info.ObjectiveFitnessIt[i];

                double v = fitness - mean;
                sdTotal += v * v;
            }

            info.ObjectiveFitnessMean = mean;
            info.ObjectiveFitnessStandardDeviation = Math.Sqrt(sdTotal / info.Iterations);
            info.ObjectiveFitnessMax = max;
            info.ObjectiveFitnessMin = min;
        }
示例#4
0
        private static void GeneralizeAllChamps()
        {
            string[] xmls = Directory.EnumerateFiles(_currentDir, "champion*.xml").ToArray();
            Console.WriteLine($"Found {xmls.Length} champion genomes");

            int count = xmls.Length;
            int iterations = GetIntegerConsoleInput("Enter number of iterations:");

            NextExperiment();

            EvaluationInfo[] results = new EvaluationInfo[count];
            for (int i = 0; i < count; i++)
            {
                results[i] = _experiment.TestSavedChampion(xmls[i], iterations, 1, true, true)[0];
            }

            try
            {
                string genDataFile = $"{_currentDir}/{DATA_FILE_GEN}";

                using (StreamWriter sw = File.AppendText(genDataFile))
                {
                    sw.WriteLine("Genome", "Iterations", "Mean", "Standard Deviation", "Max", "Min");

                    for (int i = 0; i < count; i++)
                    {
                        EvaluationInfo res = results[i];

                        sw.WriteLine(string.Format(CultureInfo.InvariantCulture,
                            "{0},{1},{2:F4},{3:F4},{4:F4},{5:F4}",
                            res.GenomeId, res.Iterations, res.ObjectiveFitnessMean, res.ObjectiveFitnessStandardDeviation, res.ObjectiveFitnessMax, res.ObjectiveFitnessMin));
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.Warn($"Could not write to generalization file: {ex.Message}", ex);
            }

            Console.WriteLine("Done. Press any key to exit...");
            Console.ReadKey();
        }
        private EvaluationInfo[] TestGenome(NeatGenome genome, int iterations, int runs, bool createRecordings, bool generalize)
        {
            if (runs <= 0)
            {
                return(new EvaluationInfo[0]);
            }

            if (_ea != null && _ea.RunState == RunState.Running)
            {
                _ea.RequestPause();
            }

            // Create the genome decoder
            IGenomeDecoder <NeatGenome, IBlackBox> decoder = CreateGenomeDecoder();

            // Decode the genome (genotype => phenotype)
            IBlackBox phenome = decoder.Decode(genome);

            //TODO FIXME We had problems with the logger, it hangs at some point probably a buffer issue on the windows cmd???
            //We had to disable the console appender on log4net and just log to the file, so there is now a console writeline instead
            Debug.On = true;
            _logger.Info($"Testing phenome {(generalize ? "generalization " : "")}(ID: {genome.Id})...");
            Console.WriteLine($"Testing phenome (ID: {genome.Id})...");

            EvaluationInfo[] fitness = new EvaluationInfo[runs];

            CreateExperimentDirectoryIfNecessary();

            // run evaluations
            double minFitness = double.MaxValue;
            double maxFitness = double.MinValue;

            for (int i = 0; i < runs; i++)
            {
                if (generalize)
                {
                    fitness[i]          = _evaluator.TestPhenomeGeneralization(phenome, iterations);
                    fitness[i].GenomeId = genome.Id;
                }
                else
                {
                    fitness[i] = _evaluator.TestPhenome(phenome, iterations);
                }

                if (fitness[i].ObjectiveFitnessMean < minFitness)
                {
                    minFitness = fitness[i].ObjectiveFitnessMean;
                }

                if (fitness[i].ObjectiveFitnessMean > maxFitness)
                {
                    maxFitness = fitness[i].ObjectiveFitnessMean;
                }

                if (createRecordings)
                {
                    if (Recorder != null)
                    {
                        string recordingFile = generalize
                            ? $"{RecordingGeneralizationFile($"{genome.Id}_{i}")}"
                            : $"{RecordingFile($"{genome.Id}_{i}")}";

                        string tapeFile = generalize
                            ? $"{TapeGeneralizationFile($"{genome.Id}_{i}")}"
                            : $"{TapeFile($"{genome.Id}_{i}")}";

                        using (Bitmap bmp = Recorder.LifetimeToBitmap())
                        {
                            bmp.Save(recordingFile, ImageFormat.Png);
                        }

                        if (Recorder.FinalTuringTape != null)
                        {
                            using (Bitmap bmp = Recorder.TapeToBitmap())
                            {
                                bmp.Save(tapeFile, ImageFormat.Png);
                            }
                        }
                    }
                    else
                    {
                        _logger.Warn("Recorder was null");
                        break;
                    }

                    _logger.Info($"Run {i}: Achieved fitness: {fitness[i].ObjectiveFitnessMean:F4}");
                    Console.WriteLine($"Run {i}: Achieved fitness: {fitness[i].ObjectiveFitnessMean:F4}");
                }
            }

            // evaluate runs
            if (runs > 1)
            {
                double[] fit = new double[runs];
                for (int i = 0; i < runs; i++)
                {
                    fit[i] = fitness[i].ObjectiveFitnessMean;
                }

                double mean = Utilities.Mean(fit);
                double sd   = Utilities.StandartDeviation(fit);
                //TODO FIXME We had problems with the logger, it hangs at some point probably a buffer issue on the windows cmd???
                //We had to disable the console appender on log4net and just log to the file, so there is now a console writeline instead
                _logger.Info($"Done. Average fitness: {mean:F4}, min fitness: {minFitness:F4}, max fitness: {maxFitness:F4}, sd: {sd:F4}");
                Console.WriteLine($"Done. Average fitness: {mean:F4}, min fitness: {minFitness:F4}, max fitness: {maxFitness:F4}, sd: {sd:F4}");
            }

            return(fitness);
        }
 protected abstract void EvaluateRecord(TController controller, int iterations, ref EvaluationInfo evaluation);
 protected abstract void EvaluateNovelty(TController controller, ref EvaluationInfo evaluation);
 protected abstract void EvaluateObjective(TController controller, int iterations, ref EvaluationInfo evaluation);