示例#1
0
        /// <summary>
        /// Create a network activation scheme from the scheme setting in the provided config XML.
        /// </summary>
        /// <returns></returns>
        public static NetworkActivationScheme CreateActivationScheme(XmlElement xmlConfig, string activationElemName)
        {
            // Get root activation element.
            XmlNodeList nodeList = xmlConfig.GetElementsByTagName(activationElemName, "");

            if (nodeList.Count != 1)
            {
                throw new ArgumentException("Missing or invalid activation XML config setting.");
            }

            XmlElement xmlActivation = nodeList[0] as XmlElement;
            string     schemeStr     = XmlUtils.TryGetValueAsString(xmlActivation, "Scheme");

            switch (schemeStr)
            {
            case "Acyclic":
                return(NetworkActivationScheme.CreateAcyclicScheme());

            case "CyclicFixedIters":
                int iters = XmlUtils.GetValueAsInt(xmlActivation, "Iters");
                return(NetworkActivationScheme.CreateCyclicFixedTimestepsScheme(iters));

            case "CyclicRelax":
                double deltaThreshold = XmlUtils.GetValueAsInt(xmlActivation, "Threshold");
                int    maxIters       = XmlUtils.GetValueAsInt(xmlActivation, "MaxIters");
                return(NetworkActivationScheme.CreateCyclicRelaxingActivationScheme(deltaThreshold, maxIters));
            }
            throw new ArgumentException(string.Format("Invalid or missing ActivationScheme XML config setting [{0}]", schemeStr));
        }
示例#2
0
 /// <summary>
 /// This is inspired by ExperimentUtils.CreateActivationScheme, but can't be put there, because NeatConfigInfo_Activation isn't
 /// defined that low
 /// </summary>
 private static NetworkActivationScheme GetActivationScheme(ExperimentInitArgs_Activation scheme)
 {
     if (scheme == null)
     {
         throw new ArgumentNullException("scheme");
     }
     else if (scheme is ExperimentInitArgs_Activation_Acyclic)
     {
         return(NetworkActivationScheme.CreateAcyclicScheme());
     }
     else if (scheme is ExperimentInitArgs_Activation_CyclicFixedTimesteps)
     {
         ExperimentInitArgs_Activation_CyclicFixedTimesteps cast = (ExperimentInitArgs_Activation_CyclicFixedTimesteps)scheme;
         return(NetworkActivationScheme.CreateCyclicFixedTimestepsScheme(cast.TimestepsPerActivation, cast.FastFlag));
     }
     else if (scheme is ExperimentInitArgs_Activation_CyclicRelaxing)
     {
         ExperimentInitArgs_Activation_CyclicRelaxing cast = (ExperimentInitArgs_Activation_CyclicRelaxing)scheme;
         return(NetworkActivationScheme.CreateCyclicRelaxingActivationScheme(cast.SignalDeltaThreshold, cast.MaxTimesteps, cast.FastFlag));
     }
     else
     {
         throw new ArgumentException("Unknown scheme type: " + scheme.GetType().ToString());
     }
 }
    /// <summary>
    /// Initialize the experiment with some optional XML configutation data.
    /// </summary>
    public void Initialize(string name, XmlElement xmlConfig)
    {
        _name        = name;
        _description = "Just a test experiment class";

        // Dont use xml, just hard code the values for now
        _populationSize = 50;
        _specieCount    = 5;

        // PicBreeder appears to use acyclic networks, so we will do the same.
        // Cyclic ("recurrent") networks seem better for realtime reactive controllers, e.g. predator-prey, where the recurrent connections allow for memory of past events
        _activationScheme = NetworkActivationScheme.CreateAcyclicScheme();

        // Next two values just seem to be commen.
        // Relative just means that limit of complexification is relative to the last simplification process (so it can continue to grow)
        // Alternative is "Absolute", which means, with a threshold of 10, network wont ever be more complex than 10 connections
        _complexityRegulationStr = "Absolute";
        _complexityThreshold     = 50;

        //_parallelOptions = new ParallelOptions();


        // Param constructors set defaul param values, a lot of experiments just leave them as default
        _eaParams                         = new NeatEvolutionAlgorithmParameters();
        _eaParams.SpecieCount             = _specieCount;
        _neatGenomeParams                 = new NeatGenomeParameters();
        _neatGenomeParams.FeedforwardOnly = _activationScheme.AcyclicNetwork;
    }
