2012-03-12 24 views
7

Estoy tratando de implementar y entrenar una red neuronal de cinco neuronas con propagación hacia atrás para la función XOR en Java. Mi código (disculpen que la fealdad):Red neuronal XOR en Java

public class XORBackProp { 

private static final int MAX_EPOCHS = 500; 

//weights 
private static double w13, w23, w14, w24, w35, w45; 
private static double theta3, theta4, theta5; 
//neuron outputs 
private static double gamma3, gamma4, gamma5; 
//neuron error gradients 
private static double delta3, delta4, delta5; 
//weight corrections 
private static double dw13, dw14, dw23, dw24, dw35, dw45, dt3, dt4, dt5; 
//learning rate 
private static double alpha = 0.1; 
private static double error; 
private static double sumSqrError; 
private static int epochs = 0; 
private static boolean loop = true; 

private static double sigmoid(double exponent) 
{ 
    return (1.0/(1 + Math.pow(Math.E, (-1) * exponent))); 
} 

private static void activateNeuron(int x1, int x2, int gd5) 
{ 
    gamma3 = sigmoid(x1*w13 + x2*w23 - theta3); 
    gamma4 = sigmoid(x1*w14 + x2*w24 - theta4); 
    gamma5 = sigmoid(gamma3*w35 + gamma4*w45 - theta5); 

    error = gd5 - gamma5; 

    weightTraining(x1, x2); 
} 

private static void weightTraining(int x1, int x2) 
{ 
    delta5 = gamma5 * (1 - gamma5) * error; 
    dw35 = alpha * gamma3 * delta5; 
    dw45 = alpha * gamma4 * delta5; 
    dt5 = alpha * (-1) * delta5; 

    delta3 = gamma3 * (1 - gamma3) * delta5 * w35; 
    delta4 = gamma4 * (1 - gamma4) * delta5 * w45; 

    dw13 = alpha * x1 * delta3; 
    dw23 = alpha * x2 * delta3; 
    dt3 = alpha * (-1) * delta3; 
    dw14 = alpha * x1 * delta4; 
    dw24 = alpha * x2 * delta4; 
    dt4 = alpha * (-1) * delta4; 

    w13 = w13 + dw13; 
    w14 = w14 + dw14; 
    w23 = w23 + dw23; 
    w24 = w24 + dw24; 
    w35 = w35 + dw35; 
    w45 = w45 + dw45; 
    theta3 = theta3 + dt3; 
    theta4 = theta4 + dt4; 
    theta5 = theta5 + dt5; 
} 

public static void main(String[] args) 
{ 

    w13 = 0.5; 
    w14 = 0.9; 
    w23 = 0.4; 
    w24 = 1.0; 
    w35 = -1.2; 
    w45 = 1.1; 
    theta3 = 0.8; 
    theta4 = -0.1; 
    theta5 = 0.3; 

    System.out.println("XOR Neural Network"); 

    while(loop) 
    { 
     activateNeuron(1,1,0); 
     sumSqrError = error * error; 
     activateNeuron(0,1,1); 
     sumSqrError += error * error; 
     activateNeuron(1,0,1); 
     sumSqrError += error * error; 
     activateNeuron(0,0,0); 
     sumSqrError += error * error; 

     epochs++; 

     if(epochs >= MAX_EPOCHS) 
     { 
      System.out.println("Learning will take more than " + MAX_EPOCHS + " epochs, so program has terminated."); 
      System.exit(0); 
     } 

     System.out.println(epochs + " " + sumSqrError); 

     if (sumSqrError < 0.001) 
     { 
      loop = false; 
     } 
    } 
} 
} 

Si se ayuda a cualquiera, aquí hay un diagram of the network.

Los valores iniciales para todos los pesos y la tasa de aprendizaje se toman directamente de un ejemplo en mi libro de texto. El objetivo es entrenar la red hasta que la suma de los errores al cuadrado sea menor que .001. El libro de texto también da los valores de todos los pesos después de la primera iteración (1,1,0) y he probado mi código y sus resultados coinciden perfectamente con los resultados del libro de texto. Pero de acuerdo con el libro, esto solo debería tomar 224 épocas para converger. Pero cuando lo ejecuto, siempre llega a MAX_EPOCHS a menos que esté configurado en varios miles. ¿Qué estoy haciendo mal?

+1

En su diagrama, la flecha 'w14' está mal etiquetada como' w24'. – Gabe

+0

Cambié la velocidad de aprendizaje a 19.801 (que generalmente es demasiado alta) y alcancé el error deseado en 300 épocas. Creo que tomaron otra tasa de aprendizaje. Pero también podría haber un error en tu código. – alfa

Respuesta

1

intentar hacer redondeo de gamma3, gamma4, gamma5 mientras que en fase de activación para instace:

if (gamma3 > 0.7) gamma3 = 1; 
if (gamma3 < 0.3) gamma3 = 0; 

y se elevan poco learnig variable (alfa)

alpha = 0.2; 

aprendizaje termina en 466 épocas.

Por supuesto, si u hacer más grande y más alto redondeo alfa u Colocar u puede lograr aún mejor resultado que 224.

2
//Add this in the constants declaration section. 
    private static double alpha = 3.8, g34 = 0.13, g5 = 0.21; 

    // Add this in activate neuron 
    gamma3 = sigmoid(x1 * w13 + x2 * w23 - theta3); 
    gamma4 = sigmoid(x1 * w14 + x2 * w24 - theta4);   
    if (gamma3 > 1 - g34) {gamma3 = 1;} 
    if (gamma3 < g34) {gamma3 = 0;} 
    if (gamma4 > 1- g34) {gamma4 = 1;} 
    if (gamma4 < g34) {gamma4 = 0;} 
    gamma5 = sigmoid(gamma3 * w35 + gamma4 * w45 - theta5); 
    if (gamma5 > 1 - g5) {gamma5 = 1;} 
    if (gamma5 < g5) {gamma5 = 0;} 

ANN debe aprender en 66 iteraciones, pero es en el borde de la divergencia.

1

El objetivo de esta red es mostrar cómo enfrentar una situación cuando la agrupación no se basa en "top = yes, bottom = no", sino que hay una línea central (pasando por puntos (0,1) y (1,0) en este caso) y si el valor está cerca de la línea, entonces la respuesta es "sí", mientras que si está lejos, entonces la respuesta es "no". No puede agrupar dicho sistema con solo una capa. Sin embargo, dos capas son suficientes.

Cuestiones relacionadas