Esempio n. 1
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);
        }
Esempio n. 2
0
        internal override Vector <double> PropogateError(Vector <double> outputError, double errorWeight, Vector <double> inputCacheOverride = null, Vector <double> additionalError = null)
        {
            Vector <double> inputError;

            if (inputCacheOverride == null)
            {
                inputError = outputError.PointwiseMultiply(ActFunc.Derivative(InputCache * Weights));
            }
            else
            {
                inputError = outputError.PointwiseMultiply(ActFunc.Derivative(inputCacheOverride * Weights));
            }

            if (additionalError != null)
            {
                inputError -= additionalError;
            }

            BiasErrorCache   -= inputError * errorWeight;
            WeightErrorCache -= errorWeight * InputCache.OuterProduct(inputError);
            if (RegMode == RegularizationMode.L2)
            {
                WeightErrorCache -= errorWeight * NormalizationWeight * Weights;
            }
            return(Weights * inputError);
        }
Esempio n. 3
0
        internal Nuron(NetworkAuto network, Nuron other)
        {
            this.network = network;
            this.func    = other.func;
            this.index   = other.index;
            this.level   = other.level;

            this.value = 0.0;
            this.vprev = 0.0;
        }
Esempio n. 4
0
        /// <summary>
        /// Creates a new nuron on a given network, with a given activation
        /// function and level depth. An index is required to be able to
        /// refrence the nuron from outside the network.
        /// </summary>
        /// <param name="network">Network on wich to create the nuron</param>
        /// <param name="func">Activation funciton of the nuron</param>
        /// <param name="index">Index of the nuron</param>
        /// <param name="level">Level of the nuron</param>
        internal Nuron(NetworkAuto network, ActFunc func, int index, int level)
        {
            this.network = network;
            this.func    = func;
            this.index   = index;
            this.level   = level;

            this.value = 0.0;
            this.vprev = 0.0;
        }
Esempio n. 5
0
        /// <summary>
        /// Creates a new nuron on a given network, with a given activation
        /// function and level depth. An index is required to be able to
        /// refrence the nuron from outside the network.
        /// </summary>
        /// <param name="network">Network on wich to create the nuron</param>
        /// <param name="func">Activation funciton of the nuron</param>
        /// <param name="level">Level of the nuron</param>
        /// <param name="index">Index of the nuron</param>
        internal NuronOld(NetworkCPP network, ActFunc func, int level, int index)
        {
            this.network = network;
            this.func    = func;
            this.level   = level;
            this.index   = index;

            inputs = new VListArray <Axon>();
            value  = 0.0;
        }
Esempio n. 6
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);
            }
        }
Esempio n. 7
0
        internal override Vector <double> PropogateError(Vector <double> outputError, double errorWeight, Vector <double> inputCacheOverride = null, Vector <double> additionalError = null)
        {
            if (additionalError != null)
            {
                throw new NNException("Additional error is not supported for Convolutional Layers");
            }
            int             nNodes           = OutputHeight * OutputWidth;
            int             nInputNodes      = InputHeight * InputWidth;
            Vector <double> directInputError = 10 * outputError.PointwiseMultiply(ActFunc.Derivative(DirectInputCache)); // DEBUG 10*
            Vector <double> inputError       = new DenseVector(InputDimension);

            for (var channel = 0; channel < InputDepth; channel++)
            {
                for (var f = 0; f < NFilters; f++)
                {
                    int outputLayer = channel * NFilters + f;
                    for (var i = 0; i < OutputHeight; i++)
                    {
                        for (var j = 0; j < OutputWidth; j++)
                        {
                            double nodeError = directInputError[outputLayer * nNodes + i * OutputWidth + j];
                            BiasErrorCache[f] -= errorWeight * nodeError / nNodes; // Average the update over all instances of the same filter.

                            // Get the matrix of weight errors by multiplying the nodeError by the matrix in the input cache.
                            Matrix <double> weightError = new DenseMatrix(Weights[f].RowCount, Weights[f].ColumnCount);
                            for (var m = 0; m < weightError.RowCount; m++)
                            {
                                for (var n = 0; n < weightError.ColumnCount; n++)
                                {
                                    int inputIndex = channel * nInputNodes + (m + i * Stride) * InputWidth + n + j * Stride;
                                    weightError[m, n]      = nodeError * InputCache[inputIndex];
                                    inputError[inputIndex] = Weights[f][m, n] * nodeError;
                                }
                            }

                            WeightErrorCache[f] -= errorWeight * weightError / nNodes; // Average the update over all instances of the same filter.
                        }
                    }
                }
            }

            return(inputError);
        }
