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




