/// <summary>
        /// Pomnoziti sve ulaze sa tezinama.
        /// Sabrati sve rezultate mnozaca. Kao povratnu vrednost
        /// vratiti vrednost aktivacione funkije za vrednost suma
        /// svih mnozaca
        /// </summary>
        /// <param name="x">x is a vector of inputs</param>
        /// <returns></returns>
        public double forward(List <double> x)
        {
            List <double> inputs = new List <double>(x);

            inputs.Add(1.0); //bias

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

            //TODO 6: Izracunati vrednost na izlazu vestackog neurona
            for (int i = 0; i < inputs.Count; i++)
            {
                MultiplyNode mn     = this.multiplyNodes[i];
                double       weight = mn.x[1];

                List <double> newInputs = new List <double>();
                newInputs.Add(inputs[i]);
                newInputs.Add(weight);

                forSum.Add(mn.forward(newInputs));
            }

            double summed = this.sumNode.forward(forSum);
            double summed_act;


            if (activation.Equals("sigmoid"))
            {
                summed_act = this.activation_node.forward(summed);
            }
            else
            {
                summed_act = this.activation_node2.forward(summed);
            }
            return(summed_act);
        }
        /// <summary>
        /// </summary>
        /// <param name="dz"></param>
        /// <returns></returns>
        public List <double> backward(List <double> dz)
        {
            List <double> dw = new List <double>();
            List <double> dx = new List <double>();
            double        backward_signal = dz.Sum();

            if (this.activation.Equals("sigmoid"))
            {
                backward_signal = this.activation_node.backward(backward_signal);
            }
            else
            {
                backward_signal = this.activation_node2.backward(backward_signal);
            }

            List <double> backWard = this.sumNode.backward(backward_signal);

            for (int i = 0; i < this.multiplyNodes.Count; i++)
            {
                MultiplyNode  mn      = this.multiplyNodes[i];
                List <double> retVals = mn.backward(backWard[i]);
                dx.Add(retVals[0]);
                dw.Add(retVals[1]);
            }
            //https://en.wikipedia.org/wiki/Gradient_descent
            //df/dx1, df/dx2...
            this.gradients.Add(dw);

            return(dx);
        }
Пример #3
0
        /// <summary>
        /// Greska se propagira u nazad kroz aktivacionu funkciju,
        /// preko sabiraca, do svakog pojedinacnog mnozaca
        /// </summary>
        /// <param name="dz"></param>
        /// <returns></returns>
        public List <double> backward(List <double> dz)
        {
            //greska svakog ulaza
            List <double> dw = new List <double>();
            List <double> dx = new List <double>();
            double        backward_signal = dz.Sum();

            //TODO 7: Izvrsiti propagaciju signala u nazad, prvo kroz aktivacionu funkciju,
            //        onda kroz sabirac pa kroz svaki pojedinacan mnozac
            backward_signal = this.activation_node.backward(backward_signal);

            //dobije se nazad lista gresaka po mnoziocima koje ulaze u sabirac
            //z = x + y ===> dx = dz && dy = dz, te se dobije samo lista dz-ova onoliko puta koliko ima sabiraoca
            List <double> sabiracListaGreska = this.sumNode.backward(backward_signal);

            //za svaki sabiraoc (koji je ustv mnozac), izracunati gresku po promenljivoj i po tezini
            for (int i = 0; i < sabiracListaGreska.Count; i++)
            {
                MultiplyNode  mn = this.multiplyNodes[i];
                List <double> parPromenljivaTezinaGreska = mn.backward(sabiracListaGreska[i]);
                dx.Add(parPromenljivaTezinaGreska[0]);
                dw.Add(parPromenljivaTezinaGreska[1]);
            }

            //https://en.wikipedia.org/wiki/Gradient_descent
            //df/dx1, df/dx2...
            this.gradients.Add(dw);

            return(dx);
        }
