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)
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.
Archivo del blog
sábado, 22 de junio de 2019
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)
Suscribirse a:
Entradas (Atom)
Con la tecnología de Blogger.