示例#4
0
        public Experiment()
        {
            this.InputCount  = 36;
            this.OutputCount = 3;

            this.eaParams                              = new NeatEvolutionAlgorithmParameters();
            this.eaParams.SpecieCount                  = 200;   // default: 10
            this.eaParams.ElitismProportion            = 0.05;  // default: 0.2
            this.eaParams.SelectionProportion          = 0.15;  // default: 0.2
            this.eaParams.OffspringAsexualProportion   = 0.7;   // default: 0.5
            this.eaParams.OffspringSexualProportion    = 0.3;   // default: 0.5
            this.eaParams.InterspeciesMatingProportion = 0.01;  // default: 0.01

            this.neatGenomeParams = new NeatGenomeParameters();
            this.neatGenomeParams.ConnectionWeightRange = 3.0;                  // default: 5
            this.neatGenomeParams.ConnectionWeightMutationProbability = 0.95;   // default: 0.94;
            this.neatGenomeParams.AddNodeMutationProbability          = 0.01;   // default: 0.01;
            this.neatGenomeParams.AddConnectionMutationProbability    = 0.075;  // default: 0.025;
            this.neatGenomeParams.DeleteConnectionMutationProbability = 0.075;  // default: 0.025;

            this.parallelOptions = new ParallelOptions();
            //this.parallelOptions.MaxDegreeOfParallelism = 8;

            this.activationScheme = NetworkActivationScheme.CreateAcyclicScheme(); //NetworkActivationScheme.CreateCyclicFixedTimestepsScheme(1);
            this.neatGenomeParams.FeedforwardOnly = this.activationScheme.AcyclicNetwork;
        }
示例#5
0
    public void Initialize(NeatGenome genome)
    {
        IGenomeDecoder <NeatGenome, IBlackBox> genomeDecoder = new NeatGenomeDecoder(NetworkActivationScheme.CreateAcyclicScheme());

        try {
            _blackBox = genomeDecoder.Decode(genome);
        }
        catch (Exception) {
            if (CyclicNetworkTest.IsNetworkCyclic(genome))
            {
                Debug.Log("Cyclic");
            }
        }
        Genome = genome;
    }
示例#6
0
    private void Start()
    {
        int populationSize = 100;
        NetworkActivationScheme activationScheme = NetworkActivationScheme.CreateAcyclicScheme();

        NeatGenomeParameters neatParams = new NeatGenomeParameters();

        neatParams.ActivationFn    = TanH.__DefaultInstance;
        neatParams.FeedforwardOnly = activationScheme.AcyclicNetwork;

        IGenomeDecoder <NeatGenome, IBlackBox> neatDecoder = new NeatGenomeDecoder(activationScheme);

        IGenomeFactory <NeatGenome> neatFactory = new NeatGenomeFactory(3, 3, neatParams);
        List <NeatGenome>           genomeList  = neatFactory.CreateGenomeList(populationSize, 0);
        ArenaEvaluator evaluator = GetComponent <ArenaEvaluator>();

        evaluator.Initialize(neatDecoder);

        IDistanceMetric distanceMetric = new ManhattanDistanceMetric(1.0, 0.0, 10.0);

        // Evolution parameters
        NeatEvolutionAlgorithmParameters neatEvolutionParams = new NeatEvolutionAlgorithmParameters();

        neatEvolutionParams.SpecieCount = 10;
        ISpeciationStrategy <NeatGenome> speciationStrategy           = new KMeansClusteringStrategy <NeatGenome>(distanceMetric);
        IComplexityRegulationStrategy    complexityRegulationStrategy = new DefaultComplexityRegulationStrategy(ComplexityCeilingType.Absolute, 10);

        NeatEvolutionAlgorithm <NeatGenome> ea = GetComponent <UnityEvolutionAlgorithm>();

        ea.Construct(neatEvolutionParams, speciationStrategy, complexityRegulationStrategy, new NullGenomeListEvaluator <NeatGenome, IBlackBox>());
        ea.Initialize(evaluator, neatFactory, genomeList);
        ea.UpdateScheme = new UpdateScheme(1); // This needs to be set AFTER Initialize is called

        ea.PausedEvent += (sender, e) =>
        {
            //ea.StartContinue();
        };
        ea.GenerationEvent += (sender, gen) =>
        {
            Debug.Log($"Generation {gen}");
            Debug.Log($"Highest fitness: {ea.CurrentChampGenome.EvaluationInfo.Fitness}");
            nnMesh.GenerateMesh(ea.CurrentChampGenome);
            ea.RequestPause();
            StartCoroutine(PauseRoutine(ea));
        };

        ea.StartContinue();
    }