Esempio n. 8
0
        /// <summary>
        /// Creates a copy of a given nuron for a given network. All of the
        /// refrences to axons in the old network, now point to axons in
        /// the new network. All other values remain the same.
        /// </summary>
        /// <param name="network">The network containing this nuron</param>
        /// <param name="other">Another neuron to copy its values</param>
        internal NuronOld(NetworkCPP network, NuronOld other)
        {
            //sets the network refrence to the new network
            this.network = network;

            //copies the other vlaues
            func  = other.func;
            level = other.level;
            value = other.value;

            inputs = new VListArray <Axon>(other.inputs.Count);

            //makes a deep copy of the list of inputs
            foreach (Axon ax in other.inputs)
            {
                Axon clone = new Axon(ax);
                this.inputs.Add(clone);
            }
        }
Esempio n. 9
0
        internal override Vector <double> Process(Vector <double> input)
        {
            InputCache = input;

            for (var i = 0; i < OutputHeight; i++)
            {
                for (var j = 0; j < OutputWidth; j++)
                {
                    for (var inputFrame = 0; inputFrame < InputDepth; inputFrame++)
                    {
                        for (var f = 0; f < NFilters; f++)
                        {
                            // (inputFrame * NFilters + f) =  the output frame
                            // OutputHeight * OutputWidth = Number of pixels per frame
                            int outputIndex = (inputFrame * NFilters + f) * OutputHeight * OutputWidth + i * OutputWidth + j;
                            DirectInputCache[outputIndex] = ApplyFilter(input, inputFrame, f, i * Stride, j * Stride);
                        }
                    }
                }
            }
            return(10 * (ActFunc.Of(DirectInputCache) - 0.5));  // DEBUG 10*
        }
Esempio n. 10
0
 internal NuronComp(ActFunc func)
 {
     this.func  = func;
     this.value = 0.0;
 }
Esempio n. 11
0
 internal override Vector <double> Process(Vector <double> input)
 {
     InputCache = input;
     return(ActFunc.Of(input * Weights));
 }
Esempio n. 12
0
        private void Expand(VRandom rng)
        {
            Nuron n1, n2;

            //generates a pair of random nurons on diffrent levels
            bool pass = GetRandomPair(rng, out n1, out n2);

            if (!pass)
            {
                return;
            }

            //determins if this should be a recurent conneciton
            bool testrec = recurent;

            testrec = testrec && !n1.IsInput;
            testrec = testrec && rng.RandBool(P_Recur);

            if (testrec)
            {
                Nuron nx = n1;
                n1 = n2;
                n2 = nx;
            }

            //creates a temporary axon between the two nurons
            double w    = rng.RandGauss() * SD_NEW;
            Axon   temp = new Axon(n1.Index, n2.Index, w);

            //atempts to gain the actual axon if it exists
            Axon actual = axons.GetValue(temp.Index);

            if (actual == null)
            {
                //adds the new axon into the network
                axons.Add(temp.Index, temp);
            }
            else if (actual.Enabled == false)
            {
                //reneables the axon and updates it weight
                actual.Enabled = true;
                actual.Weight  = temp.Weight;
            }
            else
            {
                //determins if we are able to insert a new node
                int nid1 = GetRandomIndex(rng);
                if (nid1 < 0)
                {
                    return;
                }

                //sets the level of the new node in the middle
                if (Math.Abs(n1.Level - n2.Level) < 3)
                {
                    return;
                }
                int level = (n1.Level + n2.Level) / 2;

                //adds a new node to the network
                ActFunc act = GetRandomActivation(rng);
                Nuron   n3  = new Nuron(this, act, nid1, level);
                nurons.Add(n3.Index, n3);

                //inserts two new axons where the old one used to be
                int nid0 = actual.Source;
                int nid2 = actual.Target;

                //Axon ax1 = new Axon(nid0, nid1, actual.Weight);
                //Axon ax2 = new Axon(nid1, nid2, temp.Weight);

                Axon ax1 = new Axon(nid0, nid1, actual.Weight);
                Axon ax2 = new Axon(nid1, nid2, 1.0);

                //we use the overwitre comand because there may be hash collisions
                axons.Overwrite(ax1.Index, ax1);
                axons.Overwrite(ax2.Index, ax2);

                //deactivates the old axon
                actual.Enabled = false;
            }
        }