示例#1
0
    /// Finds a link and expands it
    void AddNewHiddenNeuron()
    {
        if (linkCount == 0)
        {
            Debug.LogError("Cannot create new hidden neuron because link list count is zero");
            return;
        }

        int randLinkID = Random.Range(0, linkCount);

        // Create new neuron
        //NeuronGenome newNeuronGenome = new NeuronGenome("HidNew", NeuronType.Hid, BrainModuleID.Undefined, hiddenNeurons.Count);
        var newHiddenNeuron = new NeuronGenome(hiddenTemplate, inOutNeurons.Count + hiddenNeurons.Count);

        hiddenNeurons.Add(newHiddenNeuron);

        // create 2 new links
        LinkGenome linkGenome1 = new LinkGenome(links[randLinkID].from, newHiddenNeuron, 1f, true);
        LinkGenome linkGenome2 = new LinkGenome(newHiddenNeuron, links[randLinkID].to, links[randLinkID].weight, true);

        // delete old link
        links[randLinkID].enabled = false; // *** not needed? ****
        links.RemoveAt(randLinkID);

        // add new links
        links.Add(linkGenome1);
        links.Add(linkGenome2);

        //Debug.Log("New Neuron! " + newNeuronGenome.nid.neuronID.ToString() +
        // " - from: [" + linkGenome1.fromModuleID.ToString() + ", " +
        // linkGenome1.fromNeuronID.ToString() + "], to: [" + linkGenome2.toModuleID.ToString() +
        // ", " + linkGenome2.toNeuronID.ToString() + "]");
    }
示例#2
0
    List <LinkGenome> MutateLinks(List <LinkGenome> original, MutationSettingsInstance settings)
    {
        var result = new List <LinkGenome>();

        foreach (var element in original)
        {
            LinkGenome newLinkGenome = new LinkGenome(element.from, element.to, element.weight, true);

            // Remove fully??? *****
            if (RandomStatics.CoinToss(settings.brainRemoveLinkChance))
            {
                newLinkGenome.weight = 0f;
            }

            if (RandomStatics.CoinToss(settings.brainWeightMutationChance))
            {
                float randomWeight = Gaussian.GetRandomGaussian();
                newLinkGenome.weight += Mathf.Lerp(0f, randomWeight, settings.brainWeightMutationStepSize);
            }

            newLinkGenome.weight *= settings.brainWeightDecayAmount;
            result.Add(newLinkGenome);
        }

        return(result);
    }
示例#3
0
    /// Apply a random chance of connecting two neurons with a random weight
    void RequestConnection(NeuronGenome from, NeuronGenome to, float connectionChance, float weightMultiplier)
    {
        var connectNeurons = RandomStatics.CoinToss(connectionChance);

        if (!connectNeurons)
        {
            return;
        }
        var randomWeight = Gaussian.GetRandomGaussian() * weightMultiplier;
        var linkGenome   = new LinkGenome(from, to, randomWeight, true);

        links.Add(linkGenome);
    }
示例#4
0
    void AddNewLink(MutationSettingsInstance settings)
    {
        foreach (var neuron in hiddenNeurons)
        {
            inputNeurons.Add(neuron);
            outputNeurons.Add(neuron);
        }

        if (inputNeurons.Count <= 0 || outputNeurons.Count <= 0)
        {
            Debug.LogError("Cannot create new list because input or output list count is zero.  " +
                           $"Input count = {inputNeurons.Count}, output count = {outputNeurons.Count}");
            return;
        }

        // Try x times to find new connection -- random scattershot approach at first:
        // other methods:
        //      -- make sure all bodyNeurons are fully-connected when modifying body
        int maxChecks = 8;

        for (int k = 0; k < maxChecks; k++)
        {
            int randInputID = Random.Range(0, inputNeurons.Count);
            var from        = inputNeurons[randInputID];

            int randOutputID = Random.Range(0, outputNeurons.Count);
            var to           = outputNeurons[randOutputID];

            if (LinkExists(from, to))
            {
                continue;
            }

            float      randomWeight = Gaussian.GetRandomGaussian() * settings.brainWeightMutationStepSize;
            LinkGenome linkGenome   = new LinkGenome(from, to, randomWeight, true);
            links.Add(linkGenome);

            //Debug.Log("New Link! from: [" + fromNID.moduleID.ToString() + ", " + fromNID.neuronID.ToString() + "], to: [" + toNID.moduleID.ToString() + ", " + toNID.neuronID.ToString() + "]");
            break;
        }
    }
