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.

sábado, 22 de junio de 2019

Perceptrón multicapa. Ajuste pesos.

Siguiendo el hilo anterior en esta ocasión se procede ajustar los pesos (W) para minimizar el error. Para ello son utilizadas las siguientes variables:

μ  = Tasa de aprendizaje
δ  = Error neurona (E)
Ø  = Bias (-1)
ʄ  = Función de activación
ʄ' = Derivada de la función de activación
ΔW = Delta de los pesos




Función Sigmoide:

ʄ(x)  = 1 / ( 1 + e^(-x) )


Derivada función Sigmoide:

ʄ'(x) = ʄ(x) * ( 1 - ʄ(x) )


Cálculo deltas(Δ) de los pesos:

ΔW = µ * δ * ʄ'(x) * Y
ΔW = µ * δ * ʄ'(x) * Ø -> para ajuste pesos del Bias(Ø)


Ajuste pesos:

W' = W + ΔW




Código Java:


package ajustePesos;

import java.util.ArrayList;
import java.util.List;

public class AjustePesos {

   public static void main(String[] args) {

      //sketch: num neuronas
      List<Integer> nN = new ArrayList<>();
      nN.add(2);
      nN.add(3);
      nN.add(2);
      nN.add(1);

      double µ = 0.001;
      int r = 0; // num. registro del dataset
      int nK = nN.size(); // num. de capas = 4
      int nE = nN.get(0); // num. de entradas = 2
      int nS = nN.get(nK - 1); // num. de salidas = 1
      String tmp;

      // 2.0:-------------------------------------------------------------------
      System.out.println("Ajuste pesos:\n");
      k = 1;
      for (int j = 0; j < nN.get(k); j++) {
         for (int i = 0; i < nE; i++) {
            System.out.format("W'[%d][%d][%d] = W[%d][%d][%d] + ( µ * E[%d][%d] * F'(Y[%d][%d]) * D[%d][%d] )\n", k, j, i, k, j, i, k, j, k, j, r, i);
         }
         System.out.format("WB'[%d][%d] = WB[%d][%d] + ( µ * E[%d][%d] * F'(Y[%d][%d]) * %d)\n\n", k, j, k, j, k, j, k, j, - 1);
      }

      // 2.1:-------------------------------------------------------------------
      System.out.println("");
      for (k = 2; k < nK; k++) {
         for (int j = 0; j < nN.get(k); j++) {
            for (int i = 0; i < nN.get(k - 1); i++) {
               System.out.format("W'[%d][%d][%d] = W[%d][%d][%d] + ( µ * E[%d][%d] * F'( Y[%d][%d] ) * Y[%d][%d] )\n", k, j, i, k, j, i, k, j, k, j, k - 1, i);
            }
            System.out.format("WB'[%d][%d] = WB[%d][%d] + ( µ * E[%d][%d] * F'(Y[%d][%d]) * (%d) )\n\n", k, j, k, j, k, j, k, j, -1);
         }
         System.out.println("");
      }

   }

}


Resultado:

run:
Ajuste pesos:

W'[1][0][0] = W[1][0][0] + ( µ * E[1][0] * F'(Y[1][0]) * D[0][0] )
W'[1][0][1] = W[1][0][1] + ( µ * E[1][0] * F'(Y[1][0]) * D[0][1] )
WB'[1][0] = WB[1][0] + ( µ * E[1][0] * F'(Y[1][0]) * -1)

W'[1][1][0] = W[1][1][0] + ( µ * E[1][1] * F'(Y[1][1]) * D[0][0] )
W'[1][1][1] = W[1][1][1] + ( µ * E[1][1] * F'(Y[1][1]) * D[0][1] )
WB'[1][1] = WB[1][1] + ( µ * E[1][1] * F'(Y[1][1]) * -1)

W'[1][2][0] = W[1][2][0] + ( µ * E[1][2] * F'(Y[1][2]) * D[0][0] )
W'[1][2][1] = W[1][2][1] + ( µ * E[1][2] * F'(Y[1][2]) * D[0][1] )
WB'[1][2] = WB[1][2] + ( µ * E[1][2] * F'(Y[1][2]) * -1)


