Representación visual de retropropagación en una red neuronal artificial

Retropropagación: qué es y cómo funciona en el entrenamiento de redes neuronales

Introducción

Las redes neuronales artificiales han impulsado avances importantes en inteligencia artificial: reconocimiento de imágenes, procesamiento de lenguaje natural, predicción de señales, clasificación de datos y muchas otras tareas.

Una de las ideas centrales detrás de su entrenamiento es la retropropagación, también conocida como backpropagation. Este algoritmo permite calcular qué tanto contribuyó cada peso de la red al error final y ajustar esos pesos para mejorar la predicción.

Dicho de forma simple: una red neuronal hace una predicción, mide qué tan equivocada estuvo y después reparte ese error hacia atrás para corregir sus conexiones internas. Esa corrección repetida, combinada con gradiente descendente, es lo que permite que la red aprenda.

Nota importante

El ejemplo de dengue que aparece en este artículo es únicamente educativo para explicar una red neuronal simple. No debe usarse como herramienta médica, diagnóstico ni recomendación clínica. Cualquier sospecha de enfermedad debe revisarse con personal de salud calificado.

¿Qué es la retropropagación?

La retropropagación es un algoritmo utilizado para entrenar redes neuronales artificiales. Su objetivo es calcular cómo deben ajustarse los pesos y sesgos de la red para reducir el error entre la predicción y la respuesta esperada.

El proceso se basa en dos movimientos principales:

  • Propagación hacia adelante: los datos entran a la red, pasan por sus capas y generan una predicción.
  • Propagación hacia atrás: el error se calcula en la salida y se distribuye hacia las capas anteriores para actualizar pesos y sesgos.

Para actualizar los pesos, backpropagation utiliza derivadas y la regla de la cadena. En la práctica, esto permite saber qué dirección reduce mejor la función de pérdida.

Idea clave

Backpropagation no “adivina” cómo ajustar una red neuronal. Calcula gradientes para saber qué pesos deben subir o bajar y en qué proporción.

Propagación hacia adelante y hacia atrás

Para entender backpropagation, primero hay que separar el entrenamiento en dos fases. Una red neuronal no aprende solamente generando salidas; aprende cuando compara esas salidas contra una respuesta esperada y corrige sus parámetros.

1. Propagación hacia adelante

Durante la propagación hacia adelante, cada entrada se multiplica por pesos, se suman sesgos y se aplican funciones de activación. El resultado fluye de capa en capa hasta producir una salida.

Por ejemplo, si la red recibe síntomas codificados como números, puede generar una probabilidad entre 0 y 1 usando una función sigmoide en la salida.

2. Cálculo del error

Una vez que la red produce una salida, esa predicción se compara con el valor esperado. La diferencia se mide mediante una función de pérdida. En ejemplos simples puede usarse error cuadrático, aunque en clasificación binaria suele ser más común usar entropía cruzada.

3. Propagación hacia atrás

En la propagación hacia atrás, el algoritmo calcula gradientes: pequeñas señales matemáticas que indican cómo cambiar cada peso para reducir el error.

Después, los pesos se actualizan usando una tasa de aprendizaje. Si la tasa es demasiado alta, el modelo puede volverse inestable. Si es demasiado baja, puede tardar demasiado en aprender.

Construcción de una red neuronal simple

Para aterrizar la idea, construiremos una red neuronal pequeña en Python. El ejemplo usa tres entradas que representan síntomas codificados entre 0 y 1:

  • Fiebre alta: valor cercano a 1 si el síntoma está presente.
  • Dolor de cabeza: valor cercano a 1 si el síntoma es fuerte.
  • Dolor muscular: valor cercano a 1 si está presente.

La salida será un valor entre 0 y 1. En un caso real se necesitarían datos clínicos, validación médica, muchas variables, evaluación rigurosa y supervisión profesional. Aquí lo usamos solamente como ejemplo técnico para entender backpropagation.

Arquitectura del ejemplo

La red tendrá tres entradas, una capa oculta con dos neuronas y una neurona de salida. Usaremos ReLU en la capa oculta y sigmoide en la salida.

Implementación en Python

Empecemos definiendo las funciones de activación, los datos de entrada y los pesos iniciales de la red.

import numpy as np

# Función de activación ReLU
def relu(x):
    return np.maximum(0, x)