示例#5
0
    public void CreateSpeciesLeaderboardGenomeTexture()
    {
        int width  = 32;
        int height = 96;

        speciesPoolGenomeTex.Resize(width, height);
        SpeciesGenomePool pool = simulationManager.GetSelectedGenomePool();

        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                LinkGenome linkGenome = pool.GetLeaderboardLinkGenome(x, y);
                Color      testColor  = linkGenome == null ? CLEAR : Color.Lerp(negativeColor, positiveColor, linkGenome.normalizedWeight);
                speciesPoolGenomeTex.SetPixel(x, y, testColor);
            }
        }

        // Body Genome
        //int xI = curLinearIndex % speciesPoolGenomeTex.width;
        //int yI = Mathf.FloorToInt(curLinearIndex / speciesPoolGenomeTex.width);

        speciesPoolGenomeTex.Apply();
    }
示例#6
0
    public void SetToMutatedCopyOfParentGenome(BrainGenome parentGenome, TrainingSettingsManager settings)
    {
        this.bodyNeuronList = parentGenome.bodyNeuronList; // UNSUSTAINABLE!!! might work now since all neuronLists are identical
        // Alternate: SetBodyNeuronsFromTemplate(BodyGenome templateBody);

        // Existing Hidden Neurons!!
        hiddenNeuronList = new List <NeuronGenome>();
        for (int i = 0; i < parentGenome.hiddenNeuronList.Count; i++)
        {
            NeuronGenome newHiddenNeuronGenome = new NeuronGenome(parentGenome.hiddenNeuronList[i]);  // create new neuron as a copy of parent neuron
            // Might be able to simply copy hiddenNeuronList or individual hiddenNeuronGenomes from parent if they are functionally identical...
            // for now going with the thorough approach of a reference-less copy
            hiddenNeuronList.Add(newHiddenNeuronGenome);
        }

        // Existing Links!!
        linkList = new List <LinkGenome>();
        for (int i = 0; i < parentGenome.linkList.Count; i++)
        {
            LinkGenome newLinkGenome = new LinkGenome(parentGenome.linkList[i].fromModuleID, parentGenome.linkList[i].fromNeuronID, parentGenome.linkList[i].toModuleID, parentGenome.linkList[i].toNeuronID, parentGenome.linkList[i].weight, true);
            float      randChance    = UnityEngine.Random.Range(0f, 1f);
            if (randChance < settings.mutationChance)
            {
                float randomWeight = Gaussian.GetRandomGaussian();
                newLinkGenome.weight = Mathf.Lerp(newLinkGenome.weight, randomWeight, settings.mutationStepSize);
            }
            linkList.Add(newLinkGenome);
        }

        // Add Brand New Link:
        //
        float randLink = UnityEngine.Random.Range(0f, 1f);

        if (randLink < settings.newLinkChance)
        {
            List <NeuronGenome> inputNeuronList = new List <NeuronGenome>();
            //List<NeuronGenome> hiddenNeuronList = new List<NeuronGenome>();
            List <NeuronGenome> outputNeuronList = new List <NeuronGenome>();
            for (int j = 0; j < bodyNeuronList.Count; j++)
            {
                if (bodyNeuronList[j].neuronType == NeuronGenome.NeuronType.In)
                {
                    inputNeuronList.Add(bodyNeuronList[j]);
                }
                if (bodyNeuronList[j].neuronType == NeuronGenome.NeuronType.Out)
                {
                    outputNeuronList.Add(bodyNeuronList[j]);
                }
            }
            for (int j = 0; j < hiddenNeuronList.Count; j++)
            {
                inputNeuronList.Add(hiddenNeuronList[j]);
                outputNeuronList.Add(hiddenNeuronList[j]);
            }

            // Try x times to find new connection -- random scattershot approach at first:
            // other methods:
            //      -- make sure all bodyNeurons are fully-connected when modifying body
            int maxChecks = 8;
            for (int k = 0; k < maxChecks; k++)
            {
                int randID  = UnityEngine.Random.Range(0, inputNeuronList.Count);
                NID fromNID = inputNeuronList[randID].nid;

                randID = UnityEngine.Random.Range(0, outputNeuronList.Count);
                NID toNID = outputNeuronList[randID].nid;

                // check if it exists:
                bool linkExists = false;
                for (int l = 0; l < linkList.Count; l++)
                {
                    if (linkList[l].fromModuleID == fromNID.moduleID && linkList[l].fromNeuronID == fromNID.neuronID && linkList[l].toModuleID == toNID.moduleID && linkList[l].toNeuronID == toNID.neuronID)
                    {
                        linkExists = true;
                        break;
                    }
                }

                if (linkExists)
                {
                }
                else
                {
                    float      randomWeight = Gaussian.GetRandomGaussian() * 0f;
                    LinkGenome linkGenome   = new LinkGenome(fromNID.moduleID, fromNID.neuronID, toNID.moduleID, toNID.neuronID, randomWeight, true);
                    //Debug.Log("New Link! from: [" + fromNID.moduleID.ToString() + ", " + fromNID.neuronID.ToString() + "], to: [" + toNID.moduleID.ToString() + ", " + toNID.neuronID.ToString() + "]");
                    linkList.Add(linkGenome);
                    break;
                }
            }
        }

        // Add Brand New Hidden Neuron:
        float randNeuronChance = UnityEngine.Random.Range(0f, 1f);

        if (randNeuronChance < settings.newHiddenNodeChance)
        {
            // find a link and expand it:
            int randLinkID = UnityEngine.Random.Range(0, linkList.Count);
            // create new neuron
            NeuronGenome newNeuronGenome = new NeuronGenome(NeuronGenome.NeuronType.Hid, -1, hiddenNeuronList.Count);
            hiddenNeuronList.Add(newNeuronGenome);
            // create 2 new links
            LinkGenome linkGenome1 = new LinkGenome(linkList[randLinkID].fromModuleID, linkList[randLinkID].fromNeuronID, newNeuronGenome.nid.moduleID, newNeuronGenome.nid.neuronID, 1f, true);
            LinkGenome linkGenome2 = new LinkGenome(newNeuronGenome.nid.moduleID, newNeuronGenome.nid.neuronID, linkList[randLinkID].toModuleID, linkList[randLinkID].toNeuronID, linkList[randLinkID].weight, true);

            // delete old link
            linkList.RemoveAt(randLinkID);
            // add new links
            linkList.Add(linkGenome1);
            linkList.Add(linkGenome2);

            //Debug.Log("New Neuron! " + newNeuronGenome.nid.neuronID.ToString() + " - from: [" + linkGenome1.fromModuleID.ToString() + ", " + linkGenome1.fromNeuronID.ToString() + "], to: [" + linkGenome2.toModuleID.ToString() + ", " + linkGenome2.toNeuronID.ToString() + "]");
        }
    }