W'[2][0][0] = W[2][0][0] + ( µ * E[2][0] * F'( Y[2][0] ) * Y[1][0] )
W'[2][0][1] = W[2][0][1] + ( µ * E[2][0] * F'( Y[2][0] ) * Y[1][1] )
W'[2][0][2] = W[2][0][2] + ( µ * E[2][0] * F'( Y[2][0] ) * Y[1][2] )
WB'[2][0] = WB[2][0] + ( µ * E[2][0] * F'(Y[2][0]) * (-1) )

W'[2][1][0] = W[2][1][0] + ( µ * E[2][1] * F'( Y[2][1] ) * Y[1][0] )
W'[2][1][1] = W[2][1][1] + ( µ * E[2][1] * F'( Y[2][1] ) * Y[1][1] )
W'[2][1][2] = W[2][1][2] + ( µ * E[2][1] * F'( Y[2][1] ) * Y[1][2] )
WB'[2][1] = WB[2][1] + ( µ * E[2][1] * F'(Y[2][1]) * (-1) )


W'[3][0][0] = W[3][0][0] + ( µ * E[3][0] * F'( Y[3][0] ) * Y[2][0] )
W'[3][0][1] = W[3][0][1] + ( µ * E[3][0] * F'( Y[3][0] ) * Y[2][1] )
WB'[3][0] = WB[3][0] + ( µ * E[3][0] * F'(Y[3][0]) * (-1) )


BUILD SUCCESSFUL (total time: 5 seconds)


miércoles, 12 de junio de 2019

Perceptrón multicapa. Propagación hacia atrás.




Descripción:

En base al valor de salida del dataset (D02), se visualiza la base conceptual para el cálculo de los errores (Exx) de cada neurona (Yxx) de una red neuronal tipo perceptrón multicapa. Todo ese proceso se le llama propagación hacia atrás.



Nomenclatura:

Y[k][j]: Salida neurona (capa, posición j-enésima)

E[k][j]: Error neurona (δ) (capa, posición j-enésima)
W[k][j][i]: Peso (capa, neurona destino, neurona origen)



Código Java:

package backward;

import java.util.ArrayList;
import java.util.List;

public class Backward
{

   public static void main(String[] args) {

      //sketch: num neuronas
      List<Integer> nN = new ArrayList<>();
      nN.add(2);
      nN.add(3);
      nN.add(2);
      nN.add(1);

      int r = 0; // num. registro del dataset
      int nK = nN.size(); // num. de capas = 4
      int nE = nN.get(0); // num. de entradas = 2
      int nS = nN.get(nK - 1); // num. de salidas = 1
      String tmp;

      // 1.0:-------------------------------------------------------------------
      System.out.println("Backward:\n");
      int k = nK - 1;
      for (int j = 0; j < nS; j++) {
         System.out.format("E[%d][%d] = ( D[%d][%d] - Y[%d][%d] )\n", k, j, r, nE + j, k, j);
      }

      // 1.1:-------------------------------------------------------------------
      System.out.println("");
      for (k = k - 1; k > 0; k--) {
         for (int j = nN.get(k); j > 0; j--) {
            tmp = "";
            for (int i = nN.get(k + 1); i > 0; i--) {
               tmp += String.format("( E[%d][%d] * W[%d][%d][%d] ) + ", k + 1, i - 1, k + 1, i - 1, j - 1);
            }
            System.out.format("E[%d][%d] = %s%s\n", k, j - 1, tmp, "0 ");
         }
         System.out.println("");
      }

   }

}



Resultado:

run:
Backward:

E[3][0] = ( D[0][2] - Y[3][0] )

E[2][1] = ( E[3][0] * W[3][0][1] ) + 0
E[2][0] = ( E[3][0] * W[3][0][0] ) + 0

E[1][2] = ( E[2][1] * W[2][1][2] ) + ( E[2][0] * W[2][0][2] ) + 0
E[1][1] = ( E[2][1] * W[2][1][1] ) + ( E[2][0] * W[2][0][1] ) + 0
E[1][0] = ( E[2][1] * W[2][1][0] ) + ( E[2][0] * W[2][0][0] ) + 0 