Пример #4
0
        private static GaussianRandom grnd = new GaussianRandom(); //gausova raspodela za random vrednosti

        /// <summary>
        /// https://en.wikipedia.org/wiki/Artificial_neuron
        /// ulaz1*tezina1
        /// ulaz1*tezina2
        /// bias(+1*tezina)
        /// sve se sabere
        /// provuce se kroz aktivacionu funkciju
        /// </summary>
        /// <param name="n_inputs"></param>
        /// <param name="activation"> String naziv aktivacione funkcije </param>
        public NeuronNode(int n_inputs, string activation)
        {
            this.n_inputs        = n_inputs;
            this.multiplyNodes   = new List <MultiplyNode>();   //for inputs and weights
            this.sumNode         = new SumNode();               //for sum of inputs*weights
            this.previous_deltas = new List <double>();         //vrednost delti u prosloj iteraciji
            this.gradients       = new List <List <double> >(); //lokalni gradijenti
            MultiplyNode mulNode;

            //init inputs
            //collect inputs and corresponding weights
            for (int i = 0; i < this.n_inputs; i++)
            {
                mulNode = new MultiplyNode();
                double b = grnd.NextGaussian(0.3, 0.5);
                mulNode.x = new List <double>()
                {
                    1.0, b
                };
                this.multiplyNodes.Add(mulNode);
                previous_deltas.Add(0.0);
            }

            //init bias node and weight
            mulNode = new MultiplyNode();
            double m = grnd.NextGaussian(0.0, 0.01);

            mulNode.x = new List <double>()
            {
                1.0, m
            };
            this.multiplyNodes.Add(mulNode);
            previous_deltas.Add(0.0);

            // TODO: Ovde dodajem ako dodajem neku drugu aktivacionu funkciju

            /*
             * if else(activation.Equals("TangesHiperbolic").....
             */
            if (activation.Equals("sigmoid"))
            {
                this.activation_node = new SigmoidNode();
            }
            else if (activation.Equals("tanh"))
            {
                this.activation_node = new TanhNode();
            }
            else
            {
                throw new NotImplementedException("Activation function is not supported");
            }
        }
        /// <summary>
        /// https://en.wikipedia.org/wiki/Artificial_neuron
        /// input1*weight1
        /// input1*weight2
        /// bias(+1*weight)
        /// </summary>
        /// <param name="n_inputs"></param>
        /// <param name="activation"></param>
        public NeuronNode(int n_inputs, string activation)
        {
            this.n_inputs        = n_inputs;
            this.multiplyNodes   = new List <MultiplyNode>();   //for inputs and weights
            this.sumNode         = new SumNode();               //for sum of inputs*weights
            this.previous_deltas = new List <double>();         // values of las iteration
            this.gradients       = new List <List <double> >(); //local gradients
            MultiplyNode mulNode;

            //init inputs
            //collect inputs and corresponding weights
            for (int i = 0; i < this.n_inputs; i++)
            {
                mulNode = new MultiplyNode();
                double b = grnd.NextGaussian(0.3, 0.5);
                mulNode.x = new List <double>()
                {
                    1.0, b
                };
                this.multiplyNodes.Add(mulNode);
                previous_deltas.Add(0.0);
            }

            //init bias node and weight
            mulNode = new MultiplyNode();
            double m = grnd.NextGaussian(0.0, 0.01);

            mulNode.x = new List <double>()
            {
                1.0, m
            };
            this.multiplyNodes.Add(mulNode);
            previous_deltas.Add(0.0);

            if (activation.Equals("sigmoid"))
            {
                this.activation_node = new SigmoidNode();
            }
            if (activation.Equals("relu"))
            {
                this.activation_node2 = new RelUNode();
            }
            else
            {
                throw new NotImplementedException("Activation function is not supported");
            }

            this.activation = activation;
        }
