jueves, 13 de agosto de 2015

Estructura de la Neurona Artificial II

Neurona Artificial en Java

Llegamos a donde quería llegar, darle vida a esto que en principio parece muy teórico y abstracto y poder bajarlo a tierra y verlo funcionando. Vamos a intentar traducir estos conceptos a código Java y sucesivamente lo iremos refinando para darle mas funcionalidad. Vale aclarar que si bien tengo bastante experiencia en Java y soy partidario de las buenas practicas de desarrollo, en este caso voy a hacer algunas excepciones para facilitar la comprensión de estos conceptos en lugar de hacer hincapié en las buenas prácticas de desarrollo en Java.

Vamos a modelar nuestra Neurona Artificial con una clase Java a la que iremos agregando los distintos atributos que tiene una Neurona Artificial. Entonces creamos primero la clase, que nos quedará asi:

/**
 * Neurona Artificial
 * @author Vincent
 */
public class Neurona {
 
}

Dijimos ademas que una neurona puede tener varias entras xi. y que cada entrada tendrá un peso asociado wi, esto lo modelamos con dos arreglos de la siguiente manera:

/**
 * Entradas
 */
public double[] x;
/**
 * Pesos de las entradas
 */
public double[] w;

También dijimos que una Neurona Artificial tiene un entrada neta Net y una salida y. Cuando a la Neurona se le aplica la Función de Activación, éste queda en un Estado de Activación el cual es un valor real. Estos atributos lo medelaremos así:

/**
 * Entrada Neta
 */
public double Net;
/**
 * Estado de activacion
 */
public double activacion;
/**
 * Valor de salida
 */
public double y;

Ya tenemos una primera aproximación de la estructura de nuestra Neurona. Ahora vamos a agregarle un constructor a la clase para que al momento de instanciarla (crearla) se inicialice en cierto estado para poder utilizarla cómodamente, Al instanciar nuestra Neurona vamos a decirle cuantas entradas queremos que tenga y que automáticamente asigne los pesos el valor 0.5, No necesitamos indicarle valores a las entradas en este momento ya que lo haremos al momento de usar la Neurona. Nos quedará algo así:

/**
 * Constructor de la clase
 */
public Neurona(int cantidadEntradas){
 // dimensiona el vector de entradas con el tamaño de entradas
 x = new double[cantidadEntradas];
 // dimensiona el vector de pesos asociados a las entradas
 w = new double[cantidadEntradas];
 // inicializa los pesos en con 0.5
 for (int i = 0; i < w.length; i++) {
  w[i] = 0.5d;
 }
}

Adicionalmente vamos a agregarle un método para calcular la entrada neta Net que dijimos que es la sumatoria de los productos entre cada entrada con su correspondiente peso. Nos quedará algo así:

/**
 * Calcula la entrada neta de la neurona
 */
public void calcularNet(){
 double result = 0;
 
 for (int i = 0; i < x.length; i++) {
  result = result + ( x[i] * w[i] );
 }
 
 Net = result;
}

Finalmente tenemos nuestra primera aproximación:

/**
 * Neurona Artificial
 * @author Vincent
 */
public class Neurona {
 /**
  * Valores de entrada
  */
 public double[] x;
 /**
  * Pesos de las entradas
  */
 public double[] w;
 /**
  * Entrada Neta
  */
 public double Net;
 /**
  * Estado de activacion
  */
 public double activacion;
 /**
  * Valor de salida
  */
 public double y;
 
 /**
  * Constructor de la clase
  */
 public Neurona(int cantidadEntradas){
  // dimensiona el vector de entradas con el tamaño de entradas
  x = new double[cantidadEntradas];
  // dimensiona el vector de pesos asociados a las entradas
  w = new double[cantidadEntradas];
  // inicializa los pesos en con 0.5
  for (int i = 0; i < w.length; i++) {
   w[i] = 0.5d;
  }
 }
 /**
  * Calcula la entrada neta de la neurona
  */
 public void calcularNet(){
  double result = 0;
  
  for (int i = 0; i < x.length; i++) {
   result = result + ( x[i] * w[i] );
  }
  
  Net = result;
 }
}

Todo muy lindo hasta acá pero esta cosa aun no hace nada, así que ahora vamos a hacer que haga algo muy simple, luego entraremos mas en detalle como hacer que "aprenda" a hacer cosas mas interesantes. Haremos una clase de prueba que cree la Neurona, le asigne algunos valores, haga unos cálculos y nos retorne por consola los valores de sus atributos:

/**
 * @author Vincent
 */
public class NeuronaTest {
 
 /**
  * @param args
  */
 public static void main(String[] args){
  // crea la neruona indicando que tendra 2 entradas
  Neurona U = new Neurona(2);
  // asigna valores a sus 2 entradas
  U.x[0] = 10;
  U.x[1] = 8.7;
  // hace los calculos correspondientes
  U.calcularNet();
  // imprime por consola
  printEntradas(U);
  printPesos(U);
  printEntradaNeta(U);
  printValorActivacion(U);
  printSalida(U);
 }
 
 //--------------- Impresion por consola ---------------//
 /**
  * @param U
  */
 private static void printEntradas(Neurona U){
  printArray("entradas", U.x);
 }
 /**
  * @param U
  */
 private static void printPesos(Neurona U){
  printArray("pesos", U.w);
 }
 
 /**
  * @param U
  */
 private static void printEntradaNeta(Neurona U){
  System.out.println("Net: " + U.Net);
 }
 
 /**
  * @param U
  */
 private static void printValorActivacion(Neurona U){
  System.out.println("Valor de Activacion: " + U.activacion);
 }
 
 /**
  * @param U
  */
 private static void printSalida(Neurona U){
  System.out.println("salida: " + U.y);
 }
 
 /**
  * @param array
  */
 private static void printArray(String nombre, double[] array){
  System.out.print(nombre + ": [");
  for (int i = 0; i < array.length-1; i++) {
   System.out.print(array[i] + ", ");
  }
  System.out.print(array[array.length-1]);
  System.out.println("]");  
 }
}

Al ejecutar la clase de prueba nos dará la siguiente salida:

entradas: [10.0, 8.7]
pesos: [0.5, 0.5]
Net: 9.35
Estado de Activacion: 0.0
salida: 0.0

Vemos que el Estado de Activación y su salida y son 0, esto se debe a que aun no le hemos agregado ni la Función de Activación ni la Función de Transferencia así que en la próxima publicación veremos esas funciones y la implementaremos en Java.

Hasta la próxima !!!

No hay comentarios:

Publicar un comentario

Nota: solo los miembros de este blog pueden publicar comentarios.