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.
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));
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
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]
-----------------------