/// <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); }
/// <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); }
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; }
/// <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"); } }
/// <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); }