示例#7
0
    public void InitializeAxons(float initialWeightMultiplier)
    {
        int numInputs = 0;

        for (int i = 0; i < bodyNeuronList.Count; i++)
        {
            if (bodyNeuronList[i].neuronType == NeuronGenome.NeuronType.In)
            {
                numInputs++;
            }
        }
        // !!!!! ===== UPGRADE NOTE: !!!!!!!!!!!!
        //  Add support for initial traditional hidden layers - generalize down to 0 to support all initializations
        // !!!!! ===== UPGRADE NOTE: !!!!!!!!!!!!

        // Create Hidden nodes TEMP!!!!
        for (int i = 0; i < numInputs; i++)
        {
            //NeuronGenome neuron = new NeuronGenome(NeuronGenome.NeuronType.Hid, 20, i);
            //brainGenome.neuronList.Add(neuron);
        }

        // Create initial connections -- :
        List <NeuronGenome> inputNeuronList = new List <NeuronGenome>();
        //List<NeuronGenome> hiddenNeuronList = new List<NeuronGenome>();
        List <NeuronGenome> outputNeuronList = new List <NeuronGenome>();

        for (int i = 0; i < bodyNeuronList.Count; i++)
        {
            if (bodyNeuronList[i].neuronType == NeuronGenome.NeuronType.In)
            {
                inputNeuronList.Add(bodyNeuronList[i]);
            }
            //if (brainGenome.neuronList[i].neuronType == NeuronGenome.NeuronType.Hid) {
            //    hiddenNeuronList.Add(brainGenome.neuronList[i]);
            //}
            if (bodyNeuronList[i].neuronType == NeuronGenome.NeuronType.Out)
            {
                outputNeuronList.Add(bodyNeuronList[i]);
            }
        }
        // Initialize fully connected with all weights Random
        for (int i = 0; i < outputNeuronList.Count; i++)
        {
            for (int j = 0; j < inputNeuronList.Count; j++)
            {
                float      randomWeight = Gaussian.GetRandomGaussian() * initialWeightMultiplier;
                LinkGenome linkGenome   = new LinkGenome(inputNeuronList[j].nid.moduleID, inputNeuronList[j].nid.neuronID, outputNeuronList[i].nid.moduleID, outputNeuronList[i].nid.neuronID, randomWeight, true);
                linkList.Add(linkGenome);
            }
        }

        /*for (int i = 0; i < outputNeuronList.Count; i++) {
         *  for(int j = 0; j < hiddenNeuronList.Count; j++) {
         *      float randomWeight = Gaussian.GetRandomGaussian() * initialWeightMultiplier;
         *      LinkGenome linkGenome = new LinkGenome(hiddenNeuronList[j].nid.moduleID, hiddenNeuronList[j].nid.neuronID, outputNeuronList[i].nid.moduleID, outputNeuronList[i].nid.neuronID, randomWeight, true);
         *      brainGenome.linkList.Add(linkGenome);
         *  }
         * }
         * for (int i = 0; i < hiddenNeuronList.Count; i++) {
         *  for (int j = 0; j < inputNeuronList.Count; j++) {
         *      float randomWeight = Gaussian.GetRandomGaussian() * initialWeightMultiplier;
         *      LinkGenome linkGenome = new LinkGenome(inputNeuronList[j].nid.moduleID, inputNeuronList[j].nid.neuronID, hiddenNeuronList[i].nid.moduleID, hiddenNeuronList[i].nid.neuronID, randomWeight, true);
         *      brainGenome.linkList.Add(linkGenome);
         *  }
         * }*/

        //PrintBrainGenome();
    }
