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, 12 de diciembre de 2014

Red neuronal artificial (III). Añadiendo pesos a los enlaces y cálculo de salidas.

Una vez creada la estructura básica de la red, voy a ir añadiendo valores aleatorios a los enlaces (pesos - w). Hecho esto ya se puede calcular los valores de salida de cada neurona (y).
Las formulas utilizadas para los cálculos son los mismos que ver referencia.


Código 1 (RedNeuronal1.java): 

package redneuronal1;

import java.util.ArrayList;
import java.util.Random;

public class RedNeuronal1 {

    public static void main(String[] args) {

        int nNeuronas = 9;
        int nEnlaces = 50;

        ArrayList<Integer>[] S = new ArrayList[nNeuronas];
        ArrayList<Integer>[] E = new ArrayList[nNeuronas];

        AleatoriedadCondicionada ac = new AleatoriedadCondicionada();
        Random r1 = new Random();        
        int nSalidas = 1;
        int neurona;

        //Crea red neuronal aleatoria
        for (int i = 0; i < S.length; i++) {
            S[i] = new ArrayList();
            E[i] = new ArrayList();

            //Salidas maxima por neurona            
            nSalidas = r1.nextInt(nEnlaces / nNeuronas) + 1;
            for (int j = 0; j < nSalidas; j++) {

                neurona = r1.nextInt(nNeuronas);

                //Aplicación de la Aleatoriedad Condicionada
                neurona = (int) Math.rint(ac.getSalida(nNeuronas, neurona));
                if (r1.nextBoolean()) {
                    //Conexión hacia delante
                    neurona = i + neurona;
                    if (neurona > nNeuronas) {
                        neurona = neurona - nNeuronas;
                    }
                } else {
                    //Conexión hacia atrás
                    neurona = i - neurona;
                    if (neurona < 0) {
                        neurona = neurona + nNeuronas;
                    }
                }
                //Evitar enlaces repetidos a la misma neurona
                if (S[i].contains(neurona) == false) {
                    S[i].add(neurona);
                }
            }
        }

        //Búsqueda enlaces de entrada de cada neurona
        for (int i = 0; i < S.length; i++) {
            for (int j = 0; j < E.length; j++) {
                if (S[i].contains(j)) {
                    E[j].add(i);
                }
            }
        }

        //Añadiendo Pesos (w) a los enlaces
        ArrayList<Double>[] w = new ArrayList[nNeuronas];
        int aux = 0;
        for (int i = 0; i < E.length; i++) {
            w[i] = new ArrayList();
            aux = E[i].size();
            for (int j = 0; j < aux; j++) {
                w[i].add(Math.rint(r1.nextDouble() * 10000) / 10000);
            }
        }

        //Cálculo de salidas (y)
        //Inicializando valores de salida
        double[] y = new double[nNeuronas];
        for (int i = 0; i < nNeuronas; i++) {
            y[i] = 1.0;
        }

        //Realización de los cálculos (y)
        double tmp = 0;
        for (int i = 0; i < nNeuronas; i++) {
            tmp = 0;
            for (int j = 0; j < E[i].size(); j++) {
                tmp += (y[E[i].get(j)] * w[i].get(j));
            }
            y[i] = Math.rint(Math.tanh(tmp) * 10000) / 10000;
        }

        //Mostrar enlaces de Entrada (E)
        System.out.println("\n* Enlaces entrada:");
        for (int i = 0; i < E.length; i++) {
            System.out.println("Enlaces entradas Neurona [" + i + "]: " + E[i].toString());
        }

        //Mostrar enlaces de Salidas (S)
        System.out.println("\n* Enlaces salida:");
        for (int i = 0; i < S.length; i++) {
            System.out.println("Enlaces salidas Neurona [" + i + "]: " + S[i].toString());
        }

        //Mostrar valor Pesos (w)
        System.out.println("\n* Pesos:");
        for (int i = 0; i < E.length; i++) {
            System.out.println("w[" + i + "]: " + w[i].toString());
        }

        //Mostrar Salidas calculadas (y):
        System.out.println("\n* Salidas:");
        for (int i = 0; i < nNeuronas; i++) {
            System.out.println("y[" + i + "] = " + y[i]);
        }

    }

}


Código 2 (AleatoriedadCondicionada.java):

package redneuronal1;
public class AleatoriedadCondicionada {    
    public double getSalida(double x, double num) {
        double c = Math.atan(10);
        return ((Math.atan(((num*100/x)/10)-10)*100/c)+100)*x/100;
    }
}


Resultado:

run:

* Enlaces entrada:
Enlaces entradas Neurona [0]: [2, 4]
Enlaces entradas Neurona [1]: [1]
Enlaces entradas Neurona [2]: [2, 3]
Enlaces entradas Neurona [3]: [3, 7]
Enlaces entradas Neurona [4]: [0, 4, 6]
Enlaces entradas Neurona [5]: [0, 3]
Enlaces entradas Neurona [6]: [2, 7]
Enlaces entradas Neurona [7]: [5, 7]
Enlaces entradas Neurona [8]: [8]

* Enlaces salida:
Enlaces salidas Neurona [0]: [5, 4]
Enlaces salidas Neurona [1]: [1]
Enlaces salidas Neurona [2]: [0, 2, 6]
Enlaces salidas Neurona [3]: [5, 3, 2]
Enlaces salidas Neurona [4]: [0, 4]
Enlaces salidas Neurona [5]: [7]
Enlaces salidas Neurona [6]: [4]
Enlaces salidas Neurona [7]: [6, 3, 7]
Enlaces salidas Neurona [8]: [8]

* Pesos:
w[0]: [0.8555, 0.6536]
w[1]: [0.819]
w[2]: [0.9977, 0.1134]
w[3]: [0.2289, 0.5195]
w[4]: [0.315, 0.3569, 0.5067]
w[5]: [0.9875, 0.9863]
w[6]: [0.5892, 0.3078]
w[7]: [0.5503, 0.1076]
w[8]: [0.3883]

* Salidas:
y[0] = 0.9068
y[1] = 0.6745
y[2] = 0.8045
y[3] = 0.6342
y[4] = 0.8175
y[5] = 0.9089
y[6] = 0.6537
y[7] = 0.5426
y[8] = 0.3699

BUILD SUCCESSFUL (total time: 0 seconds)


2 comentarios:

Con la tecnología de Blogger.