# Derivada de ReLU
def relu_deriv(x):
    return np.where(x > 0, 1, 0)

# Función de activación sigmoide
def sigmoid(x):
    return 1 / (1 + np.exp(-x))

# Derivada de sigmoide usando la salida ya calculada
def sigmoid_deriv_from_output(y_hat):
    return y_hat * (1 - y_hat)

# Entrada: fiebre, dolor de cabeza y dolor muscular
X = np.array([[0.9, 0.8, 1.0]])

# Salida esperada: 1 representa caso positivo en este ejemplo didáctico
y = np.array([[1.0]])

# Pesos iniciales
W1 = np.array([
    [0.5, 0.2, 0.8],
    [0.9, 0.7, 0.3]
])

W2 = np.array([[1.2, 0.5]])

# Sesgos iniciales
b1 = np.array([[-0.1], [0.2]])
b2 = np.array([[-0.3]])

# Propagación hacia adelante
z1 = np.dot(W1, X.T) + b1
h1 = relu(z1)

z2 = np.dot(W2, h1) + b2
output = sigmoid(z2)

print("Salida inicial:", output)
Salida inicial de una red neuronal antes de aplicar retropropagación
La salida inicial muestra la predicción de la red antes de ajustar pesos y sesgos.

En este primer paso, la red todavía no ha aprendido. Solo está usando pesos iniciales para generar una predicción. Lo interesante ocurre cuando calculamos el error y usamos backpropagation para ajustar los parámetros.

Cálculo de la retropropagación

Después de obtener la salida, calculamos el error y propagamos ese error hacia atrás. Luego actualizamos pesos y sesgos usando una tasa de aprendizaje.

# Tasa de aprendizaje
learning_rate = 0.1

# Cálculo del error
error = y - output

# Gradiente en la salida
d_output = error * sigmoid_deriv_from_output(output)

# Gradiente en la capa oculta
d_h1 = np.dot(W2.T, d_output) * relu_deriv(z1)

# Actualización de pesos y sesgos
W2 += learning_rate * np.dot(d_output, h1.T)
b2 += learning_rate * d_output

W1 += learning_rate * np.dot(d_h1, X)
b1 += learning_rate * d_h1

# Nueva propagación hacia adelante después del ajuste
z1_new = np.dot(W1, X.T) + b1
h1_new = relu(z1_new)

z2_new = np.dot(W2, h1_new) + b2
output_new = sigmoid(z2_new)

print("Nueva salida después de retropropagación:", output_new)
Salida de la red neuronal después de aplicar retropropagación
Después de actualizar los pesos, la salida se mueve en dirección al valor esperado.

Este ejemplo muestra una sola actualización. En un entrenamiento real, este proceso se repite muchas veces sobre muchos ejemplos hasta que el error disminuye o el modelo deja de mejorar.

Visualización del progreso del entrenamiento

Para observar cómo aprende la red, podemos ejecutar varias iteraciones y registrar el error en cada época. La curva ideal debería tender a disminuir, aunque en problemas reales puede tener ruido o estancarse.

import numpy as np
import matplotlib.pyplot as plt

# Reiniciar pesos y sesgos para el ejemplo
W1 = np.array([
    [0.5, 0.2, 0.8],
    [0.9, 0.7, 0.3]
])

W2 = np.array([[1.2, 0.5]])

b1 = np.array([[-0.1], [0.2]])
b2 = np.array([[-0.3]])

learning_rate = 0.1
epochs = 1000
errors = []

for epoch in range(epochs):
    # Forward pass
    z1 = np.dot(W1, X.T) + b1
    h1 = relu(z1)

    z2 = np.dot(W2, h1) + b2
    output = sigmoid(z2)

    # Error
    error = y - output
    errors.append(np.mean(np.abs(error)))

    # Backpropagation
    d_output = error * sigmoid_deriv_from_output(output)
    d_h1 = np.dot(W2.T, d_output) * relu_deriv(z1)

    # Actualización
    W2 += learning_rate * np.dot(d_output, h1.T)
    b2 += learning_rate * d_output

    W1 += learning_rate * np.dot(d_h1, X)
    b1 += learning_rate * d_h1

