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.

domingo, 19 de noviembre de 2017

Creación de una estructura de red neuronal artificial perceptrón multicapa.

Se trata de que a partir de un vector se cree una estructura neuronal artificial basada en capas (perceptrón multicapa).
El funcionamiento es que los valores introducidos en el vector indican el número de neuronas que tiene cada capa, y la posición o el índice de estos valores corresponde a la capa a la que se aplica.

Ejemplo:

Con el vector {2, 3, 3, 1} la red tendría la siguiente estructura:





En el ejemplo también se agregan los pesos(w) de las conexiones y se calculan todas las salidas de las neuronas(s). El cálculo de las salidas se le llama "propagación hacia delante".


* Nomenclatura de los pesos(w):

w[k][j][i]

k = índice capa
j = índice conector destino
i = índice conector origen


* Nomenclatura de las salidas(s):

s[k][j]

k = índice capa
j = índice neurona

En última instancia se calcula el error, teniendo como referencia la salida deseada (d1) en contraste con la salida real.


Código1 (Red.java):

package red;
public class Red {
   public static void main(String[] args) {
      Estructura red = new Estructura();
      red.estruct();
   }
}


Código2 (Estructura.java):

package red;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random;

public class Estructura {

   int nK[] = {2, 3, 3, 1};
   double[][][] w = new double[nK.length][9][9]; //peso
   double[][] s = new double[nK.length][9]; //salida

   // tabla de entrenamiento
   final int x1[] = {34}; // entrada 1 (x1)
   final int x2[] = {23}; // entrada 2 (x2)
   final int d1[] = {57}; // salida deseada 1 (d1)

   public void estruct() {

      int row = 1;
      for (int i = 0; i < nK.length; i++) {
         row *= nK[i];
      }

      // inicializar vector con pesos aleatorios.
      double[] vw = new double[row];
      for (int i = 0; i < vw.length; i++) {
         vw[i] = new Random().nextDouble();
      }

      // Añadir los pesos(w) y cálculo salidas(s) - Propagación hacia delante -
      propagacion_hacia_delante(vw);

   }

   private void propagacion_hacia_delante(double[] vw) {

      // vector a lista  
      List<Double> lw = new ArrayList<>();
      for (int i = 0; i < vw.length; i++) {
         lw.add(vw[i]);
      }
      Iterator wi = lw.iterator();

      System.out.println("* Entradas (x1, x2): ");
      int k = 0;
      s[k][0] = x1[0] / 100.0;
      s[k][1] = x2[0] / 100.0;
      System.out.println("s[" + k + "][" + 0 + "] = " + s[k][0]);
      System.out.println("s[" + k + "][" + 1 + "] = " + s[k][1]);
      double aux;
      for (k = 1; k < nK.length; k++) {
         System.out.println("\n* Capa(k): " + k);
         for (int j = 0; j < nK[k]; j++) {
            aux = 0.0;
            for (int i = 0; i < nK[k - 1]; i++) {
               if (wi.hasNext()) {
                  w[k][j][i] = (double) wi.next();
                  System.out.println("w[" + k + "][" + j + "][" + i + "] = " + w[k][j][i]);
                  aux += s[k - 1][i] * w[k][j][i];
               }
            }
            s[k][j] = F(aux);
            System.out.println("s[" + k + "][" + j + "] = " + s[k][j]);
            System.out.println("");
         }
      }

      double error = error(s[nK.length - 1][0]);
      System.out.println("Error(%) = " + error + "\n");

   }

   // cálculo error
   private double error(double salida) {
      System.out.println("\nCalculando error: ");
      System.out.println("Salida real (s) = " + salida);
      System.out.println("Salida deseada (d1) = " + d1[0] / 100.0);
      double error = (d1[0] / 100.0) - salida;
      return Math.abs(error) * 100.0;
   }

   // función de activación(F)
   public double F(double n) {
      return 1 / (1 + Math.pow(Math.E, -n));
   }

}


Resultado:

run:

* Entradas (x1, x2):
s[0][0] = 0.34
s[0][1] = 0.23

* Capa(k): 1
w[1][0][0] = 0.8626655902899227
w[1][0][1] = 0.6463931000086637
s[1][0] = 0.6087299411252262

w[1][1][0] = 0.7796971368969626
w[1][1][1] = 0.5490805855405314
s[1][1] = 0.5966162004085603

w[1][2][0] = 0.009961780486465899
w[1][2][1] = 0.9279270075726691
s[1][2] = 0.5539912241475227


* Capa(k): 2
w[2][0][0] = 0.34979295784506204
w[2][0][1] = 0.2971577727858278
w[2][0][2] = 0.18553139517021167
s[2][0] = 0.6208132190214526

w[2][1][0] = 0.43931905607836685
w[2][1][1] = 0.20711093913624445
w[2][1][2] = 0.4093740271593507
s[2][1] = 0.6497139364472229

w[2][2][0] = 0.9188418704894066
w[2][2][1] = 0.027621699012403522
w[2][2][2] = 0.9216813528324754
s[2][2] = 0.7477050027136913


* Capa(k): 3
w[3][0][0] = 0.4759577050326803
w[3][0][1] = 0.6521570348684057
w[3][0][2] = 0.07185252070446402
s[3][0] = 0.6841523907997876


Calculando error:
Salida real (s) = 0.6841523907997876
Salida deseada (d1) = 0.57
Error(%) = 11.415239079978768



BUILD SUCCESSFUL (total time: 0 seconds)


6 comentarios:

Con la tecnología de Blogger.