Пример #6
0
        /// <summary>
        /// https://en.wikipedia.org/wiki/Artificial_neuron
        /// ulaz1*tezina1
        /// ulaz1*tezina2
        /// bias(+1*tezina)
        /// sve se sabere
        /// provuce se kroz aktivacionu funkciju
        /// </summary>
        /// <param name="n_inputs"></param>
        /// <param name="activation"></param>
        public NeuronNode(int n_inputs, string activation)
        {
            this.n_inputs        = n_inputs;
            this.multiplyNodes   = new List <MultiplyNode>();   //for inputs and weights
            this.sumNode         = new SumNode();               //for sum of inputs*weights
            this.previous_deltas = new List <double>();         //vrednost delti u prosloj iteraciji
            this.gradients       = new List <List <double> >(); //lokalni gradijenti
            MultiplyNode mulNode;

            //init inputs
            //collect inputs and corresponding weights
            for (int i = 0; i < this.n_inputs; i++)
            {
                mulNode   = new MultiplyNode();
                mulNode.x = new List <double>()
                {
                    1.0, (rnd.NextDouble() - 0.5) / 50.0
                };                                                                      //izemdju -0.1 i 0.1
                this.multiplyNodes.Add(mulNode);
                previous_deltas.Add(0.0);
            }

            //init bias node and weight
            mulNode   = new MultiplyNode();
            mulNode.x = new List <double>()
            {
                1.0, (rnd.NextDouble() - 0.5 / 50.0)
            };                                                                       // -0.01 do 0.01
            this.multiplyNodes.Add(mulNode);
            previous_deltas.Add(0.0);

            if (activation.Equals("sigmoid"))
            {
                this.activation_node = new SigmoidNode();
            }
            else
            {
                throw new NotImplementedException("Activation function is not supported");
            }
        }
Пример #7
0
        /// <summary>
        /// Pomnoziti sve ulaze sa tezinama.
        /// Sabrati sve rezultate mnozaca. Kao povratnu vrednost
        /// vratiti vrednost aktivacione funkije za vrednost suma
        /// svih mnozaca
        /// </summary>
        /// <param name="x">x is a vector of inputs</param>
        /// <returns></returns>
        public double forward(List <double> x)
        {
            /*
             * List<double> inputs = new List<double>(x);
             * inputs.Add(1.0); //bias
             *
             * List<double> forSum = new List<double>();
             * //TODO 6: Izracunati vrednost na izlazu vestackog neurona
             * for (int i = 0; i < inputs.Count; i++)
             * {
             *  double w_i = this.multiplyNodes[i].x[1]; //uzmi tezinu iz mnozackog cvora, drugi parametar
             *  MultiplyNode mn = new MultiplyNode();
             *
             *
             *  List<double> parTezinaInput = new List<double>();
             *
             *
             *  parTezinaInput.Add(w_i);
             *  parTezinaInput.Add(inputs[i]);
             *
             *  //mora ovako jer mn.forward trazi parametre
             *
             *
             *  //pomnozi i dodaj u buduci sabirac
             *  forSum.Add(mn.forward(parTezinaInput));
             *
             * }
             *
             * double summed = 0.0;
             * //SumNode sumNode = new SumNode();
             * summed = sumNode.forward(forSum);
             *
             * // dobijena vrednost se propusti kroz aktivacionu funkciju
             * double summed_act = this.activation_node.forward(summed);
             * return summed_act;
             */


            List <double> inputs = new List <double>(x);

            inputs.Add(1.0); //bias

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

            //TODO 6: Izracunati vrednost na izlazu vestackog neurona
            for (int i = 0; i < inputs.Count; i++)
            {
                MultiplyNode mn     = this.multiplyNodes[i];
                double       weight = mn.x[1];

                List <double> newInputs = new List <double>();
                newInputs.Add(inputs[i]);
                newInputs.Add(weight);

                forSum.Add(mn.forward(newInputs));
            }

            double summed = this.sumNode.forward(forSum);

            // dobijena vrednost se propusti kroz aktivacionu funkciju
            double summed_act = this.activation_node.forward(summed);

            return(summed_act);
        }