Advertisement

Having problems with neural network training C#

Started by November 19, 2010 08:59 AM
22 comments, last by sjaakiejj 14 years, 2 months ago


This is the function to calculate the 'error' for the output layer:
ErrorOut = Output * (Activation_Potential)*(Target - Output)

Though the more correct wording would be delta.

This is the function for all the other layers
Error = Output * ActivationPotential * SUM(Weights * ErrorOut)


This is the one you are using.
     //calculate errorsfor (int c = 0; c < Y.Length / 2; c++){    errors[c] = TS[a, 1, c] - Y[c, 0];}//last level (Y)for (int c = 0; c < Y.Length/2; c++){    Y[c, 1] = (float)(errors[c] * B * (1 - Math.Pow(Y[c, 0], 2)));}//then change the valuesfor (int d = 0; d < Y.Length/2; d++){     //error*Beta*(1-Y^2)*sum     H3[c, 1] = (float)(B * (1-Math.Pow(Y[d,0], 2)) * sum);}


Now to be honest with you, this part of the code doesn't make any sense. You're using an array of inputs into the first layer to calculate your delta? Following on which you use the Beta to calculate Y, and then use the beta again to calculate the error? If I look at the equations, the activation levels from the previous level are used instead of the TS, and the Beta is not used in the calculation to Delta at all.

In pseudo code the Neural Network would probably look something like this:

//The following code belongs to a loop which goes through every sample in the traindata.for each node in InputLayer  activationLevel[Node] = neuron(Weights(Node), TD(Node))endfor each node in otherLayers  activationLevel[Node] = neuron(Weights(Node), activationLevel[prevNodes]) end//Output Layer only has one deltadeltas[outputLayer] = activationLevel[outNode] * (activationPotential) * (labels - activationLevel[outNode])for each node in lastHiddenLayer  deltas[node] = activationLevel[node] * activationPotential * WeightsToOutput * deltas[outputLayer]end//The rest is pretty similar, you can work that out by yourself//After you get the deltas, you update the weights. Then you iterate through this loop //again for the next sample.


Since I only made that pseudo code quickly, there may be some mistakes in it, but you get the general idea. Hope this helps.
Okay, in fact I was detecting some strange code, for example:

Y[c, 1] = (float)(errors[c] * B * (1 - Math.Pow(Y[c, 0], 2)));

I really don't know where I read the (1-Y^2), it is completely nonsense!

So, I suppose that the update code for now is 'correct'.
I think I should probably make a pseudocode for everything and THEN transpose it to C# code.
Thanks, I'll see what I made out of this and I'll post my results.

Well, let's see if I understood, following your explanation I modified my code in this way:

           //########### BACK-PROPAGATION ###########                //calculate errors using optimal output                for (int c = 0; c < Y.Length / 2; c++)                {                    errors[c] = TS[a, 1, c] - Y[c, 0];                }                //last level (Y)                for (int c = 0; c < Y.Length / 2; c++)                {                    //Y[c, 1] = sigma(Y[c, 1]) * errors[c];                    Y[c, 1] = Y[c, 0] * B * errors[c];                }                //level H3                for (int c = 0; c < H3.Length / 2; c++)                {                    float sum = 0;                    //first sum all the values                    for (int d = 0; d < Y.Length/2; d++)                    {                        sum += W4[(d * (H3.Length / 2)) + c] * Y[d,1];                    }                    //then change the values                    for (int d = 0; d < Y.Length/2; d++)                    {                        H3[c, 1] = H1[c, 0] * B * sum;                    }                }


But I've a huge question (now my knowledge is stagging), what do you mean for (Activation_Potential) in these two equations?:

ErrorOut = Output * (Activation_Potential)*(Target - Output)
Error = Output * ActivationPotential * SUM(Weights * ErrorOut)

I think you don't mean Beta (as I left written in my code) but I neither now what else is it, thresholds? or activation functions like BTanh(value)?
Sorry if I have so many troubles (and sorry for the english)
What can you suggest me?
Advertisement
I took Activation Potential from your notes, but it means this:
Activation_Potential = 1 - activationLevel