BUILD SUCCESSFUL (total time: 1 second)



lunes, 10 de junio de 2019

Perceptrón multicapa. Propagación hacia adelante.





Descripción:

En base a los valores de entrada Dxx (dataset), Wxxx (pesos) y WBxx (bias pesos), se visualiza la base conceptual para el cálculo de las salidas de las neuronas (Yxx) de una red neuronal tipo perceptrón multicapa. Todo ese proceso se le llama propagación hacia delante.


Nomenclatura:

Y[k][j]: Salida neurona (capa, posición j-enésima)
W[k][j][i]: Peso (capa, neurona destino, neurona origen)
WB[k][j]: Pesos Bias (capa, posición j-enésima)
F: Función Activación



Dataset:
 
D[row][col]: Dataset (fila, columna)


     0     1     2     col(n)
0   D00   D01   D02     .
1   D10   D11   D12     .
2   D20   D21   D22     .
.    .     .     .      .
row(n)    




 
Código Java:

package forward;

import java.util.ArrayList;
import java.util.List;

public class Forward {

   public static void main(String[] args) {

      //sketch: num neuronas
      List<Integer> nN = new ArrayList<>();
      nN.add(2);
      nN.add(3);
      nN.add(2);
      nN.add(1);

      int r = 0; // num. registro del dataset
      int nK = nN.size(); // num. de capas = 4
      int nE = nN.get(0); // num. de entradas = 2
      int nS = nN.get(nK - 1); // num. de salidas = 1
      String tmp;

      // 0.0:-------------------------------------------------------------------
      System.out.println("
Forward:\n");
      int k = 1;
      for (int j = 0; j < nN.get(k); j++) {
         tmp = "";
         for (int i = 0; i < nE; i++) {
            tmp += String.format("( D[%d][%d] * W[%d][%d][%d] ) + ", r, i, k, j, i);
         }
         System.out.format("Y[%d][%d] = F{ %s( -1 * WB[%d][%d] ) }\n", k, j, tmp, k, j);
      }

      // 0.1:-------------------------------------------------------------------
      System.out.println("");
      for (k = 2; k < nK; k++) {
         for (int j = 0; j < nN.get(k); j++) {
            tmp = "";
            for (int i = 0; i < nN.get(k - 1); i++) {
               tmp += String.format("( Y[%d][%d] * W[%d][%d][%d] ) + ", k - 1, i, k, j, i);
            }
            System.out.format("Y[%d][%d] = F{ %s( -1 * WB[%d][%d] ) }\n", k, j, tmp, k, j);
         }
         System.out.println("");
      }

   }

}



Resultado:

run: 
Forward:

Y[1][0] = F{ ( D[0][0] * W[1][0][0] ) + ( D[0][1] * W[1][0][1] ) + ( -1 * WB[1][0] ) }
Y[1][1] = F{ ( D[0][0] * W[1][1][0] ) + ( D[0][1] * W[1][1][1] ) + ( -1 * WB[1][1] ) }
Y[1][2] = F{ ( D[0][0] * W[1][2][0] ) + ( D[0][1] * W[1][2][1] ) + ( -1 * WB[1][2] ) }

Y[2][0] = F{ ( Y[1][0] * W[2][0][0] ) + ( Y[1][1] * W[2][0][1] ) + ( Y[1][2] * W[2][0][2] ) + ( -1 * WB[2][0] ) }
Y[2][1] = F{ ( Y[1][0] * W[2][1][0] ) + ( Y[1][1] * W[2][1][1] ) + ( Y[1][2] * W[2][1][2] ) + ( -1 * WB[2][1] ) }

Y[3][0] = F{ ( Y[2][0] * W[3][0][0] ) + ( Y[2][1] * W[3][0][1] ) + ( -1 * WB[3][0] ) }

BUILD SUCCESSFUL (total time: 0 seconds)
 


Con la tecnología de Blogger.