GetEpsilon() public static method

Computes the weight epsilon parameter.
public static GetEpsilon ( double min, double max, double inputs, double outputs ) : double
min double Minimum activation function value.
max double Maximum activation function value.
inputs double Number of inward connections to the current node.
outputs double Number of outward connections from the current node.
return double
Example #1
0
        /// <summary>
        /// Adds new connections for the specified node for the parent and child nodes.
        /// </summary>
        /// <param name="network">Current network.</param>
        /// <param name="node">Neuron being added.</param>
        /// <param name="parentNodes">Parent nodes that this neuron is connected with.</param>
        /// <param name="childNodes">Child nodes that this neuron is connected to.</param>
        /// <param name="epsilon">Weight initialization parameter.</param>
        /// <returns></returns>
        public static Network AddConnections(this Network network, Neuron node, IEnumerable <Neuron> parentNodes, IEnumerable <Neuron> childNodes, double epsilon = double.NaN)
        {
            if (epsilon == double.NaN)
            {
                epsilon = Edge.GetEpsilon(node.ActivationFunction.Minimum, node.ActivationFunction.Maximum, parentNodes.Count(), childNodes.Count());
            }

            if (parentNodes != null)
            {
                for (int i = 0; i < parentNodes.Count(); i++)
                {
                    network.AddEdge(Edge.Create(parentNodes.ElementAt(i), node, epsilon: epsilon));
                }
            }

            if (childNodes != null)
            {
                for (int j = 0; j < childNodes.Count(); j++)
                {
                    network.AddEdge(Edge.Create(node, childNodes.ElementAt(j), epsilon: epsilon));
                }
            }

            return(network);
        }
