2016-10-01 63 views
0

我需要我的感知器1圖層的幫助,我使用函數sigmoide來傳遞函數,並將算法傳回給學習。我想爲計算A和B(邏輯和)做一個簡單的神經網絡。我的問題是學習後我把2的值(例如0和0),我的IA給我總是0.99。我看到代碼3次,我不明白爲什麼我的程序在學習後返回錯誤的答案。請幫幫我。使用感知器1學習的錯誤圖層

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]+""); 
} 
} 

感謝幫助我

回答

0

你的雙曲線函數不正確。它需要一個負值t:

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

我不確定這是否是唯一的錯誤。

此外,對於連接「和」你只需要一層。

最後,你在背部傳播方法中分別對待你的偏見。可以通過添加一個常數爲1的輸入節點作爲輸入,並將偏差作爲權重來簡化。見https://en.wikipedia.org/wiki/Perceptron#Definitions