Capas y activaciones
¿Cómo ganan poder las redes al apilar capas?
Lección completa
Si quieres:
Una capa oculta bastó para resolver XOR. Hoy apilamos más capas y vemos cuánto poder se gana, y por qué apilar, a secas, no basta.
Sin voz: la lección avanza sola con subtítulos.
La voz de esta lección está en preparación: por ahora avanza sola con subtítulos.
Modo revisiónComentar este pasoTerminé la lección
Qué lograrás
- Explicar por qué apilar capas lineales equivale a una sola capa, y qué cambia cuando se añade una activación no lineal.
- Calcular a mano el pase hacia delante de una red diminuta, con y sin ReLU.
- Reconocer qué dice —y qué no dice— el teorema de aproximación universal, y por qué en la práctica se apilan capas.
Ideas clave
- Una capa es un grupo de neuronas que miran las mismas entradas; el pase hacia delante calcula capa por capa, de la entrada a la salida.
- Sin activación, dos capas equivalen a una: el producto de dos transformaciones lineales es otra transformación lineal. Apilar no suma.
- La no linealidad (ReLU, tanh, sigmoide) dobla el espacio: lo que una recta no separaba, tras el doblez sí se separa.
- Con suficientes neuronas, una sola capa oculta puede aproximar cualquier función continua sobre un conjunto cerrado y acotado (aproximación universal), pero el teorema no dice cuántas neuronas hacen falta ni que el entrenamiento las encuentre.
- Apilar capas multiplica los pliegues: para ciertas funciones, una red profunda necesita muchas menos neuronas que una capa única.
Lo que mucha gente cree
Creencia común Cuantas más capas tiene una red, más poderosa es, siempre.
Lo correcto Sin una activación no lineal entre ellas, cualquier número de capas equivale a una sola. Con ella, más capas permiten más formas, pero también cuestan más de entrenar y de usar, y no garantizan un mejor resultado.
Compruébalo
Cuatro preguntas. Sin nota ni cuenta: sirven para ver si la idea quedó.
Por dentroPara quien quiere las fórmulas y el código. No hace falta para seguir el curso.
Una capa, en una fórmula
Una capa con neuronas y entradas guarda una matriz de pesos (una fila por neurona) y un vector de sesgos . Dada la entrada , calcula
donde es la activación, aplicada a cada componente. Un pase hacia delante encadena esta fórmula capa por capa. Una red densa con tamaños tiene parámetros: por ejemplo, la red 2-8-8-8-1 del patio de juegos tiene .
El colapso lineal
Si es la identidad, dos capas dan
que es una sola capa con pesos y sesgo . Con los números de la lección:
Por inducción, capas lineales equivalen a una. Con y la entrada , la capa oculta da , la ReLU lo convierte en y la salida es , no : la equivalencia se rompe.
Las activaciones
Sus derivadas importan para entrenar (lección 8): , y (en no existe; por convención se toma 0). La ReLU, «unidad lineal rectificada», tiene variantes suaves, como la GELU (Hendrycks y Gimpel, 2016), que BERT usa en lugar de la ReLU (Devlin et al., 2019).
Aproximación universal
Qué dice (Cybenko, 1989, teorema 2). Una función es sigmoidal si cuando y cuando . Si es continua y sigmoidal, para toda función continua sobre el cubo unitario (con un cambio de escala, sobre cualquier cubo) y todo existen , , y tales que
Quiénes más, y con qué condiciones. El mismo año, Hornik, Stinchcombe y White lo probaron para «funciones de aplastamiento» (no decrecientes, con límites 0 y 1, no necesariamente continuas), y para funciones medibles en un sentido más débil (aproximación en probabilidad); en una nota final reconocen el trabajo de Funahashi (1989), que llegó por su cuenta a un resultado cercano. Las hipótesis no coinciden: Cybenko no exige que sea monótona, y Hornik et al. no exigen que sea continua. Hornik (1991) mostró que basta con una activación acotada y no constante (aproximación en ; si además es continua, aproximación uniforme sobre compactos). Leshno, Lin, Pinkus y Schocken (1993) cerraron la cuestión: para una activación localmente acotada y continua a trozos, una red con una capa oculta aproxima toda función continua, uniformemente sobre cada compacto, si y solo si la activación no es un polinomio. La ReLU cumple esa condición. El teorema también necesita el sesgo (el umbral): sin él, no vale.
Qué no dice. Aproxima una función conocida sobre un conjunto acotado; no dice nada fuera de él ni sobre aprender de ejemplos. No acota ni dice cómo hallar los pesos. Cybenko lo reconoce en su discusión final: su artículo se limita a la existencia, y sospecha que la gran mayoría de los problemas de aproximación exigirán un número astronómico de términos, por la maldición de la dimensionalidad. Hornik et al. añaden que un fallo en la práctica puede deberse a un aprendizaje inadecuado, a pocas neuronas o a que la relación entre entrada y salida sea aleatoria.
La construcción de la lección. No es la demostración de Cybenko, que usa el teorema de Hahn–Banach y no construye nada. Para una función de una variable, con nudos equiespaciados y pendientes , ,
es una red con una capa oculta de neuronas ReLU que coincide con en los nudos (interpolación lineal por tramos). Si , el error máximo es a lo sumo : al duplicar las neuronas, la cota se divide por cuatro. Para la curva de la escena, ; con la cota es 0.026 y el error medido, 0.025. La razón de errores medidos no es siempre cuatro: 2.5 al pasar de 3 a 6 neuronas, 3.0 de 6 a 12, 4.1 de 12 a 24 y 3.8 de 24 a 48. Tampoco baja en cada paso (de 1 a 2, de 4 a 5 y de 7 a 8 neuronas sube un poco, porque los nudos equiespaciados caen en otros lugares). La meta del turno, 0.05, se alcanza con 17 neuronas (0.047; con 16, 0.057). Aquí los pesos se calculan, no se entrenan.
Profundidad: la sierra
La función tienda sobre usa dos neuronas: sube de 0 a 1 en y baja de 1 a 0 en . La composición ( capas, neuronas) tiene tramos rectos (comprobado numéricamente hasta ). Una red de una sola capa oculta con neuronas ReLU tiene a lo sumo tramos en una dimensión (cada neurona aporta una esquina), así que para igualarla necesita al menos neuronas. Telgarsky (2016) usa esta misma función y prueba algo más fuerte, para aproximar y no solo igualar: para cada existe una red ReLU con capas y neuronas tal que toda red ReLU con a lo sumo capas y a lo sumo neuronas queda a distancia de al menos sobre . Es un resultado sobre funciones concretas, no una ley: no dice que toda tarea real se beneficie igual de la profundidad.
En código: el pase hacia delante y el colapso
import numpy as np
W1 = np.array([[1, 2],
[3, -1]]) # capa oculta: una fila por neurona
W2 = np.array([[2, 1]]) # salida
def red(x, activacion):
h = activacion(W1 @ x) # pase hacia delante: capa oculta...
return (W2 @ h)[0] # ...y salida
lineal = lambda z: z
relu = lambda z: np.maximum(0, z)
print("W2 @ W1 =", W2 @ W1) # la neurona única equivalente
for x in ([2, 1], [1, 0], [0, 1]):
x = np.array(x)
print(x, "sin activación:", red(x, lineal), "| una neurona:", (W2 @ W1 @ x)[0], "| con ReLU:", red(x, relu))
Salida esperada:
W2 @ W1 = [[5 3]]
[2 1] sin activación: 13 | una neurona: 13 | con ReLU: 13
[1 0] sin activación: 5 | una neurona: 5 | con ReLU: 5
[0 1] sin activación: 3 | una neurona: 3 | con ReLU: 4
En código: una red que aprende los círculos
Es la misma idea del patio de juegos (red 2-6-1, ReLU y sigmoide de salida), con descenso del gradiente simple. Las líneas con dZ son la retropropagación, que se explica en la lección 8.
import numpy as np
rng = np.random.default_rng(0)
# Datos: un grupo central (clase 0) rodeado por un anillo (clase 1)
n = 90
a0, r0 = rng.uniform(0, 2 * np.pi, n), np.sqrt(rng.uniform(0, 1, n)) * 1.15
a1, r1 = rng.uniform(0, 2 * np.pi, n), rng.uniform(1.95, 2.8, n)
X = np.vstack([np.c_[r0 * np.cos(a0), r0 * np.sin(a0)], np.c_[r1 * np.cos(a1), r1 * np.sin(a1)]])
X = (X + 0.12 * rng.normal(size=X.shape)) / 3 # coordenadas en [-1, 1]
y = np.r_[np.zeros(n), np.ones(n)]
# Red 2 → 6 (ReLU) → 1 (sigmoide)
W1 = rng.normal(0, np.sqrt(2 / 2), (2, 6)); b1 = rng.uniform(-0.5, 0.5, 6)
W2 = rng.normal(0, np.sqrt(1 / 6), (6, 1)); b2 = np.zeros(1)
sig = lambda z: 1 / (1 + np.exp(-z))
for paso in range(1500):
Z1 = X @ W1 + b1; H = np.maximum(0, Z1); p = sig(H @ W2 + b2).ravel() # pase hacia delante
dZ2 = (p - y)[:, None] / len(y) # error en la salida
dW2, db2 = H.T @ dZ2, dZ2.sum(0)
dZ1 = (dZ2 @ W2.T) * (Z1 > 0) # la culpa vuelve a la capa oculta
dW1, db1 = X.T @ dZ1, dZ1.sum(0)
for P, G in ((W1, dW1), (b1, db1), (W2, dW2), (b2, db2)):
P -= 0.5 * G # descenso del gradiente
print("aciertos:", ((p > 0.5) == y).mean())
Salida esperada: aciertos: 1.0. Con 6 neuronas dio 1.0 en las diez semillas probadas (0 a 9); con 3 neuronas, entre 0.81 y 1.0; con 2, entre 0.82 y 0.89 (los números aleatorios de NumPy pueden cambiar entre versiones). Son aciertos sobre los mismos puntos con los que se entrena: acertar con datos nuevos es otra pregunta (lección 10). El patio de juegos de la lección usa el optimizador Adam en lugar del descenso simple (lección 9).
Lo que viene
Calcular el gradiente de cada peso en una red así es la retropropagación (lección 8). Cómo entrenar bien —lotes, optimizadores— es la lección 9, y la 10 muestra que acertar en los puntos de entrenamiento, como aquí, no garantiza acertar con datos nuevos.
Lente de decisión
Qué significa esta idea si tu trabajo es decidir, no programar.
- «Más capas» no es una medida de calidad: cada capa suma costo de entrenamiento y de uso. Los aciertos del patio se miden sobre los mismos puntos con que se entrena; pide la comparación con un modelo sencillo sobre datos que ninguno vio, antes de aceptar que la profundidad se justifica.
- El teorema de aproximación universal garantiza que existe una red, no que sirva en tu caso: no dice cuántos datos, cuánto cómputo ni cuántas neuronas hacen falta. Si alguien lo invoca para vender una solución, pregunta por la evidencia en tu problema.
- Entrenar es sensible al punto de partida: la misma receta con otra semilla puede dar resultados distintos (pruébalo en el patio con «Reiniciar» y pocas neuronas). Pide que se repita el entrenamiento y se reporte la variabilidad, no solo la mejor corrida.
- Tamaño es costo: GPT-3 tiene noventa y seis capas y ciento setenta y cinco mil millones de parámetros. Cuando hablen de una «red profunda», pide el número de parámetros y el costo por tarea (lecciones 24 y 26).
Términos de la lección
- Capa Grupo de neuronas que reciben las mismas entradas y calculan a la vez. Una red es una cadena de capas: entrada, una o más ocultas, y salida.
- Pase hacia delante Cálculo de la salida de una red: los números avanzan capa por capa, de la entrada a la salida.
- ReLU Unidad lineal rectificada: función de activación que devuelve cero si la suma es negativa y la propia suma si es positiva, máx(0, z). Una bisagra con una sola esquina.
- No linealidad Propiedad de una función que no es una recta. Es lo que impide que apilar capas colapse en una sola y lo que permite doblar el espacio.
- Aproximación universal Teorema: una red con una capa oculta y suficientes neuronas puede aproximar cualquier función continua sobre un conjunto cerrado y acotado, con la precisión que se quiera. No dice cuántas neuronas hacen falta ni que el entrenamiento las encuentre.
- Red profunda Red con varias capas ocultas. Cada capa aprovecha lo que la anterior ya transformó; para ciertas funciones, así logra formas complejas con muchas menos neuronas que una sola capa ancha.
- Neurona artificial Unidad de cálculo que multiplica cada entrada por un peso, suma los resultados, añade un sesgo y aplica una función de activación: y = f(w·x + b).
- Función de activación Función que se aplica a la suma ponderada más el sesgo para producir la salida de la neurona. Ejemplos: el escalón y la sigmoide.
- Sigmoide Función σ(z) = 1/(1 + e⁻ᶻ): convierte cualquier número en un valor entre 0 y 1, y vale 0.5 cuando z = 0.
- Capa oculta Capa de neuronas entre la entrada y la salida. Crea señales intermedias que la salida combina; su valor no se observa directamente.
- Frontera de decisión Conjunto de puntos donde la neurona cambia de respuesta. Con dos entradas es una recta: w₁x₁ + w₂x₂ + b = 0.
- Peso (w) En un modelo lineal, el número que multiplica a la entrada: la pendiente de la recta. Indica cuánto sube la predicción por cada unidad que aumenta la entrada.
- Sesgo (b) El término que se suma al final del modelo: la predicción cuando la entrada vale cero, es decir, la altura a la que la recta corta el eje vertical. No es el sesgo de los datos o de un modelo injusto, que es otro concepto.
- Parámetro Cada uno de los números que un modelo ajusta al entrenarse y en los que guarda lo aprendido.
- Función de pérdida Un único número que resume qué tan equivocado está un modelo con sus datos. Entrenar es buscar los parámetros que lo hacen lo más pequeño posible.
Transcripción completa
Fuentes
- Cybenko, G. (1989). Approximation by superpositions of a sigmoidal function
- Hornik, K., Stinchcombe, M., White, H. (1989). Multilayer feedforward networks are universal approximators
- Funahashi, K. (1989). On the approximate realization of continuous mappings by neural networks
- Hornik, K. (1991). Approximation capabilities of multilayer feedforward networks
- Leshno, M., Lin, V. Y., Pinkus, A., Schocken, S. (1993). Multilayer feedforward networks with a nonpolynomial activation function can approximate any function
- Telgarsky, M. (2016). Benefits of depth in neural networks
- Brown, T. B., et al. (2020). Language Models are Few-Shot Learners (GPT-3: 96 capas, 175 mil millones de parámetros; tabla 2.1)
- Hendrycks, D., Gimpel, K. (2016). Gaussian Error Linear Units (GELUs)
- Devlin, J., Chang, M.-W., Lee, K., Toutanova, K. (2019). BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding (usa la GELU en lugar de la ReLU)
- Kingma, D. P., Ba, J. (2015). Adam: A Method for Stochastic Optimization
ComentariosConversación pública de esta lección: dudas, datos por revisar, ideas.
Los comentarios viven en GitHub Discussions, en el repositorio público del curso; para escribir se necesita una cuenta de GitHub. Se cargan desde giscus.app al abrir esta sección. Las personas que revisan el curso los leen, y si un cambio se acepta, se aplica en los dos idiomas. Abrir el hilo en GitHub