Example #2
0
        /// <summary>
        /// Creates a new fully connected deep neural network based on the supplied size and depth parameters.
        /// </summary>
        /// <param name="inputLayer">Neurons in the input layer.</param>
        /// <param name="outputLayer">Neurons in the output layer.</param>
        /// <param name="activationFunction">Activation function for the hidden and output layers.</param>
        /// <param name="outputFunction">(Optional) Output function of the the Nodes in the output layer (overrides the Activation function).</param>
        /// <param name="fnNodeInitializer">(Optional) Function to call for initializing new Nodes - supplying parameters for the layer and node index.</param>
        /// <param name="fnWeightInitializer">(Optional) Function to call for initializing the weights of each connection (including bias nodes).
        /// <para>Where int1 = Source layer (0 is input layer), int2 = Source Node, int3 = Target node in the next layer.</para></param>
        /// <param name="epsilon">Weight initialization parameter for random weight selection.  Weight will be in the range of: -epsilon to +epsilon.</param>
        /// <param name="hiddenLayers">An array of hidden neuron dimensions, where each element is the size of each layer (excluding bias nodes).</param>
        /// <returns>Returns an untrained neural network model.</returns>
        public static Network Create(this Network network, int inputLayer, int outputLayer, IFunction activationFunction, IFunction outputFunction = null, Func <int, int, Neuron> fnNodeInitializer = null,
                                     Func <int, int, int, double> fnWeightInitializer = null, double epsilon = double.NaN, params int[] hiddenLayers)
        {
            IFunction ident = new Ident();

            if (hiddenLayers == null || hiddenLayers.Length == 0)
            {
                hiddenLayers = new int[] { (int)System.Math.Ceiling((inputLayer + outputLayer + 1) * (2.0 / 3.0)) }
            }
            ;

            List <double> layers = new List <double>();

            layers.Add(inputLayer);
            foreach (int l in hiddenLayers)
            {
                layers.Add(l + 1);
            }
            layers.Add(outputLayer);

            if (fnNodeInitializer == null)
            {
                fnNodeInitializer = new Func <int, int, Neuron>((i, j) => new Neuron());
            }

            if (fnWeightInitializer == null)
            {
                fnWeightInitializer = new Func <int, int, int, double>((l, i, j) => {
                    double inputs  = (l > 0 ? layers[l - 1] : 0);
                    double outputs = (l < layers.Count - 1 ? layers[l + 1] : 0);
                    double eps     = (double.IsNaN(epsilon) ? Edge.GetEpsilon(activationFunction.Minimum, activationFunction.Maximum, inputs, outputs) : epsilon);
                    return(Edge.GetWeight(eps));
                });
            }

            // creating input nodes
            network.In    = new Neuron[inputLayer + 1];
            network.In[0] = network.AddNode(new Neuron(true)
            {
                Label = "B0", ActivationFunction = ident, NodeId = 0, LayerId = 0
            });

            for (int i = 1; i < inputLayer + 1; i++)
            {
                network.In[i]       = fnNodeInitializer(0, i);
                network.In[i].Label = (network.In[i].Label ?? string.Format("I{0}", i));
                network.In[i].ActivationFunction = (network.In[i].ActivationFunction ?? ident);
                network.In[i].LayerId            = 0;
                network.In[i].NodeId             = i;

                network.AddNode(network.In[i]);
            }

            Neuron[] last = null;
            for (int layerIdx = 0; layerIdx < hiddenLayers.Length; layerIdx++)
            {
                // creating hidden nodes
                Neuron[] layer = new Neuron[hiddenLayers[layerIdx] + 1];
                layer[0] = network.AddNode(new Neuron(true)
                {
                    Label = $"B{layerIdx + 1}", ActivationFunction = ident, LayerId = layerIdx + 1, NodeId = 0
                });
                for (int i = 1; i < layer.Length; i++)
                {
                    layer[i]       = fnNodeInitializer(layerIdx + 1, i);
                    layer[i].Label = (layer[i].Label ?? String.Format("H{0}.{1}", layerIdx + 1, i));
                    layer[i].ActivationFunction = (layer[i].ActivationFunction ?? activationFunction);
                    layer[i].OutputFunction     = layer[i].OutputFunction;
                    layer[i].LayerId            = layerIdx + 1;
                    layer[i].NodeId             = i;

                    network.AddNode(layer[i]);
                }

                if (layerIdx > 0 && layerIdx < hiddenLayers.Length)
                {
                    // create hidden to hidden (full)
                    for (int i = 0; i < last.Length; i++)
                    {
                        for (int x = 1; x < layer.Length; x++)
                        {
                            network.AddEdge(Edge.Create(last[i], layer[x], weight: fnWeightInitializer(layerIdx, i, x), epsilon: epsilon));
                        }
                    }
                }
                else if (layerIdx == 0)
                {
                    // create input to hidden (full)
                    for (int i = 0; i < network.In.Length; i++)
                    {
                        for (int j = 1; j < layer.Length; j++)
                        {
                            network.AddEdge(Edge.Create(network.In[i], layer[j], weight: fnWeightInitializer(layerIdx, i, j), epsilon: epsilon));
                        }
                    }
                }

                last = layer;
            }

            // creating output nodes
            network.Out = new Neuron[outputLayer];
            for (int i = 0; i < outputLayer; i++)
            {
                network.Out[i]       = fnNodeInitializer(hiddenLayers.Length + 1, i);
                network.Out[i].Label = (network.Out[i].Label ?? String.Format("O{0}", i));
                network.Out[i].ActivationFunction = (network.Out[i].ActivationFunction ?? activationFunction);
                network.Out[i].OutputFunction     = (network.Out[i].OutputFunction ?? outputFunction);
                network.Out[i].LayerId            = hiddenLayers.Length + 1;
                network.Out[i].NodeId             = i;

                network.AddNode(network.Out[i]);
            }

            // link from (last) hidden to output (full)
            for (int i = 0; i < network.Out.Length; i++)
            {
                for (int j = 0; j < last.Length; j++)
                {
                    network.AddEdge(Edge.Create(last[j], network.Out[i], weight: fnWeightInitializer(hiddenLayers.Length, j, i), epsilon: epsilon));
                }
            }

            return(network);
        }