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 !!!

jueves, 6 de agosto de 2015

Estructura de la Neurona Artificial

Las introducciones a nuevos temas por lo general son algo aburridas porque implica introducir muchos conceptos nuevos para comprender de que se trata el tema principal, trataré de ser lo mas breve posible, luego si es necesario ampliaré un poco mas para que no nos queden cosas sueltas.

La Neurona Biológica

Para comprender como funciona una Neurona Artificial primero veamos un poco como es una neurona biológica. Una neurona básicamente es una célula viva que además de contener lo que contiene cualquier célula, tiene algunos elementos característicos (no soy neurobiólogo, así que no me podré explayar mas, aunque quisiera ):
  • Dendritas: son los puntos de entrada a la neurona y es por donde llegan las señales al interior de la neurona (la señal puede provenir de otra neurona).
  • Cuerpo: contiene el núcleo de la célula.
  • Axón: es el punto de salida de la neurona, transporta la señal del interior hacia el exterior (u otra neurona).
  • Sinapsis: es el punto de conexión con otra neurona.
Funciona básicamente así: la neurona recibe en su Cuerpo celular las señales provenientes del exterior a través de las Dendritas, la señal se procesa en el interior de la neurona y emite una señal de salida que es transportada por el Axón hacia el exterior, que bien podrían ser otras neuronas. El punto de conexión entre neuronas o Sinapsis puede ser de tipo excitadora, es decir, producen una activación en la neurona con la que está conectada; o bien puede ser de tipo inhibidora, es decir, inhiben la activación de la neurona con la que esta conectada.

Una de las características que diferencia las neuronas del resto de las células vivas, como acabo de comentar, es su capacidad de comunicarse entre si, de esto se deduce que encontraremos no una, sino muchísimas neuronas interconectadas unas con otras formando una Red Neuronal, este último concepto lo desarrollaremos mas adelante.

La Neurona Artificial

Ya nos estamos acercando a donde queremos llegar !!!. Una Neurona Artificial se basa en el modelo de neurona biológica intentando imitar su comportamiento con la intención de que pueda resolver problemas lo mas parecido posible a como lo hacen los seres biológicos. El trabajo que tiene que hacer un Neurona Artificial es muy simple, consiste en recibir las entradas (del mundo exterior o de otras neuronas), calcular el valor de la salida (señal) y enviar la señal de salida (de nuevo al mundo exterior o bien a otras neuronas). Hasta este momento todo es muy simple, pero ahora viene la parte "nerd" ya que debemos formalizar este planteo que estamos haciendo.
  • Vamos a referirnos a una Neurona Artificial como U.
  • En un instante dado, la neurona U posee un valor numérico denominado Valor de Activación o Estado de Activación.
  • El cálculo que hace la neurona para transformar las señales de entrada en una señal de salida se llama Función de Transferencia.
  • Vamos a referirnos a la señal de salida como y.
  • Vamos a referirnos a cada entrada de la neurona como xi.
  • Las entradas xi se verán afectada por la Sinapsis que se representará como un peso asociado a cada entrada y que llamaremos wi.


  • Net es la entrada neta de la neurona y se obtiene haciendo la sumatoria del producto entre cada entrada y su peso asociado. (neeeeeeerrrrrrdddddddd!!!)
  • G(Net) es la Función de Activación o Regla de Activación.
  • F[G(Net)] es la Función de Salida o Función de Transferencia.
Por hoy vamos a llegar hasta acá, el próximo post se va a poner mejor ya que llevaremos todo esto a código JAVA, vamos crear una clase Neurona con todas estas característas para posteriormente intentar que aprenda algo.



viernes, 17 de julio de 2015

Hola Mundo !!!

Este es el primer post del primer blog de mi vida, a ver que sale. La idea del blog es bajar a tierra algunos conocimientos, es decir, al mundo terrenal. En la Universidad aprendí muchos conceptos a los cuales me pregunté ¿y esto para que me sirve? ¿voy a usar esto en algún momento? como la mayoría de las veces no encontraba respuesta a ese estilo de preguntas, solo estudiaba los conceptos, cálculos, g, etc, sin saber mucho de la aplicación practica de ello, con entender mas o menos el concepto y aprobar los exámenes alcanzaba. Para no quedar mal ni con la Universidad, ni con mi Profesión vale aclarar que muchas otras si las entendí con el nivel de profundidad necesaria y las aplico a diario en el mundo laboral. Ya graduado, mas aliviado, luego de noches enteras (y madrugadas también) de estudio, realización de trabajos prácticos y tesis final, sentí el inmenso alivio, ya está, ya me gradué, ahora a disfrutar !!!


Luego me sucedió algo que no pensé que sucedería, comencé a sentir un síndrome de abstinencia, llegaba a mi casa luego del trabajo, me sentaba, miraba mi escritorio, compañero de noches de desvelo, y me sentía vacío, tanto estudio que me hizo pasar de revoluciones me hizo "adicto" al aprender, dirán que estoy mal de la cabeza, yo les diría que es muy probable, así que me dije: voy a aprovecharlo para tratar de comprender aquellas cosas que vi en la Universidad y que me parecieron interesantes pero como los tiempos me corrían entonces, no le dediqué el tiempo para meterme de lleno, comprender realmente de que se trata, y bajarlo a tierra y verlo funcionando en la vida real.


Una de las materias que me resultaron súper interesantes pero que vi muy a vuelo de pájaro fue Inteligencia Artificial (IA para los amigos), con solo escuchar el nombre uno pensaría, "Que groso !!! Inteligencia Artificial", pero la verdad solo hicimos un par de Trabajos Prácticos en grupo, y no me quedaron claro algunos conceptos.

Así que la idea inicial de este blog será abordar este tema, con algo de teoría (amena) para comprender rápidamente de que se trata, y poner ejemplos en JAVA para verlo en vivo y en directo, funcionando. Vi que hay muchos blogs sobre este tema, y muy buenos, yo trataré de poner mi impronta, pondré a trabajar Mis Dos Neuronas para hacerlo fácil, rápido y práctico.