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.
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?
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 };
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.