But yeah I'd definitely suggest working something like this out in Pseudo code first, and then implement it in C#. Neural Networks aren't exactly easy to implement, considering that the one you're trying to implement is actually the simplest form of it.
Ok, so, not for bothering xD
Could you explain me your pseudo code? I didn't understand your neuron(,) part of it
Hey I found a way to work on it!!
I've posted down here my code, it's a bit more complex but it can be modified, I made that you can build the neural network with the number of layer and neurons you want with AddLayer(), then you add all the weights with ComputeWeigth().

    class NNOperator    {        public NNOperator(int inputs,int outputs)        {            layers = new List<float[,]>();            weights = new List<float[]>();            layers.Add(new float[inputs, 2]);            layers.Add(new float[outputs, 2]);        }        public void AddLayer(int neurons)        {            weights.Clear();            layers.Insert(1, new float[neurons, 2]);        }        public void ComputeWeights()        {            weights.Clear();            for (int a = 0; a < layers.Count()-1; a++)            {                weights.Add(new float[layers[a].GetLength(0) * layers[a + 1].GetLength(0)]);            }        }        public List<float[,]> layers;        public List<float[]> weights;        public float[] Update(float[] inputs)        {            float[] output = new float[layers.Last().GetLength(0)];            //Copy input values            for (int a = 0; a < layers[0].GetLength(0); a++)            {                layers[0][a, 0] = inputs[a];            }            //Cycle through layers            for (int layer = 0; layer < layers.Count() - 1; layer++)            {                //Cycle through neurons of the next layer                for (int next = 0; next < layers[layer+1].GetLength(0); next++)                {                    //Reset neuron temporary value                    layers[layer+1][next, 0] = 0;                    //Cycle through neurons of the current layer                    for (int prev = 0; prev < layers[layer].GetLength(0); prev++)                    {                        //H2[a, 0] += H1[b, 0] * W2[(a * H1.Length / 2) + b];                        layers[layer + 1][next, 0] += layers[layer][prev, 0] * weights[layer][(next * layers[layer].GetLength(0)) + prev];                    }                    //If the temporary value doesn't exceed threshold, reset it                    if (layers[layer + 1][next, 0] < layers[layer + 1][next, 1])                    {                        layers[layer + 1][next, 0] = 0;                    }                }            }            //Transfer values to output            for (int a = 0; a < output.Length; a++)            {                output[a] = layers.Last()[a, 0];            }            return output;        }    }


For testing the update method I built a neural network like the XOR neural network you see in this page: http://www.heatonresearch.com/course/intro-neural-nets-cs/1
And I set it up with this code:

            NNOperator nn = new NNOperator(2, 1);            nn.AddLayer(2);            nn.ComputeWeights();            //let's set it up as a XOR (perfect xor)            nn.weights[0][0] = 1;            nn.weights[0][1] = 1;            nn.weights[0][2] = 1;            nn.weights[0][3] = 1;            nn.layers[1][0, 1] = 1.5f;            nn.layers[1][1, 1] = 0.5f;            nn.weights[1][0] = -1;            nn.weights[1][1] = 1;            nn.layers[2][0, 1] = 0.5f;


And I've tested it by giving to it two values into input like 0,0 0,1 1,0 and 1,1 the result I've obtained is a perfect XOR!
A B Output
0 0 0
0 1 1
1 0 1
1 1 0
So the update works perfectly!
Now I've only to find out a way for backpropagation.
What do you think?
Are you doing back propagation because you want to learn how it works? Or would you be happy with any method of neural network learning?

If you would be just as happy with another method, you might check out using genetic algorithms to train neural nets.

It isn't appropriate for all situations but it may be useful for yours, depending on what you are trying to accomplish.

Essentially you have "genes" that defines a network (ie neuron weights and thresholds, possibly even network topology) and generate a bunch of these guys with a random set of genes or a guided randomness if you wish)

Then you evaluate the performance of each of these networks and take some percentage of the winning networks, and a smaller percentage of the non winning networks, and "Mate" them all with some rate of mutation, coming up with the next generation of neural networks.

Rinse and repeat til you have suitable network(s).

Might be OT but wanted to toss it out there in case you weren't aware of the technique.
Advertisement
Neuron(;) would be the Sigma or Sigmoid function that you use to calculate your activation level.
Actually, as you can read in my last reply (not this), you can see that I made a XOR neural network by creating the network and setting all the values to work like a perfect XOR, I would like to learn how to implement back-propagation training to, for example, creating a network with casual values and by training it, seeing that it works as a XOR.
(Maybe I'll be able to use this class for my games in future)
I gave you all the information you need to implement a Back-Prop neural network, but you'll have to understand the Maths behind it first. Read the link that I posted a few replies back, that one should be clear enough.
Well that link doesn't seem to work.. okay thank you for your help, I'll try making it out with the information you gave me.

This topic is closed to new replies.

Advertisement