Example #1
0
        /// <summary>
        /// Helper mehtod: Selects a pair of nurons at random from diffrent
        /// levels of the network. The nurons are always listed in order. It
        /// returns false if it was ubale to generate a valid pair.
        /// </summary>
        /// <param name="n1">The lower level nuron</param>
        /// <param name="n2">The upper level nuron</param>
        private bool RandPair(out NuronOld n1, out NuronOld n2)
        {
            //generates two random nurons
            n1 = RandNuron();
            n2 = RandNuron();

            int count = 0;

            //keeps searching while the nurons are on the same level
            while (n1.Level == n2.Level && count < MAX_TRY)
            {
                NuronOld n3 = RandNuron();
                n1 = n2;
                n2 = n3;
                count++;
            }

            //swaps the nurons if they are out of order
            if (n1.Level > n2.Level)
            {
                NuronOld n3 = n1;
                n1 = n2;
                n2 = n3;
            }

            //indicates if we found a valid pair
            return(count < MAX_TRY);
        }
Example #2
0
        /// <summary>
        /// Adds a nuron to the network at the given level and with the given
        /// activation function. It returns null if it was unable to add the nuron.
        /// </summary>
        /// <param name="func">Activation function of the nuron</param>
        /// <param name="level">Level of the nuron</param>
        /// <returns>The inserted nuron</returns>
        public NuronOld AddNuron(ActFunc func, int level)
        {
            //clamps the level to be within range
            if (level > MAX_LV)
            {
                level = MAX_LV;
            }
            if (level < 0)
            {
                level = 0;
            }

            //tries to generate a random index
            int index = RandIndex();

            if (index < 0)
            {
                return(null);
            }

            //creates the node and adds it
            NuronOld n = new NuronOld(this, func, level, index);

            nurons.Add(index, n);

            return(n);
        }
Example #3
0
        /// <summary>
        /// Helper method: Finds an axon in the curent network that matches a
        /// target axon from another network. If no sucth match can be found,
        /// it returns null instead.
        /// </summary>
        /// <param name="other">Target axon</param>
        /// <returns>A matching axon</returns>
        private Axon FindMatch(Axon other)
        {
            //first atempts to find the target nuron
            NuronOld n1 = nurons.GetValue(other.Target);

            if (n1 == null)
            {
                return(null);
            }

            //obtains the axon from the target
            return(n1.GetAxon(other.Source));
        }
Example #4
0
        /// <summary>
        /// Clones a given network by make a deep copy of the internal
        /// structor, so that the clone may be manipulated without effecting
        /// the original. It also replaces the internal random number generator
        /// with a potentialy diffrent generator.
        /// </summary>
        /// <param name="rng">Random number generator</param>
        /// <param name="other">Network to clone</param>
        private NetworkCPP(VRandom rng, NetworkCPP other)
        {
            //copies the RNG by refrence
            this.rng = rng;

            //creates a new table with the same size
            int size = other.nurons.Buckets;

            nurons = new TableOpen <Int32, NuronOld>(size);

            //makes a deep copy of the former network's structor
            foreach (var pair in other.nurons)
            {
                NuronOld copy = new NuronOld(this, pair.Item);
                nurons.Add(pair.Key, copy);
            }
        }
Example #5
0
        /// <summary>
        /// Expands the curent nural net, in place, by either inserting a
        /// new node along a pre-existing edge or creating a new edge. The
        /// probibility of either event occoring is determined by the
        /// existing topology.
        /// </summary>
        public void ExpandSelf()
        {
            NuronOld n1, n2;

            //generates a pair of random nurons
            bool test   = RandPair(out n1, out n2);
            Axon target = n2.GetAxon(n1.Index);

            if (test && target == null)
            {
                //creates a new axon between the nurons
                double weight = rng.RandGauss() * SDN;
                n2.AddAxonInit(n1, weight);
            }
            else if (test && !target.Enabled)
            {
                //reinitilises the axon with a new weight
                target.Weight  = rng.RandGauss() * SDN;
                target.Enabled = true;
            }
            else if ((n2.Level - n1.Level) > 3)
            {
                //disables the target edge
                double weight = target.Weight;
                target.Enabled = false;

                //creates a new node with a random funciton
                int     index = RandIndex();
                int     level = (n2.Level + n1.Level) / 2;
                ActFunc func  = RandFunc();

                //aborts the operation if we fail to insert
                if (index < 0)
                {
                    return;
                }

                //inserts the node into our data-structor
                NuronOld nx = new NuronOld(this, func, level, index);
                nurons.Add(index, nx);

                //adds axons to replace the missing axon
                nx.AddAxonInit(n1, 1.0);
                n2.AddAxonInit(nx, weight);
            }
        }
Example #6
0
        /// <summary>
        /// Preterbs the current neural net by some random amount without
        /// creating a clone. The rate of mutaiton determins how many of the
        /// network connections are preturbed. For exampe, a mutation rate
        /// of 0.5 indicates that half the weights will be perturbed.
        /// </summary>
        /// <param name="rate">Rate of mutation</param>
        public void MutateSelf(double rate)
        {
            //clamps the rate to be between zero and one
            rate = VMath.Clamp(rate);

            if (rng.RandBool(P_Node))
            {
                //changes the activation funciton of a single node
                NuronOld node = RandNuron();
                node.Func = RandFunc();
                return;
            }

            //lists all the axons in the network
            var axons = ListAxons();

            foreach (Axon ax in axons)
            {
                //mutates weights based on the rate of mutation
                if (rng.RandBool(1.0 - rate))
                {
                    continue;
                }

                if (ax.Enabled)
                {
                    //permutes the weight by a small amount
                    double delta = rng.RandGauss() * SDS;
                    ax.Weight = ax.Weight + delta;
                }
                else
                {
                    //resets the neuron to a small weight
                    ax.Weight  = rng.RandGauss() * SDS;
                    ax.Enabled = true;
                }
            }
        }