Avatar billede brian0905 Nybegynder
19. september 2008 - 11:19 Der er 5 kommentarer

Problemer med Neuralt Netværk

HEjsa,
Jeg er absolut begynder med hensyn til neurale netværk. Jeg har fundet en masse eksempler på nettet hvordan man implementerer dem. Jeg er ved at eksperimentere med et der benytter Backpropagation til at træne med. Her er jeg stødt ind i nogle problemer. Som simpelt test tester jeg en xor, hvor jeg inputter værdierne: [0,0], [0,1], [1,0] og [1,1], og så forventer at kunne få resultater [0], [1], [1], [0]. Det vil sige jeg har et netværk der har 3 lag, 2 noder i input, 10 noder i hidden og 1 node i output der beskriver enten true eller false. Problemet ser ud til at jeg ikke helt forstår hvordan jeg træner mit netværk. Jeg har min trænings kode nedenfor, håber kommentarerne giver mening:

public void Train(double[] inputData, double[] outputData, double minErrorMargin)
        {
            //validate input and output length
            while (this.globalError > minErrorMargin)
            {
                if (inputData.Length == inputLayer.Neurons.Length && outputData.Length == outputLayer.Neurons.Length)
                {
                    //forward propagate
                    Run(inputData);

                    //calculate error in output layer
                    for (int i = 0; i < outputLayer.Neurons.Length; i++)
                    {
                        outputLayer.Neurons[i].Error = outputLayer.Neurons[i].Activation * (1 - outputLayer.Neurons[i].Activation) * (outputData[i] - outputLayer.Neurons[i].Activation);
                    }

                    //calculate weights for hidden to output
                    for (int i = 0; i < hiddenLayer.Neurons.Length; i++)
                    {
                        for (int j = 0; j < hiddenLayer.Neurons[i].Dendrites.Length; j++)
                        {
                            hiddenLayer.Neurons[i].Error += hiddenLayer.Neurons[i].Dendrites[j].Weight * outputLayer.Neurons[j].Error;
                        }
                        //calculate the difference in hidden layer
                        hiddenLayer.Neurons[i].Error *= hiddenLayer.Neurons[i].Activation * (1 - hiddenLayer.Neurons[i].Activation);
                    }

                    //calculate new thresholds using the learning rate
                    for (int i = 0; i < hiddenLayer.Neurons.Length; i++)
                    {
                        //compute the threshold for the hidden layer i the next iteration
                        HiddenLayer.Neurons[i].Threshold += hiddenLayer.Neurons[i].Error * this.learningRateHidden;
                    }

                    //calculate the new thresholds for the outputlayer using the learningrate
                    for (int i = 0; i < outputLayer.Neurons.Length; i++)
                    {
                        //compute the threshold for the next iteration
                        outputLayer.Neurons[i].Threshold += outputLayer.Neurons[i].Error * this.learningRateOutput;
                    }

                    //calculate new weights in hidden layer (from hidden to output)
                    double temp = 0.0f;
                    for (int i = 0; i < hiddenLayer.Neurons.Length; i++)
                    {
                        temp = hiddenLayer.Neurons[i].Activation * this.learningRateOutput;
                        for (int j = 0; j < this.outputLayer.Neurons.Length; j++)
                        {
                            hiddenLayer.Neurons[i].Dendrites[j].Weight += temp * outputLayer.Neurons[j].Error;
                        }
                    }

                    //calculate new weights in inputLayer (from input layer to hiddenlayer)
                    for (int i = 0; i < this.inputLayer.Neurons.Length; i++)
                    {
                        temp = inputData[i] * this.learningRateHidden;
                        for (int y = 0; y < this.hiddenLayer.Neurons.Length; y++)
                        {
                            inputLayer.Neurons[i].Dendrites[y].Weight += temp * hiddenLayer.Neurons[y].Error;
                        }
                    }

                    //calculate the global error
                    globalError = 0;
                    for (int i = 0; i < this.outputLayer.Neurons.Length; i++)
                    {
                        globalError += outputLayer.Neurons[i].Error;
                    }

                    //increment the iterations
                    iterations++;

                    if (OnTraningSetComplete != null)
                    {
                        OnTraningSetComplete(globalError, iterations);
                    }     
                }
            }

Det ser ud til at alle resultater (activation på output level) giver 0.8. Alle kommentarer elle eksempler er værdsat.
Avatar billede sovsekoder Nybegynder
22. september 2008 - 13:50 #1
som jeg husker det skal du ikke træne 1 pattern af gangen, men skifte mellem de 4 patterns. Så ikke netværket bliver specialist i 1 enkelt pattern.

så:
train pattern1
train pattern2
train pattern3
train pattern4
train pattern1
train pattern2
train pattern3
train pattern4
... osvosv

istedet for
train pattern1
train pattern1
train pattern1
train pattern1
train pattern1
...
...
...

indtil fejlen er lille nok. Hjælper det?
Avatar billede brian0905 Nybegynder
23. september 2008 - 08:30 #2
Jeg træner det med følgende data, problemet er at jeg får stort set de samme resultater hver gang. Resultatet bliver det samme for alle gennemløb af netværket. Er det min algoritme der er forkert?

network.Train(trainInputData1, trainOutputData1, errorThreshold);
network.Train(trainInputData2, trainOutputData2, errorThreshold);
network.Train(trainInputData3, trainOutputData3, errorThreshold);
network.Train(trainInputData4, trainOutputData4, errorThreshold);

DumpDouble(network.Run(trainInputData1));
DumpDouble(network.Run(trainInputData2));
DumpDouble(network.Run(trainInputData3));
DumpDouble(network.Run(trainInputData4));
Avatar billede sovsekoder Nybegynder
23. september 2008 - 13:54 #3
jeg mener umidlbart at du skal have din error tjek uden om dine train-kald, som f.eks:

while (this.globalError > minErrorMargin)
{
  network.Train(trainInputData1, trainOutputData1, errorThreshold);
  network.Train(trainInputData2, trainOutputData2, errorThreshold);
  network.Train(trainInputData3, trainOutputData3, errorThreshold);
  network.Train(trainInputData4, trainOutputData4, errorThreshold);
  if (OnTraningSetComplete != null)
  {
    OnTraningSetComplete(globalError, iterations);
  }     
}

..og så skal der ikke være iterationer i Train-metoden
Avatar billede sovsekoder Nybegynder
23. september 2008 - 13:56 #4
og så skal global error nul-stilles for hvert gennemløb:
while (this.globalError > minErrorMargin)
{
  globalError = 0.0
  ...
  ...
}
Avatar billede brian0905 Nybegynder
23. september 2008 - 14:44 #5
Nu sker der noget andet pudsigt. Hvis jeg træner med alle inputs seperat, ser det ud til at det bliver korrekt.

while (this.globalError > minErrorMargin)
{
  network.Train(trainInputData1, trainOutputData1, errorThreshold);
  if (OnTraningSetComplete != null)
  {
    OnTraningSetComplete(globalError, iterations);
  }     
}

og så en while igen for trainingSet2 osv... så ser netværets output korrekte ud, kun netværkets output er korrekte. HVis jeg træner med alle sammen bliver mit netværks output i mine tests til det sidste netværk der er trænet. Jeg har forsøgt begge dele, her er koden til min  træning og efterfølgende test af netværket (bemært at det er en almindelig XOR sandhedstabel der testes).


***** Test data *****
private double[] trainInputData1 = new double[] { 0, 1 };
        private double[] trainOutputData1 = new double[] { 1, 0, 0, 0 };

        private double[] trainInputData2 = new double[] { 1, 0 };
        private double[] trainOutputData2 = new double[] { 0, 1, 0, 0 };

        private double[] trainInputData3 = new double[] { 1, 1 };
        private double[] trainOutputData3 = new double[] { 0, 0, 1, 0 };

        private double[] trainInputData4 = new double[] { 0, 0 };
        private double[] trainOutputData4 = new double[] { 0, 0, 0, 1 };

*** Event handler på "Run" knap ****

private void runButton_Click(object sender, EventArgs e)
        {
            int input = Convert.ToInt32(inputText.Text);
            int hidden = Convert.ToInt32(hiddenText.Text);
            int output = Convert.ToInt32(outputText.Text);
            double hiddenLearningRate = Convert.ToDouble(hiddenLRText.Text.Replace(".", ","));
            double outputLearningRate = Convert.ToDouble(outputLRText.Text.Replace(".", ","));
            double errorThreshold = Convert.ToDouble(trainingThreshold.Text.Replace(".", ","));

            Network network = new Network(input, hidden, output, hiddenLearningRate, outputLearningRate);       

            int iterations = 0;
            while (network.globalError > errorThreshold)
            {
                network.globalError = 0;
                network.Train(trainInputData1, trainOutputData1, errorThreshold);
                //network.Train(trainInputData2, trainOutputData2, errorThreshold);
                //network.Train(trainInputData3, trainOutputData3, errorThreshold);
                //network.Train(trainInputData4, trainOutputData4, errorThreshold);
                ShowTrainingStats(network.globalError, iterations);
                iterations++;
            }
            network.globalError = 10;

            while (network.globalError > errorThreshold)
            {
                network.globalError = 0;
                network.Train(trainInputData2, trainOutputData2, errorThreshold);
                ShowTrainingStats(network.globalError, iterations);
                iterations++;
            }
            network.globalError = 10;

            while (network.globalError > errorThreshold)
            {
                network.globalError = 0;
                network.Train(trainInputData3, trainOutputData3, errorThreshold);
                ShowTrainingStats(network.globalError, iterations);
                iterations++;
            }
            network.globalError = 10;

            while (network.globalError > errorThreshold)
            {
                network.globalError = 0;
                network.Train(trainInputData4, trainOutputData4, errorThreshold);
                ShowTrainingStats(network.globalError, iterations);
                iterations++;
            }

            DumpDouble(network.Run(trainInputData1));
            Console.WriteLine("-----------------------");
            DumpDouble(network.Run(trainInputData2));
            Console.WriteLine("-----------------------");
            DumpDouble(network.Run(trainInputData3));
            Console.WriteLine("-----------------------");
            DumpDouble(network.Run(trainInputData4));
            Console.WriteLine("-----------------------");
            this.Cursor = Cursors.Default;
            //Save("c:\\xornetwork4.xml", network);
        }

*** Output ***
[0,0198024763858041]
[0,0242986460363291]
[0,0309364773818499]
[0,953548573142796]
-----------------------
[0,0436360226243823]
[0,0518210896203234]
[0,0622229576920202]
[0,928741332243757]
-----------------------
[0,0180416135897507]
[0,0222290694289719]
[0,0284929259245729]
[0,955829669822355]
-----------------------
[0,0553234928947915]
[0,0650943990563325]
[0,0767721775826373]
[0,918983512365323]
-----------------------
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester