Una forma sencilla y rápida de aprender JAVA, observando y deduciendo cómo se comporta el lenguaje a través de ejemplos prácticos.

viernes, 7 de febrero de 2014

Neurona Artificial (II). Aprendizaje (puerta lógica OR).

Voy a crear un algoritmo de aprendizaje (en este caso una puerta logica OR). Para ello voy a utilizar un tipo de neurona artificial llamada perceptrón con 2 entradas.


 























Hay que tener encuenta que en este ejemplo, la salida (Y1) solo admite los valores 1 y -1, siguiendo la siguiente regla:

 1 si f(wx) >= θ
-1 si f(wx) <  θ


Para el aprendizaje de la puerta logica OR nos hará falta crear una "tabla de la verdad" del mismo:


























 



En este nuevo ejemplo de neurona aparecen 2 nuevos valores a tener encuenta:

E = Factor de aprendizaje
θ = Umbral


Y una nueva formula que servirá para ajuste de pesos:

W = W + 2E * T * X


Codigo:

//Aprendizaje puerta logica OR. (Muestra datos paso a paso)
package neuronaOR;

import java.util.Random;
import java.util.Scanner;

public class NeuronaOR {

    public static void main(String[] args) {
        //Tabla de la verdad (X1,X2,Y1)
        int[][] tv = {{1, 1, 1}, {1, -1, 1}, {-1, 1, 1}, {-1, -1, -1}};

        System.out.println("\nInicializar pesos:\n");
        double w1 = new Random().nextDouble() / 2.5;//valores proximos a 0
        double w2 = new Random().nextDouble() / 2.5;
        double θ = -0.4;

        double y = 0;
        final double E = 0.6;//Factor de aprendizaje       

        System.out.println("w1: " + w1);
        System.out.println("w2: " + w2);
        System.out.println("θ: " + θ);

        System.out.println("\nIniciando fase de aprendizaje puerta logica OR...\n");
        int i = 0;
        int cont = 1;
        while (i < tv.length && cont < 100) {
            y = Math.tanh((tv[i][0] * w1) + (tv[i][1] * w2) + (-1 * θ));
            y = (y >= θ) ? 1 : -1;
            System.out.println("Entrada[" + tv[i][0] + "," + tv[i][1]
                    + "]) Valor esperado[" + tv[i][2]
                    + "] Salida[" + (int) y + "]");
            if (y == tv[i][2]) {
                i++;
            } else {
                System.out.println("Valor esperado difiere de la salida. Hay que reajustar pesos...");
                //Ajuste de pesos
                w1 = w1 + 2 * E * tv[i][2] * tv[i][0];
                w2 = w2 + 2 * E * tv[i][2] * tv[i][1];
                θ = θ + 2 * E * tv[i][2] * (-1);

                System.out.println("\nAjuste de pesos (" + cont + "):");
                System.out.println("w1: " + w1);
                System.out.println("w2: " + w2);
                System.out.println("θ: " + θ + "\n");
                cont++;
                i = 0;
            }
        }

        if (cont <= 9999) {
            System.out.println("\nFase de aprendizaje terminado con exito ");
            System.out.println("\nResultados:");
            System.out.println("w1: " + w1);
            System.out.println("w2: " + w2);
            System.out.println("θ: " + θ);
            System.out.println("\nIniciando fase de testeo...");
            System.out.println("Introduce Entrada 1 (X1): ");
            Scanner leerX1 = new Scanner(System.in);
            double x1 = Double.parseDouble(leerX1.next());

            System.out.println("Introduce Entrada 2 (X2): ");
            Scanner leerX2 = new Scanner(System.in);
            double x2 = Double.parseDouble(leerX2.next());

            y = Math.tanh((x1 * w1) + (x2 * w2) + (-1 * θ));
            y = (y >= θ) ? 1 : -1;

            System.out.println("\nSalida: " + (int)y);
        } else {
            System.out.println("\nFase de aprendizaje ha fallado\n");
        }

    }
}


Resultado:

run:

Inicializar pesos:

w1: 0.3223614553902566
w2: 0.11581465997718018
θ: -0.4

Iniciando fase de aprendizaje puerta logica OR...

Entrada[1,1]) Valor esperado[1] Salida[1]
Entrada[1,-1]) Valor esperado[1] Salida[1]
Entrada[-1,1]) Valor esperado[1] Salida[1]
Entrada[-1,-1]) Valor esperado[-1] Salida[1]
Valor esperado difiere de la salida. Hay que reajustar pesos...

Ajuste de pesos (1):
w1: 1.5223614553902567
w2: 1.31581465997718
θ: 0.7999999999999999

Entrada[1,1]) Valor esperado[1] Salida[1]
Entrada[1,-1]) Valor esperado[1] Salida[-1]
Valor esperado difiere de la salida. Hay que reajustar pesos...

Ajuste de pesos (2):
w1: 2.7223614553902564
w2: 0.1158146599771801
θ: -0.4

Entrada[1,1]) Valor esperado[1] Salida[1]
Entrada[1,-1]) Valor esperado[1] Salida[1]
Entrada[-1,1]) Valor esperado[1] Salida[-1]
Valor esperado difiere de la salida. Hay que reajustar pesos...

Ajuste de pesos (3):
w1: 1.5223614553902565
w2: 1.31581465997718
θ: -1.6

Entrada[1,1]) Valor esperado[1] Salida[1]
Entrada[1,-1]) Valor esperado[1] Salida[1]
Entrada[-1,1]) Valor esperado[1] Salida[1]
Entrada[-1,-1]) Valor esperado[-1] Salida[1]
Valor esperado difiere de la salida. Hay que reajustar pesos...

Ajuste de pesos (4):
w1: 2.7223614553902564
w2: 2.5158146599771802
θ: -0.40000000000000013

Entrada[1,1]) Valor esperado[1] Salida[1]
Entrada[1,-1]) Valor esperado[1] Salida[1]
Entrada[-1,1]) Valor esperado[1] Salida[1]
Entrada[-1,-1]) Valor esperado[-1] Salida[-1]

Fase de aprendizaje terminado con exito

Resultados:
w1: 2.7223614553902564
w2: 2.5158146599771802
θ: -0.40000000000000013

Iniciando fase de testeo...
Introduce Entrada 1 (X1):
1
Introduce Entrada 2 (X2):
-1

Salida: 1

BUILD SUCCESSFUL (total time: 3 minutes 25 seconds)


2 comentarios:

  1. Buen Día,
    Excelente trabajo amigo, pero puedo preguntar de donde tomaste la teoría, me puedes ayudar con eso por fa.

    Gracias!!

    ResponderEliminar
  2. Inteligencia Artificial - Un Enfoque Moderno. Russel Norving

    ResponderEliminar

Con la tecnología de Blogger.