Curso completo sobre redes neuronales profundas: qué significa que una red sea "profunda", cómo generalizar la propagación hacia adelante a cualquier número de capas, cómo verificar las dimensiones de todas las matrices, por qué la profundidad da poder expresivo, y cómo se organiza la implementación completa con bloques forward/backward, cachés y el bucle de entrenamiento — con ejemplos numéricos trabajados en cada sección y los vídeos de referencia de Andrew Ng enlazados.
~1 h de vídeo 8 lecciones Vídeos oficiales enlazados Ejemplos numéricos Quiz al final
Módulo 1 · Definición y notación
¿Qué es una red neuronal profunda?
Al terminar esta sección sabrás
Situar cualquier red en el espectro shallow (superficial) → deep (profunda).
Usar con soltura la notación general: L, n[l], a[l], W[l], b[l].
Entender que "profundidad" es un hiperparámetro más, no una categoría rígida.
1.1 El espectro de profundidad
Una red neuronal se construye encadenando capas, donde cada capa aplica el mismo par de operaciones: una combinación lineal z = W·(entrada) + b seguida de una activación no lineal a = g(z). La profundidad de la red es simplemente cuántas de esas capas encadena:
Regresión logística (0 capas ocultas): el modelo más "superficial" posible. Una sola neurona que va directa de la entrada a la salida. Solo puede trazar fronteras lineales.
Red de 1 capa oculta (red de "2 capas"): ya es no lineal, puede resolver problemas como XOR, pero su capacidad para componer conceptos es limitada.
Red de 2 capas ocultas: empieza a poder construir características sobre características.
Red de 5+ capas ocultas: esto ya se considera una red profunda. Aquí es donde el término "deep learning" cobra sentido literal.
La misma pieza básica (capa = lineal + activación) repetida más o menos veces. No hay un umbral oficial: la profundidad adecuada se elige empíricamente para cada problema.
Idea clave
"Profundo" no es una categoría mágica, es un espectro. El número de capas ocultas es un hiperparámetro que se ajusta como cualquier otro: para muchos problemas basta una regresión logística; para otros (visión, voz) las redes muy profundas funcionan drásticamente mejor. Lo razonable es empezar simple e ir añadiendo profundidad si el problema lo pide.
1.2 Notación general para L capas
Para trabajar con cualquier profundidad se generaliza la notación. Usaremos como red de referencia una de 4 capas (3 ocultas + 1 salida) con 3 entradas:
Símbolo
Significado
En la red de referencia
L
Número total de capas (ocultas + salida; la entrada no cuenta)
L = 4
n[l]
Número de unidades (neuronas) de la capa l
n[0]=3, n[1]=5, n[2]=5, n[3]=3, n[4]=1
a[l]
Vector de activaciones de la capa l, con a[l] = g[l](z[l])
a[0] = x (entrada), a[4] = ŷ (salida)
W[l], b[l]
Pesos y sesgos que calculan z[l]
4 pares: (W[1],b[1]) … (W[4],b[4])
g[l]
Función de activación de la capa l (puede variar por capa)
p. ej. ReLU en 1–3, sigmoide en 4
Dos convenios que cierran el sistema y hacen que todas las fórmulas generalicen sin casos especiales:
a[0] = x← la entrada es "la activación de la capa 0"a[L] = ŷ← la activación de la última capa es la predicción
Escribir la fórmula general del forward para cualquier capa l.
Entender por qué el bucle for l = 1..L sobre las capas es inevitable y correcto.
Seguir un ejemplo numérico completo a través de 3 capas.
2.1 Una sola regla para todas las capas
La gran ventaja de la notación general: la propagación hacia adelante de cualquier capa, sea la 1 o la 100, obedece exactamente al mismo par de ecuaciones. La capa l toma las activaciones de la capa anterior y produce las suyas:
# Regla general de la capa l (un ejemplo)z[l] = W[l]·a[l-1] + b[l]a[l] = g[l](z[l])
Y la versión vectorizada sobre los m ejemplos del dataset es idéntica con mayúsculas (cada columna de las matrices es un ejemplo):
# Regla general de la capa l (m ejemplos)Z[l] = W[l]·A[l-1] + b[l]A[l] = g[l](Z[l])# Casos frontera que cierran el sistema
A[0] = X ← el dataset completo entra por la "capa 0"
A[L] = Ŷ ← las m predicciones salen de la última capa
2.2 El bucle sobre capas: este sí es necesario
La vectorización elimina el bucle sobre ejemplos, pero el bucle sobre capas no se puede eliminar: la capa l necesita el resultado de la capa l−1, así que el cálculo es inherentemente secuencial. La implementación correcta es:
A = X # A[0] = Xfor l inrange(1, L+1): # este for está BIEN: es sobre capas
Z = W[l] @ A + b[l]
A = g[l](Z)
Y_hat = A # A[L]
Regla práctica
Un bucle for sobre los m ejemplos es un error de rendimiento (para eso está la vectorización). Un bucle for sobre las L capas es correcto y no hay forma razonable de evitarlo: L suele ser un número pequeño (4, 50, 150…) frente a m (miles o millones), así que su coste es despreciable.
Ejemplo numérico completo — red profunda 2→3→2→1 (L=3)
Red con 2 entradas, dos capas ocultas ReLU (3 y 2 neuronas) y salida sigmoide. Datos:
La red predice un 64.1% para la clase positiva. Observa dos cosas: (1) el mismo patrón z → a se repitió tres veces sin cambiar nada más que los tamaños; (2) la ReLU de la capa 2 "apagó" la neurona 1 (z negativo → activación 0), y esa neurona no contribuye nada a la salida — es la no-linealidad seleccionando qué información pasa.
Deducir la dimensión de cualquier matriz de la red a partir de los n[l].
Aplicar el método del papel y lápiz para cazar bugs antes de ejecutar código.
Distinguir qué cambia (y qué no) entre la versión de 1 ejemplo y la vectorizada.
3.1 El sistema completo de dimensiones
Comprobar dimensiones con papel y lápiz es la herramienta de depuración más rentable al implementar una red: la mayoría de los bugs de implementación son matrices que no encajan. Todo el sistema se deduce de una sola pregunta por matriz — "¿cuántas filas produce y cuántas recibe?":
Matriz
Dimensión (1 ejemplo)
Dimensión (m ejemplos)
Razonamiento
W[l]
(n[l], n[l-1])
(n[l], n[l-1]) — no cambia
Produce n[l] valores a partir de n[l-1]
b[l]
(n[l], 1)
(n[l], 1) — se replica por broadcasting
Un sesgo por neurona
z[l], a[l]
(n[l], 1)
Z[l], A[l]: (n[l], m)
Una columna por ejemplo
dW[l]
(n[l], n[l-1]) — igual que W[l]
Se resta de W[l] en el update
db[l]
(n[l], 1) — igual que b[l]
Se resta de b[l] en el update
dZ[l], dA[l]
(n[l], m) — igual que Z[l], A[l]
Un gradiente por activación
Las dos reglas de oro1) Los parámetros (W, b) tienen la misma forma con 1 o con m ejemplos: son propiedades de la red, no de los datos. 2) Todo gradiente d(cosa) tiene exactamente la misma forma que la cosa — imprescindible para poder hacer W := W − α·dW.
Ejemplo trabajado — todas las dimensiones de una red de 5 capas
Red con n = [2, 3, 5, 4, 2, 1], es decir: 2 entradas, capas ocultas de 3, 5, 4 y 2 neuronas, y 1 salida (L = 5). Deduce cada W y b aplicando "(cuántas produzco, cuántas recibo)":
Verificación de una capa cualquiera, por ejemplo la 3, con m = 1000 ejemplos:
Z[3] = W[3] · A[2] + b[3]
(4,5) · (5,1000) + (4,1)
= (4,1000) + (4,1) ← broadcasting replica b en las 1000 columnas
= (4, 1000) ✔
Total de parámetros: (3·2+3) + (5·3+5) + (4·5+4) + (2·4+2) + (1·2+1) = 9 + 20 + 24 + 10 + 3 = 66 parámetros. Contar parámetros así es útil para estimar la capacidad del modelo y su riesgo de sobreajuste con pocos datos.
¿Por qué funcionan las representaciones profundas?
Objetivos
Explicar la intuición de la jerarquía de características: de simple a complejo.
Enunciar el argumento de la teoría de circuitos: profundidad vs anchura exponencial.
Adoptar la actitud práctica correcta: la profundidad es un hiperparámetro, no una religión.
4.1 Intuición 1: jerarquía de simple a complejo
Cuando se visualiza qué detecta cada capa de una red profunda entrenada, aparece un patrón consistente: las primeras capas detectan cosas simples y locales, y cada capa siguiente compone lo anterior en conceptos más abstractos. Dos ejemplos clásicos:
Reconocimiento facial
Capa 1: bordes y orientaciones (líneas a 45°, verticales…). Capa 2: combina bordes en partes — ojos, narices, orejas. Capa 3: combina partes en caras completas. La red construye el concepto "cara" paso a paso.
Reconocimiento de voz
Capa 1: formas de onda de bajo nivel (tonos que suben/bajan, ruido). Capas intermedias: fonemas (los sonidos "C", "A", "T"). Capas superiores: palabras, y después frases completas.
La clave del porqué: cada capa solo tiene que aprender una transformación modesta (bordes → partes es un salto pequeño). El problema global difícil ("¿hay una cara?") se descompone en una cadena de problemas fáciles. Una red superficial tendría que aprender el salto píxeles → cara de golpe, que es mucho más difícil.
Cada capa compone las detecciones de la anterior. El mismo patrón aparece en visión, audio y texto.
4.2 Intuición 2: teoría de circuitos
Hay también un resultado formal (informalmente enunciado): existen funciones que una red profunda calcula con pocas unidades, pero que una red superficial necesita exponencialmente más unidades para calcular. El ejemplo canónico es la paridad (XOR encadenado) de n variables:
y = x₁ XOR x₂ XOR x₃ XOR … XOR xₙ
Con profundidad: se construye un árbol de XORs de 2 en 2. Profundidad O(log n), y en total solo se necesitan del orden de n unidades. Para n = 64 entradas: ~63 puertas XOR en ~6 niveles.
Con una sola capa oculta: para calcular la paridad de golpe, la capa necesita enumerar esencialmente todas las combinaciones de entradas: del orden de 2ⁿ⁻¹ unidades. Para n = 64: ≈ 9.2·10¹⁸ neuronas. Físicamente imposible.
Lo que significa en la práctica
La profundidad permite reutilizar cómputo intermedio: el resultado de un XOR parcial se comparte con todo lo que viene después, igual que "detector de ojo" se reutiliza para todas las caras. Una red superficial no puede compartir, así que tiene que duplicar el trabajo exponencialmente.
La actitud práctica correcta
Nada de esto significa que "más profundo siempre es mejor". El consejo práctico: al atacar un problema nuevo, empieza con regresión logística, prueba con 1 o 2 capas ocultas, y trata el número de capas como un hiperparámetro que se ajusta con el conjunto de validación. Las redes muy profundas brillan en problemas concretos (visión, voz), no en todos.
Bloques de construcción: forward, backward y caché
Objetivos
Ver cada capa como un par de funciones: un bloque forward y un bloque backward.
Entender qué es el caché y por qué guardar z[l] ahorra recomputación.
Visualizar el flujo completo de una iteración de entrenamiento.
5.1 Cada capa = dos funciones emparejadas
Al organizar la implementación de una red profunda conviene pensar cada capa l como dos funciones simétricas que comparten los parámetros W[l], b[l]:
Bloque FORWARD de la capa l
Entrada: a[l-1]. Salida: a[l]. Además: guarda z[l] (y por conveniencia W[l], b[l], a[l-1]) en un caché para el viaje de vuelta.
Bloque BACKWARD de la capa l
Entrada: da[l] (el gradiente que llega de la capa siguiente) + el caché. Salidas: da[l-1] (para seguir hacia atrás) y los gradientes dW[l], db[l] (para el update).
La fila de arriba calcula la predicción; la de abajo devuelve el error transformado en gradientes. Las flechas ámbar son los cachés: información del viaje de ida que el viaje de vuelta reutiliza.
5.2 ¿Por qué el caché?
El bloque backward de la capa l necesita z[l] (para evaluar g′(z[l])) y a[l-1] (para calcular dW[l]). Ambos ya se calcularon durante el forward. Hay dos opciones:
Sin caché: recalcular z[l] y a[l-1] durante el backward → duplicas casi todo el cómputo del forward.
Con caché: el forward guarda esos valores al pasar, y el backward los lee gratis → solo cuesta memoria, que suele ser el intercambio correcto.
Convención de implementación
En la práctica cada bloque forward devuelve dos cosas: la activación a[l] (que fluye a la capa siguiente) y una tupla cache = (a[l-1], W[l], b[l], z[l]) que se apila en una lista. El backward recorre esa lista en orden inverso. Todos los frameworks (TensorFlow, PyTorch) hacen exactamente esto por dentro con sus grafos de computación.
Escribir las fórmulas generales del backward para cualquier capa l.
Ver cómo se inicia el backward en la capa de salida.
Reunir todo en una implementación completa en NumPy.
6.1 Forward — recordatorio en una línea
# Para l = 1, 2, …, L (con A[0] = X)Z[l] = W[l]·A[l-1] + b[l]A[l] = g[l](Z[l])
6.2 Backward — la regla general de la capa l
El bloque backward de la capa l recibe dA[l] y produce tres salidas. Las cuatro fórmulas, vectorizadas sobre m ejemplos:
# Entrada del bloque: dA[l] (y el caché con Z[l], A[l-1], W[l])dZ[l] = dA[l] * g[l]′(Z[l])← * elemento a elementodW[l] = (1/m) · dZ[l] · A[l-1]ᵀ← forma (n[l], n[l-1]) ✔db[l] = (1/m) · np.sum(dZ[l], axis=1, keepdims=True)← forma (n[l], 1) ✔dA[l-1] = W[l]ᵀ · dZ[l]← lo que se pasa a la capa anterior
El sentido de cada línea:
dZ[l] = dA[l] * g′(Z[l]): el gradiente atraviesa la activación multiplicándose por su pendiente local. Si la neurona estaba en zona plana (g′ ≈ 0), el gradiente se atenúa — repetido capa tras capa, este producto es el origen del vanishing gradient en redes muy profundas.
dW[l] = (1/m)·dZ[l]·A[l-1]ᵀ: "error de la neurona × entrada que la alimentó", promediado sobre los m ejemplos. La entrada de la capa l es A[l-1].
dA[l-1] = W[l]ᵀ·dZ[l]: el error viaja hacia atrás por las mismas conexiones del forward, recorridas al revés (por eso la traspuesta). Es la salida que alimenta al bloque backward de la capa anterior.
6.3 Cómo arranca el backward: la capa de salida
El primer dA viene de derivar la pérdida respecto a la predicción. Para clasificación binaria con entropía cruzada:
# Derivada de la pérdida respecto a A[L]
dA[L] = −Y/A[L] + (1−Y)/(1−A[L])
# Pero al pasar por la sigmoide de la capa L, todo se simplifica:dZ[L] = A[L] − Y← "predicción menos verdad": el arranque práctico
Atajo estándar
En la práctica casi nadie calcula dA[L] explícitamente: se arranca el backward directamente con dZ[L] = A[L] − Y, porque la combinación sigmoide + entropía cruzada cancela los términos intermedios. Es la misma simplificación en cualquier profundidad.
Ejemplo numérico — un paso de backward en la red 2→3→2→1
Continuamos el ejemplo del Módulo 2: la red predijo a[3] = 0.641, con a[2] = [0, 0.90]ᵀ y W[3] = [0.8, 1.2]. Supón que la etiqueta era y = 1 (m = 1):
Tres observaciones: (1) dW[3] tiene un cero en la posición del peso conectado a la neurona apagada — una entrada que valía 0 no recibe corrección; (2) la neurona apagada por ReLU también bloquea el gradiente hacia atrás (dZ = 0): ni aprende ni deja pasar señal en esta iteración; (3) el signo negativo global empujará la predicción hacia arriba en el update, acercándola a y = 1.
6.4 Implementación completa en NumPy
# Red profunda genérica — parámetros en diccionarios W[l], b[l]# activaciones: ReLU en capas 1..L-1, sigmoide en la capa L# --- Forward (guardando cachés) ---
A = X
caches = []
for l inrange(1, L+1):
A_prev = A
Z = W[l] @ A_prev + b[l]
A = sigmoid(Z) if l == L elserelu(Z)
caches.append((A_prev, Z))
# --- Coste ---
J = -(1/m) * np.sum(Y*np.log(A) + (1-Y)*np.log(1-A))
# --- Backward (recorriendo cachés al revés) ---
grads = {}
dZ = A - Y # arranque: capa Lfor l inrange(L, 0, -1):
A_prev, Z = caches[l-1]
grads["dW"+str(l)] = (1/m) * dZ @ A_prev.T
grads["db"+str(l)] = (1/m) * np.sum(dZ, axis=1, keepdims=True)
if l > 1:
dA_prev = W[l].T @ dZ
_, Z_prev = caches[l-2]
dZ = dA_prev * (Z_prev > 0) # derivada de ReLU# --- Update ---for l inrange(1, L+1):
W[l] = W[l] - alpha * grads["dW"+str(l)]
b[l] = b[l] - alpha * grads["db"+str(l)]
Distinguir con precisión parámetro (lo aprende la red) de hiperparámetro (lo eliges tú).
Conocer los hiperparámetros principales de una red profunda.
Interiorizar que el deep learning aplicado es un proceso empírico e iterativo.
7.1 La distinción
Parámetros
Hiperparámetros
Qué son
W[1], b[1], …, W[L], b[L]
α (tasa de aprendizaje), nº de iteraciones, L (nº de capas), n[l] (unidades por capa), elección de activación por capa…
Quién los fija
El descenso de gradiente, automáticamente
Tú, antes de entrenar
Por qué "hiper"
—
Porque controlan el valor final de los parámetros: cambiar α o L cambia los W y b que la red acaba aprendiendo
Cómo se eligen
Minimizando el coste J
Probando valores y midiendo en el conjunto de validación
7.2 El ciclo empírico: Idea → Código → Experimento
No existe una fórmula que te diga de antemano el mejor α o el mejor número de capas para tu problema: el desarrollo en deep learning es un ciclo empírico. Un ejemplo típico con la tasa de aprendizaje:
1
Idea
"Probemos α = 0.01."
2
Código + experimento
Entrenas y trazas la curva del coste J contra las iteraciones.
3
Diagnóstico
Si J diverge o oscila → α demasiado grande. Si J baja pero lentísimo → α demasiado pequeño. Ajustas (p. ej. α = 0.05) y repites.
La curva de J es tu instrumento principal: debe bajar de forma monótona. Y una lección importante de la práctica: las intuiciones no siempre se transfieren entre dominios — el mejor conjunto de hiperparámetros para visión puede ser malo para NLP o para datos tabulares, e incluso para el mismo problema puede quedar obsoleto cuando cambian los datos o el hardware. Por eso conviene re-evaluar hiperparámetros periódicamente.
Hiperparámetros por orden de impacto típico
Cuando tengas que priorizar qué ajustar primero: 1) la tasa de aprendizaje α (el más importante con diferencia), 2) número de unidades por capa n[l], 3) número de capas L y el número de iteraciones. La elección de activación (ReLU por defecto) rara vez es lo primero que hay que tocar.
Situar la analogía cerebro ↔ red neuronal en su justa medida.
Saber por qué la analogía fue útil históricamente y por qué hoy se usa cada vez menos.
La respuesta honesta: no mucho. La analogía tiene un origen real pero muy laxo:
Una neurona biológica recibe señales eléctricas por sus dendritas, las integra, y si superan un umbral dispara un impulso por su axón. Una "neurona" artificial recibe números, los combina linealmente y aplica una activación. A ese nivel de caricatura, se parecen.
Pero ahí acaba la similitud: hoy nadie sabe con precisión cómo aprende una neurona biológica, y no hay evidencia de que el cerebro haga nada parecido a la retropropagación con descenso de gradiente. Una sola neurona real es enormemente más compleja que la caricatura logística.
La analogía fue útil para comunicar la idea y capturó la imaginación del público en los inicios del campo. En la práctica moderna, es más preciso pensar una red profunda como lo que es: una familia de funciones muy expresivas, con parámetros que se ajustan por descenso de gradiente para aproximar un mapeo X → Y a partir de datos.
Para no sobrevender
Cuando expliques deep learning a alguien, evita "funciona como el cerebro": genera expectativas equivocadas. Lo defendible es "está vagamente inspirado en el cerebro". El mérito real de estas redes no es su parecido biológico, sino que son aproximadores de funciones eficaces cuando hay muchos datos y cómputo.
L cuenta capas ocultas + salida (la entrada no); n[l] = unidades de la capa l; a[0] = x y a[L] = ŷ.
Regla única del forward para toda capa: Z[l] = W[l]·A[l-1] + b[l], A[l] = g[l](Z[l]).
El bucle forsobre las L capas es correcto e inevitable (cálculo secuencial); el que hay que eliminar es el bucle sobre los m ejemplos.
Dimensiones: W[l] es (n[l], n[l-1]); b[l] es (n[l], 1); Z[l], A[l] vectorizados son (n[l], m). W y b no cambian de forma al vectorizar.
Todo gradiente tiene la misma forma que su variable: dW como W, db como b, dZ como Z.
Por qué profundas (1): jerarquía de características — bordes → partes → caras; ondas → fonemas → palabras. Cada capa aprende un salto pequeño.
Por qué profundas (2): teoría de circuitos — la paridad de n bits necesita O(n) unidades con profundidad O(log n), pero ~2ⁿ⁻¹ unidades con una sola capa oculta.
Bloques: el forward de la capa l guarda un caché (Z[l], A[l-1], W[l], b[l]) que el backward reutiliza para no recomputar.
Parámetros (W, b) los aprende el descenso de gradiente; hiperparámetros (α, L, n[l], iteraciones, activaciones) los eliges tú y controlan a los parámetros — de ahí el "hiper".
El desarrollo es empírico: ciclo Idea → Código → Experimento guiado por la curva de J, que debe decrecer de forma monótona.
La analogía con el cerebro es solo inspiración laxa: no hay evidencia de retropropagación biológica.
Autoevaluación
Comprueba lo que aprendiste
Quiz — Redes Neuronales Profundas
10 preguntas · elige una opción por pregunta. La explicación aparece tras responder.
Q1.Una red con 3 capas ocultas y 1 capa de salida tiene L igual a:
L cuenta las capas con parámetros propios (W, b): las ocultas y la de salida. La entrada es la "capa 0" y no se cuenta.
Q2.La fórmula general del forward para la capa l es:
Cada capa consume las activaciones de la capa ANTERIOR (A[l-1]) y produce las suyas (A[l]).
Q3.En la implementación de una red profunda, ¿qué bucle for es aceptable?
El cálculo entre capas es secuencial (la capa l necesita a la l−1), así que ese bucle es inevitable y barato (L es pequeño). El bucle a eliminar es el de ejemplos.
Q4.Para una red con n = [2, 3, 5, 1], ¿qué forma tiene W[2]?
W[l] es (n[l], n[l-1]): la capa 2 produce 5 valores a partir de los 3 de la capa 1 → (5, 3).
Q5.Al vectorizar sobre m ejemplos, ¿qué matrices cambian de forma respecto a la versión de 1 ejemplo?
Los parámetros son propiedades de la red, no de los datos: W[l] sigue siendo (n[l], n[l-1]) y b[l] (n[l], 1), replicado por broadcasting.
Q6.¿Qué guarda el caché durante el forward y para qué?
El backward necesita Z[l] para evaluar g′(Z[l]) y A[l-1] para calcular dW[l]. Guardarlos en el forward cambia recomputación por memoria.
Q7.El argumento de teoría de circuitos dice que la paridad (XOR) de n variables:
La profundidad permite reutilizar cómputo intermedio (árbol de XORs); una red superficial debe enumerar exponencialmente las combinaciones.
Q8.En el backward, la fórmula que propaga el gradiente a la capa anterior es:
El error viaja hacia atrás por las mismas conexiones del forward, recorridas al revés — de ahí la traspuesta. dZ·A[l-1]ᵀ es dW[l], no dA[l-1].
Q9.¿Cuál de estos es un HIPERparámetro?
W y b son parámetros (los aprende el descenso de gradiente). L, α, n[l], las iteraciones y la elección de activación son hiperparámetros: los eliges tú y controlan el valor final de los parámetros.
Q10.¿Cuál es la relación real entre las redes neuronales y el cerebro?
La analogía tiene origen real (integración de señales y umbral) pero es muy superficial: una neurona biológica es mucho más compleja y su mecanismo de aprendizaje sigue sin conocerse.