# Graficar el error después del entrenamiento
plt.figure(figsize=(10, 5))
plt.plot(errors)
plt.title("Progreso del entrenamiento")
plt.xlabel("Iteraciones")
plt.ylabel("Error medio absoluto")
plt.grid(True)
plt.show()

Es importante que la gráfica se genere fuera del ciclo. Si llamas plt.show() dentro de cada iteración, el programa intentará abrir una gráfica en cada época y el flujo se vuelve ineficiente.

Interpretación de la curva

Si el error baja con el tiempo, significa que la red está ajustando sus pesos en una dirección útil. Si el error no baja, puede haber problemas con la tasa de aprendizaje, la arquitectura, los datos, la función de activación o la forma en que se calcularon los gradientes.

Mejores prácticas al entrenar redes neuronales

Backpropagation es una herramienta poderosa, pero el entrenamiento de redes neuronales requiere varios cuidados para evitar modelos inestables, lentos o sobreajustados.

Entrenamiento estable

  • Ajusta cuidadosamente la tasa de aprendizaje.
  • Normaliza las entradas.
  • Usa funciones de activación adecuadas.
  • Monitorea la pérdida durante el entrenamiento.

Generalización

  • Separa datos de entrenamiento y prueba.
  • Usa validación para ajustar hiperparámetros.
  • Aplica regularización cuando sea necesario.
  • Evita entrenar demasiadas épocas sin control.

1. Ajuste de la tasa de aprendizaje

La tasa de aprendizaje define qué tan grandes son los pasos al ajustar los pesos. Una tasa alta puede hacer que el modelo salte sobre el mínimo. Una tasa baja puede hacer que el entrenamiento sea muy lento.

2. Regularización para evitar sobreajuste

El sobreajuste ocurre cuando la red memoriza los datos de entrenamiento pero falla con datos nuevos. Técnicas como regularización L2, dropout, early stopping y aumento de datos pueden ayudar a reducir este problema.

3. Optimizadores modernos

Aunque el gradiente descendente simple es útil para entender la base, en proyectos reales se usan optimizadores como Adam, RMSProp o SGD con momentum, porque suelen converger de forma más estable.

4. Normalización de datos

Si las variables de entrada tienen escalas muy distintas, el entrenamiento puede volverse lento o inestable. Normalizar o estandarizar los datos ayuda a que la red aprenda mejor.

5. Validación y early stopping

Separar datos de validación permite monitorear si el modelo realmente está generalizando. Con early stopping, puedes detener el entrenamiento cuando el error de validación deja de mejorar.

Limitaciones del ejemplo

El ejemplo anterior es intencionalmente pequeño para que se entienda el mecanismo de backpropagation. Sin embargo, no representa un sistema real de diagnóstico ni un modelo clínico.

  • Usa un solo registro de entrada.
  • No contiene datos reales ni representativos.
  • No tiene conjunto de validación ni prueba.
  • No evalúa sensibilidad, especificidad ni métricas clínicas.
  • No considera contexto médico, pruebas de laboratorio ni diagnóstico profesional.

En machine learning aplicado a salud, la validación debe ser mucho más estricta. Los modelos pueden ser útiles como apoyo, pero nunca deben sustituir una evaluación médica.

Conclusión

La retropropagación es una pieza fundamental del entrenamiento de redes neuronales. Su función es calcular cómo ajustar pesos y sesgos para reducir el error del modelo en cada iteración.

A lo largo del artículo vimos la diferencia entre propagación hacia adelante y propagación hacia atrás, cómo se calcula el error, cómo se actualizan pesos con una tasa de aprendizaje y cómo visualizar el progreso del entrenamiento.

También revisamos buenas prácticas como normalización, regularización, validación, optimizadores modernos y control de épocas. Estas decisiones son clave para que una red no solo aprenda los datos de entrenamiento, sino que pueda generalizar a datos nuevos.

Entender backpropagation permite mirar las redes neuronales con menos misterio. No son magia: son sistemas matemáticos que ajustan parámetros de forma iterativa para reducir una función de pérdida.

Recursos adicionales

¿Tienes una idea?

Si este tema te interesa, podemos convertirlo en un proyecto real.

Puedo ayudarte a crear modelos de machine learning, explicar conceptos de IA, construir notebooks técnicos o convertir experimentos de redes neuronales en contenido claro y visualmente atractivo.

Platícame tu idea