Definición de funciones
sigmoid <- function(z) 1 / (1 + exp(-z))
# Función auxiliar para redondeo
r <- function(x, d=4) format(round(x, d), nsmall = d)
Parámetros iniciales
# Datos
x1 <- 0
x2 <- 1
y <- 1 # target
# Pesos iniciales
w1 <- 0.1 # x1 -> h1
w2 <- 0.5 # x1 -> h2
w3 <- -0.7 # x2 -> h1
w4 <- 0.3 # x2 -> h2
w5 <- 0.2 # h1 -> o1
w6 <- 0.4 # h2 -> o1
# Biases
b1 <- 0
b2 <- 0
b3 <- 0
alpha <- 0.25
epochs <- 2
Grafo inicial
grViz("
digraph nn {
rankdir=LR;
X1 [label='X1=0', shape=circle, style=filled, fillcolor=lightcoral]
X2 [label='X2=1', shape=circle, style=filled, fillcolor=lightcoral]
h1 [label='h1', shape=circle, style=filled, fillcolor=lightblue]
h2 [label='h2', shape=circle, style=filled, fillcolor=lightblue]
O1 [label='O1', shape=circle, style=filled, fillcolor='#90EE90']
# edges con pesos
X1 -> h1 [label='w1=0.1']
X1 -> h2 [label='w2=0.5']
X2 -> h1 [label='w3=-0.7']
X2 -> h2 [label='w4=0.3']
h1 -> O1 [label='w5=0.2']
h2 -> O1 [label='w6=0.4']
}
")
Forward Propagation (Época 1)
z1 <- w1 * x1 + w3 * x2 + b1
f1 <- sigmoid(z1)
z2 <- w2 * x1 + w4 * x2 + b2
f2 <- sigmoid(z2)
z3 <- w5 * f1 + w6 * f2 + b3
f3 <- sigmoid(z3)
Etotal <- 0.5 * (y - f3)^2
cat('Forward:\n')
## Forward:
cat(' z1 =', r(z1), ' f1 =', r(f1), '\n')
## z1 = -0.7000 f1 = 0.3318
cat(' z2 =', r(z2), ' f2 =', r(f2), '\n')
## z2 = 0.3000 f2 = 0.5744
cat(' z3 =', r(z3), ' f3 =', r(f3), '\n')
## z3 = 0.2961 f3 = 0.5735
cat(' Etotal =', r(Etotal), '\n')
## Etotal = 0.0910
Grafo con activaciones
grViz(paste0("
digraph nn {
rankdir=LR;
X1 [label='X1=",x1,"', shape=circle, style=filled, fillcolor=lightcoral]
X2 [label='X2=",x2,"', shape=circle, style=filled, fillcolor=lightcoral]
h1 [label='h1\\n f1=", r(f1), "', shape=circle, style=filled, fillcolor=lightblue]
h2 [label='h2\\n f2=", r(f2), "', shape=circle, style=filled, fillcolor=lightblue]
O1 [label='O1\\n f3=", r(f3), "', shape=circle, style=filled, fillcolor='#90EE90']
X1 -> h1 [label='w1=", w1, "']
X1 -> h2 [label='w2=", w2, "']
X2 -> h1 [label='w3=", w3, "']
X2 -> h2 [label='w4=", w4, "']
h1 -> O1 [label='w5=", w5, "']
h2 -> O1 [label='w6=", w6, "']
}
"))
Backpropagation (una iteración)
delta3 <- (y - f3) * (f3 * (1 - f3))
dE_w5 <- delta3 * f1
dE_w6 <- delta3 * f2
w5_old <- w5
w6_old <- w6
w5 <- w5 - alpha * dE_w5
w6 <- w6 - alpha * dE_w6
dE_z1 <- delta3 * w5_old * (f1 * (1 - f1))
dE_w1 <- dE_z1 * x1
dE_w3 <- dE_z1 * x2
dE_z2 <- delta3 * w6_old * (f2 * (1 - f2))
dE_w2 <- dE_z2 * x1
dE_w4 <- dE_z2 * x2
w1 <- w1 - alpha * dE_w1
w3 <- w3 - alpha * dE_w3
w2 <- w2 - alpha * dE_w2
w4 <- w4 - alpha * dE_w4
cat('Pesos actualizados:\n')
## Pesos actualizados:
cat(' w1 =', r(w1), ' w2 =', r(w2), ' w3 =', r(w3), ' w4 =', r(w4), '\n')
## w1 = 0.1000 w2 = 0.5000 w3 = -0.7012 w4 = 0.2974
cat(' w5 =', r(w5), ' w6 =', r(w6), '\n')
## w5 = 0.1913 w6 = 0.3850
Grafo con pesos actualizados
grViz(paste0("
digraph nn {
rankdir=LR;
X1 [label='X1=",x1,"', shape=circle, style=filled, fillcolor=lightcoral]
X2 [label='X2=",x2,"', shape=circle, style=filled, fillcolor=lightcoral]
h1 [label='h1', shape=circle, style=filled, fillcolor=lightblue]
h2 [label='h2', shape=circle, style=filled, fillcolor=lightblue]
O1 [label='O1\\n f3=", r(f3), "',
shape=circle, style=filled, fillcolor='#90EE90']
X1 -> h1 [label='w1=", r(w1), "']
X1 -> h2 [label='w2=", r(w2), "']
X2 -> h1 [label='w3=", r(w3), "']
X2 -> h2 [label='w4=", r(w4), "']
h1 -> O1 [label='w5=", r(w5), "']
h2 -> O1 [label='w6=", r(w6), "']
}
"))