English · Español
Break 00 — Sustituye GELU por la identidad en TenseMLP¶
🇪🇸 Rompemos
GELUpara que sea la función identidad. Tu MLP de 2 capas debería colapsar a una sola transformación lineal — predice qué métrica te lo dirá antes de mirar la pérdida.Anchors:
LYNX_CORTEX.md§4 / PHASE 9;.claude/commands/break.md.
La rotura¶
En src/minimodel/nn/activations.py:
Edición de una sola línea. La clase sigue existiendo, sigue teniendo el nombre correcto, sigue componiendo dentro de Sequential. El forward pass se convierte en:
H1 = X @ W1.T + b1 # (4, 16) — same as before
H1 = H1 # identity, no nonlinearity
logits = H1 @ W2.T + b2 # (4, 5)
Predice y luego ejecuta¶
Dos capas de Linear sin no-linealidad entre ellas es, por composición de mapeos afines, equivalente a una sola capa lineal:
donde \(W_{\text{eff}} = W_2 W_1\) tiene rango como mucho min(23, 16, 5) = 5. La tarea de clasificación de tiempos verbales de §A13 sí tiene un ground-truth exactamente lineal (one-hot verb ⊕ person → 5 tiempos), así que podrías pensar que no cambia nada. Pero:
- La familia de funciones expresables es idéntica — una sola capa lineal puede representar cualquier función de conjugación que el MLP roto pueda.
- La trayectoria de optimización difiere: el MLP roto sobreparametriza un objetivo de rango 5 con un compuesto de
(16, 23) + (5, 16) = 448parámetros, frente a los(5, 23) = 115parámetros de la única capa. El step por parámetro de Adam se diluye a través de direcciones redundantes.
Predicciones¶
- Accuracy final de validación: aproximadamente la misma (>85 %), quizá ligeramente más baja o más ruidosa.
- Pasos hasta convergencia: más (~1.5–2×) por la dilución del optimizador descrita arriba.
- Rango efectivo de
W2 @ W1: como mucho 5 (el cuello de botella). - El MLP entrenado con GELU debería alcanzar menor pérdida en un set adversarial held-out (puede ajustar la pequeña no-linealidad en el acuerdo persona/tiempo, como la
-sde la 3ª persona).
Escribe tus predicciones en learners/borja/phase-09/notes/breaks.md antes de ejecutar. El objetivo es fijar una hipótesis.
Observa¶
Ejecuta experiments/09-tense-mlp/train.py con la activación rota. Compara contra la ejecución anterior:
Diagnósticos para graficar:
- Solapamiento de curvas de pérdida —
geluvsidentity. np.linalg.matrix_rank(W2.data @ W1.data)al final del entrenamiento — debería ser ≤ 5.- Accuracy held-out sobre los 10 ejemplos más difíciles (p. ej., past-participle de 3ª persona de irregulares).
Síntoma que verá Borja¶
- La convergencia funciona pero es más lenta. La pérdida no explota; este es el caso sutil.
- Accuracy adversarial ligeramente peor.
matrix_rank(W2 @ W1) == 5.
Causa oculta (una frase)¶
GELU se sustituyó por la identidad, colapsando el MLP a un mapeo lineal efectivo de rango 5.
Cascada de pistas¶
- El forward pass muestra
(B, 16) → (B, 5)— pero ¿es la representación intermedia alguna vez no lineal? Imprime la distribución deH1. - ¿Cuál es
np.linalg.matrix_rank(W2.data @ W1.data)? ¿Está acotada por algo arquitectónico? - La clase
GELUennn/activations.pyha cambiado. Compara el métodoforwardcon la teoría de la Phase 9 §02.
Diff del arreglo¶
Por qué esto enseña el concepto¶
Los teoremas de aproximación universal (Cybenko 1989, Hornik et al. 1989) requieren una no-linealidad entre capas. Sin ella, la profundidad no añade expresividad. La tarea de §A13 resulta ser linealmente separable, así que el síntoma es optimización degradada, no representación degradada. Este es el tipo de bug que se envía a producción — el modelo "funciona", pero peor de lo que debería — y la única forma de cazarlo es entender por qué GELU está ahí. La FFN del transformer en la Phase 17 usa GELU por la misma razón; la derivación residual de la Phase 10 necesita curvatura no nula en f(x) para tener sentido.
Siguiente: el /break de la Phase 10 sobre la residual highway.