示例#8
0
    public void InitializeAxons(float initialWeightMultiplier)
    {
        int numInputs = 0;

        for (int i = 0; i < bodyNeuronList.Count; i++)
        {
            if (bodyNeuronList[i].neuronType == NeuronGenome.NeuronType.In)
            {
                numInputs++;
            }
        }
        // Create Hidden nodes TEMP!!!!
        for (int i = 0; i < numInputs; i++)
        {
            NeuronGenome neuron = new NeuronGenome(NeuronGenome.NeuronType.Hid, -1, i);
            hiddenNeuronList.Add(neuron);
        }

        // Create initial connections -- :
        List <NeuronGenome> inputNeuronList = new List <NeuronGenome>();
        //List<NeuronGenome> hiddenNeuronList = new List<NeuronGenome>();
        List <NeuronGenome> outputNeuronList = new List <NeuronGenome>();

        for (int i = 0; i < bodyNeuronList.Count; i++)
        {
            if (bodyNeuronList[i].neuronType == NeuronGenome.NeuronType.In)
            {
                inputNeuronList.Add(bodyNeuronList[i]);
            }
            //if (brainGenome.neuronList[i].neuronType == NeuronGenome.NeuronType.Hid) {
            //    hiddenNeuronList.Add(brainGenome.neuronList[i]);
            //}
            if (bodyNeuronList[i].neuronType == NeuronGenome.NeuronType.Out)
            {
                outputNeuronList.Add(bodyNeuronList[i]);
            }
        }
        // Initialize fully connected with all weights Random
        for (int i = 0; i < outputNeuronList.Count; i++)
        {
            for (int j = 0; j < inputNeuronList.Count; j++)
            {
                float      randomWeight = Gaussian.GetRandomGaussian() * initialWeightMultiplier;
                LinkGenome linkGenome   = new LinkGenome(inputNeuronList[j].nid.moduleID, inputNeuronList[j].nid.neuronID, outputNeuronList[i].nid.moduleID, outputNeuronList[i].nid.neuronID, randomWeight, true);
                linkList.Add(linkGenome);
            }
        }
        for (int i = 0; i < outputNeuronList.Count; i++)
        {
            for (int j = 0; j < hiddenNeuronList.Count; j++)
            {
                float      randomWeight = Gaussian.GetRandomGaussian() * initialWeightMultiplier;
                LinkGenome linkGenome   = new LinkGenome(hiddenNeuronList[j].nid.moduleID, hiddenNeuronList[j].nid.neuronID, outputNeuronList[i].nid.moduleID, outputNeuronList[i].nid.neuronID, randomWeight, true);
                linkList.Add(linkGenome);
            }
        }
        for (int i = 0; i < hiddenNeuronList.Count; i++)
        {
            for (int j = 0; j < inputNeuronList.Count; j++)
            {
                float      randomWeight = Gaussian.GetRandomGaussian() * initialWeightMultiplier;
                LinkGenome linkGenome   = new LinkGenome(inputNeuronList[j].nid.moduleID, inputNeuronList[j].nid.neuronID, hiddenNeuronList[i].nid.moduleID, hiddenNeuronList[i].nid.neuronID, randomWeight, true);
                linkList.Add(linkGenome);
            }
        }

        //PrintBrainGenome();
        //Debug.Log("numAxons: " + linkList.Count.ToString());
    }