2012-03-12 28 views
7

Sto cercando di implementare e addestrare una rete neuronale a cinque neuroni con propagazione posteriore per la funzione XOR in Java. Il mio codice (scusate essa la bruttezza):Rete neurale XOR in 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; 
     } 
    } 
} 
} 

Se aiuta qualunque, ecco una diagram of the network.

I valori iniziali per tutti i pesi e il tasso di apprendimento sono presi direttamente da un esempio nel mio libro di testo. L'obiettivo è addestrare la rete fino a quando la somma degli errori al quadrato è inferiore a 0,001. Il libro di testo fornisce anche i valori di tutti i pesi dopo la prima iterazione (1,1,0) e ho testato il mio codice e i suoi risultati corrispondono perfettamente ai risultati del libro di testo. Ma secondo il libro, questo dovrebbe solo prendere 224 epoche per convergere. Ma quando lo eseguo, raggiunge sempre MAX_EPOCHS a meno che non sia impostato su diverse migliaia. Che cosa sto facendo di sbagliato?

+1

Nel diagramma, la freccia 'w14' è etichettata come' w24'. – Gabe

+0

Ho cambiato la velocità di apprendimento a 19.801 (che di solito è troppo alta) e ho raggiunto l'errore desiderato in 300 epoche. Penso che abbiano preso un altro tasso di apprendimento. Ma potrebbe esserci anche un errore nel codice. – alfa

risposta

1

Prova rendendo arrotondamento gamma3, gamma4, gamma5 mentre in fase di attivazione per instace:

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

e fanno poco learnig variabile (alfa)

alpha = 0.2; 

apprendimento termina in 466 epoche.

Naturalmente se u fa grande arrotondamento e superiore alfa u impostare u può raggiungere anche migliore risultato di 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 deve imparare in 66 iterazioni, ma è sul punto di divergenza.

1

L'intero punto di questa rete è mostrare come affrontare una situazione in cui il raggruppamento non è basato su "top = yes, bottom = no", ma piuttosto c'è una linea centrale (attraversando punti (0,1) e (1,0) in questo caso) e se il valore è vicino alla linea, la risposta è "sì", mentre se è lontana, la risposta è "no". Non è possibile raggruppare tale sistema con un solo livello. Tuttavia due strati sono sufficienti.

Problemi correlati