示例#7
0
        public NeatExperiment(Simulation simulation)
        {
            _simulation = simulation;

            _name                    = "Trader";
            _populationSize          = 100;
            _specieCount             = 1;
            _activationScheme        = NetworkActivationScheme.CreateAcyclicScheme();
            _complexityRegulationStr = "Relative";
            _complexityThreshold     = 10;
            _description             = "Generate trader neural network";
            _parallelOptions         = new ParallelOptions {
                MaxDegreeOfParallelism = 2
            };

            UnityThread.SetUnityValue(() => _inputCount = 6 + UnityEngine.Object.FindObjectsOfType <Coin>().Length * 5);

            _outputCount = 8;

            _eaParams             = new NeatEvolutionAlgorithmParameters();
            _eaParams.SpecieCount = _specieCount;

            _neatGenomeParams = new NeatGenomeParameters();
            _neatGenomeParams.FeedforwardOnly = _activationScheme.AcyclicNetwork;
            //_neatGenomeParams.ActivationFn = LeakyReLU.__DefaultInstance;
            _neatGenomeParams.ActivationFn = SharpNeat.Network.SReLU.__DefaultInstance;
            // Create a genome factory with our neat genome parameters object and the appropriate number of input and output neuron genes.
            _genomeFactory = CreateGenomeFactory();

            // Create an initial population of randomly generated genomes.
            _genomeList = _genomeFactory.CreateGenomeList(_populationSize, 0);

            // Create evolution algorithm and attach update event.
            _ea = CreateEvolutionAlgorithm(_genomeFactory, _genomeList);
            // _ea.UpdateEvent += new EventHandler(ea_UpdateEvent);

            // Start algorithm (it will run on a background thread).
            _ea.StartContinue();
        }
示例#8
0
        /// <summary>
        /// Creates a cyclic or acyclic activation scheme for the network.
        /// </summary>
        private NetworkActivationScheme CreateActivationScheme(string activationScheme, int?activationIters,
                                                               double?activationDeltaThreshold)
        {
            switch (activationScheme)
            {
            case "Acyclic":
                return(NetworkActivationScheme.CreateAcyclicScheme());

            case "CyclicFixedIters":

                if (activationIters == null)
                {
                    throw new ArgumentException(
                              "Maximum iterations must be specified for cyclic activation scheme");
                }

                var iters = activationIters.Value;
                return(NetworkActivationScheme.CreateCyclicFixedTimestepsScheme(iters));

            case "CyclicRelax":

                if (activationIters == null)
                {
                    throw new ArgumentException(
                              "Maximum iterations must be specified for cyclic relaxation scheme");
                }

                if (activationDeltaThreshold == null)
                {
                    throw new ArgumentException("Delta threshold must be specified for cyclic relaxation scheme");
                }

                var deltaThreshold = activationDeltaThreshold.Value;
                var maxIters       = activationIters.Value;
                return(NetworkActivationScheme.CreateCyclicRelaxingActivationScheme(deltaThreshold, maxIters));
            }

            throw new ArgumentException($"Invalid ActivationScheme setting [{activationScheme}]");
        }
示例#9
0
        public IBlackBox BestPhenome()
        {
            var genomeFactory = new NeatGenomeFactory(this.InputCount, this.OutputCount, new NeatGenomeParameters());

            //var genomeFactory = new SharpNeat.Genomes.HyperNeat.CppnGenomeFactory(
            //    this.InputCount,
            //    this.OutputCount,
            //    SharpNeat.Network.DefaultActivationFunctionLibrary.CreateLibraryCppn(),
            //    new NeatGenomeParameters());

            List <NeatGenome> genomeList;

            using (XmlReader xr = XmlReader.Create(this.xmlPopulationFile))
            {
                genomeList = NeatGenomeXmlIO.ReadCompleteGenomeList(xr, false, genomeFactory);
            }

            //var decoder = new NeatGenomeDecoder(NetworkActivationScheme.CreateCyclicFixedTimestepsScheme(1));
            var decoder = new NeatGenomeDecoder(NetworkActivationScheme.CreateAcyclicScheme());

            return(decoder.Decode(genomeList[0]));
        }
