2016-10-01 3 views
0

Ich brauche Hilfe mit meinem Perzeptron 1 Schicht, ich benutze eine Funktion Sigmoide, um die Funktion zu übertragen und den Algorithmus zurück für das Lernen zu propagieren. Ich möchte ein einfaches neuronales Netzwerk für Rechen A und B (logisch und) machen. Mein Problem ist nach dem Lernen habe ich 2 Wert (zum Beispiel 0 und 0) und meine IA gebe mir immer 0,99. Ich sehe den Code 3 Mal und ich verstehe nicht, warum mein Programm nach dem Lernen eine schlechte Antwort zurückgibt. Bitte hilf mir.Fehler beim Lernen mit Perzeptron 1 Schicht

Neuron.java:

public class Neuron { 
    public double value; 
    public double[] weights; 
    public double bias; 
    public double deltas; 

public Neuron(int nb_entree){ 
    weights = new double[nb_entree]; 

    value = Math.random()/10000000000000.0; 
    bias = Math.random()/10000000000000.0; 
    deltas = Math.random()/10000000000000.0; 

    for(int i = 0 ; i < weights.length ; i++){ 
     weights[i] = Math.random()/10000000000000.0; 
    } 
} 

/*** 
* Function to evaluate a neurone with a sigmoide function 
* @param input : list to input value 
* @return the result of sigmoide function 
*/ 
public double evaluate(double[] input){ 
    double x = 0.0; 

    for(int i = 0 ; i < input.length ; i++){ 
     x += input[i] * weights[i]; 
    } 
    x += bias; 

    value = 1/(1 + Math.pow(Math.E, x)); 

    return value; 
} 

//Function to delete value of neurons 
protected void delete(){ 
    value = 0.0; 
} 
} 

NeuralNetwork.java:

public class NeuralNetwork { 
    public Neuron[] neurons_hidden; 
    public Neuron[] neurons_output; 
    public double rate_learning; 
    public int nb_hidden; 
    public int nb_output; 

public NeuralNetwork(int nb_input, int nb_hid, int nb_out, double rate){ 
    nb_hidden = nb_hid; 
    nb_output = nb_out; 
    rate_learning = rate; 

    neurons_hidden = new Neuron[nb_hidden]; 
    neurons_output = new Neuron[nb_output]; 

    //Create hidden neurons 
    for(int i = 0 ; i < nb_hidden ; i++){ 
     neurons_hidden[i] = new Neuron(nb_input); 
    } 

    //Create output neurons 
    for(int i = 0 ; i < nb_output ; i++){ 
     neurons_output[i] = new Neuron(nb_hidden); 
    } 
} 

public double[] evaluate(double[] input){ 
    double[] output_hidden = new double[nb_hidden]; 
    double[] outputs = new double[nb_output]; 

    //we delete the value of hidden neurons 
    for(Neuron n : neurons_hidden){ 
     n.delete(); 
    } 

    //we delete the value of output neurons 
    for(Neuron n : neurons_output){ 
     n.delete(); 
    } 

    //Pour chaque neurone caches 
    for(int i = 0 ; i < nb_hidden ; i++){ 
     output_hidden[i] = neurons_hidden[i].evaluate(input); 
    } 

    //Pour chaque neurone sortie 
    for(int i = 0 ; i < nb_output ; i++){ 
     outputs[i] = neurons_output[i].evaluate(output_hidden); 
    } 

    return outputs; 
} 


public double backPropagate(double[] input, double[] output){ 

    double[] output_o = evaluate(input); 
    double error; 
    int i; 
    int k; 

    //For all neurons output, we compute the deltas 
    for(i = 0 ; i < nb_output ; i++){ 
      error = output[i] - output_o[i]; 
      neurons_output[i].deltas = error * (output_o[i] - Math.pow(output_o[i], 2)); 
    } 

    //For all neurons hidden, we compute the deltas 
    for(i = 0 ; i < nb_hidden ; i++){ 
     error = 0.0; 
     for(k = 0 ; k < nb_output ; k++){ 
      error += neurons_output[k].deltas * neurons_output[k].weights[i]; 
     } 
     neurons_hidden[i].deltas = error * (neurons_hidden[i].value - Math.pow(neurons_hidden[i].value, 2));    
    } 


    //For all neurons output, we modify the weight 
    for(i = 0 ; i < nb_output ; i++){ 
     for(k = 0 ; k < nb_hidden ; k++){ 
      neurons_output[i].weights[k] += rate_learning * 
               neurons_output[i].deltas * 
                neurons_hidden[k].value; 
     } 
     neurons_output[i].bias += rate_learning * neurons_output[i].deltas; 
    } 


    //For all neurons hidden, we modify the weight 
    for(i = 0 ; i < nb_hidden ; i++){ 
     for(k = 0 ; k < input.length ; k++){ 
      neurons_hidden[i].weights[k] += rate_learning * neurons_hidden[i].deltas * input[k];   
     } 
     neurons_hidden[i].bias += rate_learning * neurons_hidden[i].deltas; 
    } 

    error = 0.0; 
    for(i = 0 ; i < output.length ; i++){ 
     error += Math.abs(output_o[i] - output[i]); 
    } 

    error = error/output.length; 

    return error; 
} 
} 

Test.java:

public class Test { 

public static void main(String[] args) { 

    NeuralNetwork net = new NeuralNetwork(2, 2, 1, 0.6); 

    /* Learning */ 
    for(int i = 0 ; i < 10000 ; i++) 
    { 
     double[] inputs = new double[]{Math.round(Math.random()), Math.round(Math.random())}; 
     double[] output = new double[1]; 
     double error; 

     if((inputs[0] == inputs[1]) && (inputs[0] == 1)) 
      output[0] = 1.0; 
     else 
      output[0] = 0.0; 

     System.out.println(inputs[0]+" and "+inputs[1]+" = "+output[0]); 

     error = net.backPropagate(inputs, output); 
     System.out.println("Error at step "+i+" is "+error); 
    } 

    System.out.println("Learning finish!"); 

    /* Test */ 
    double[] inputs = new double[]{0.0, 0.0}; 
    double[] output = net.evaluate(inputs); 

    System.out.println(inputs[0]+" and "+inputs[1]+" = "+output[0]+""); 
} 
} 

Danke, mir zu helfen

Antwort

0

Ihre Sigmoidfunktion ist nicht richtig. Es braucht ein negatives t:

1/(1 + Math.pow(Math.E, -x)) 

Ich bin mir nicht sicher, ob das der einzige Fehler ist.

Zusätzlich benötigen Sie für die Verbindung "und" nur eine Schicht.

Schließlich behandeln Sie Ihre Voreingenommenheit getrennt in Ihrer Rückenausbreitungsmethode. Dies kann vereinfacht werden, indem ein Eingangsknoten mit einer Konstanten 1 als Eingabe und der Bias als Gewicht hinzugefügt wird. Siehe https://en.wikipedia.org/wiki/Perceptron#Definitions.

Verwandte Themen