示例#10
0
        public static void Main(string[] args)
        {
            var random   = new Random();
            var circuits = circuitsFilePaths().ToArray();

            var perceptionStep        = TimeSpan.FromSeconds(0.1);
            var simulationStep        = TimeSpan.FromSeconds(0.05); // 20Hz
            var maximumSimulationTime = TimeSpan.FromSeconds(60);

            var tracks = circuits.Select(circuitPath => Track.Load($"{circuitPath}/circuit_definition.json"));
            var worlds = tracks.Select(track => new StandardWorld(track, simulationStep)).ToArray();

            var inputSamplesCount       = 3;
            var maximumScanningDistance = 200;

            ILidar createLidarFor(ITrack track)
            => new Lidar(track, inputSamplesCount, Angle.FromDegrees(135), maximumScanningDistance);

            var settings = new EvolutionSettings
            {
                PopulationSize      = 1000,
                SpeciesCount        = 30,
                ElitismProportion   = 0,
                ComplexityThreshold = 50
            };

            // prepare simulation
            var parameters = new NeatEvolutionAlgorithmParameters
            {
                ElitismProportion = settings.ElitismProportion,
                SpecieCount       = settings.SpeciesCount
            };

            var distanceMetric  = new ManhattanDistanceMetric(1.0, 0.0, 10.0);
            var parallelOptions = new ParallelOptions {
                MaxDegreeOfParallelism = 4
            };
            var speciationStrategy           = new ParallelKMeansClusteringStrategy <NeatGenome>(distanceMetric, parallelOptions);
            var complexityRegulationStrategy = new DefaultComplexityRegulationStrategy(ComplexityCeilingType.Absolute, settings.ComplexityThreshold);

            var evolutionaryAlgorithm = new NeatEvolutionAlgorithm <NeatGenome>(
                parameters,
                speciationStrategy,
                complexityRegulationStrategy);

            var phenomeEvaluator = new RaceSimulationEvaluator(
                random,
                simulationStep,
                perceptionStep,
                maximumSimulationTime,
                worlds,
                createLidarFor);

            var genomeDecoder       = new NeatGenomeDecoder(NetworkActivationScheme.CreateAcyclicScheme());
            var genomeListEvaluator = new ParallelGenomeListEvaluator <NeatGenome, IBlackBox>(
                genomeDecoder,
                phenomeEvaluator);

            evolutionaryAlgorithm.Initialize(
                genomeListEvaluator,
                genomeFactory: new NeatGenomeFactory(
                    inputNeuronCount: inputSamplesCount,
                    outputNeuronCount: 2,
                    DefaultActivationFunctionLibrary.CreateLibraryNeat(new BipolarSigmoid()),
                    new NeatGenomeParameters
            {
                FeedforwardOnly                     = true,
                AddNodeMutationProbability          = 0.03,
                DeleteConnectionMutationProbability = 0.05,
                ConnectionWeightMutationProbability = 0.08,
                FitnessHistoryLength                = 10,
            }),
                settings.PopulationSize);

            var lastVisualization = DateTimeOffset.Now;

            evolutionaryAlgorithm.UpdateEvent += onUpdate;
            evolutionaryAlgorithm.StartContinue();

            Console.WriteLine("Press enter to stop the evolution.");
            Console.ReadLine();
            Console.WriteLine("Finishing the evolution.");

            evolutionaryAlgorithm.Stop();
            Console.WriteLine("Evolution is stopped.");

            // simulate best individual
            Console.WriteLine("Simulating best individual...");
            evaluate(evolutionaryAlgorithm.CurrentChampGenome);
            Console.WriteLine("Done.");

            void onUpdate(object sender, EventArgs e)
            {
                Console.WriteLine($"Generation #{evolutionaryAlgorithm.CurrentGeneration}");
                Console.WriteLine($"- max fitness:  {evolutionaryAlgorithm.Statistics._maxFitness}");
                Console.WriteLine($"- mean fitness: {evolutionaryAlgorithm.Statistics._meanFitness}");
                Console.WriteLine();

                if (DateTimeOffset.Now - lastVisualization > TimeSpan.FromSeconds(35))
                {
                    lastVisualization = DateTimeOffset.Now;
                    Console.WriteLine("Simulating currently best individual...");
                    evaluate(evolutionaryAlgorithm.CurrentChampGenome);
                }
            }

            void evaluate(NeatGenome genome)
            {
                var worldId = random.Next(0, worlds.Length - 1);
                var world   = worlds[worldId];

                var bestIndividual = genomeDecoder.Decode(genome);
                var agent          = new NeuralNetworkAgent(createLidarFor(world.Track), bestIndividual);
                var simulation     = new Simulation.Simulation(agent, world);
                var summary        = simulation.Simulate(simulationStep, perceptionStep, maximumSimulationTime);

                File.Copy($"{circuits[worldId]}/visualization.svg", "C:/Users/simon/Projects/racer-experiment/simulator/src/visualization.svg", overwrite: true);
                IO.Simulation.StoreResult(world.Track, world.VehicleModel, summary, "", "C:/Users/simon/Projects/racer-experiment/simulator/src/report.json");
            }
        }
示例#11
0
 protected override NetworkActivationScheme ActivationScheme()
 {
     return(NetworkActivationScheme.CreateAcyclicScheme());
 }