English · Español
Laboratorio 03 — Normas por experimento: verificando ||Ax|| ≤ ||A||·||x||¶
Objetivo: verificar empíricamente la desigualdad submultiplicativa y encontrar el caso de igualdad (vector singular superior).
Tiempo estimado: 30–45 minutos.
Prerrequisito: leído
theory/04-norms-and-conditioning.md.
Lo que produces¶
Un directorio experiments/03-norms-by-experiment/ que contiene:
norms.py— script (lo escribe Borja).results.json— mediciones.equality_case.png— visualización de cuándo||Ax|| / ||A||·||x||se aproxima a 1.manifest.json.README.md— 1-2 párrafos.
E implementaciones en src/minigrad/linalg.py: frobenius_norm, l1_norm, l2_norm, linf_norm, op_norm.
Parte A — Implementa las normas en src/minigrad/linalg.py¶
-
l1_norm(x),l2_norm(x),linf_norm(x)para vectores 1-D. NumPy puro. -
frobenius_norm(A)para matrices. -
op_norm(A)que devuelve la norma operador L2 =σ_max(A). Usanp.linalg.svd(A, full_matrices=False, compute_uv=False).
Restricciones para las implementaciones¶
- Estabilidad numérica. Para entradas muy grandes o muy pequeñas, el ingenuo
sqrt(sum(x**2))puede desbordar / subdesbordar. Usarnp.linalg.normpor debajo está bien — pero para una de ellas, implementa a mano la forma establemax(|x|) * sqrt(sum((x / max(|x|))**2))y comprueba que sobrevive a entradas con magnitud1e30. - Sin
scipy.linalg.norm. NumPy puro. - Anotaciones de tipo + docstrings. Cada docstring expone la fórmula de la norma y enlaza a
theory/04.
Tests en tests/test_linalg.py¶
Añade:
test_norms_match_numpy— verifica contranp.linalg.normpara entradas aleatorias.test_frobenius_equals_l2_of_singular_values— paraAaleatoria, verifica quefrobenius_norm(A)² ≈ sum(σ²).test_op_norm_is_sigma_max— paraAaleatoria, verifica queop_norm(A) == max(np.linalg.svd(A, compute_uv=False)).test_submultiplicative_inequality— paraA, xaleatorios, verifica quel2_norm(A @ x) ≤ op_norm(A) * l2_norm(x)conatol=1e-5.test_stable_l2_handles_huge_values—x = [1e30, 1e30], se esperasqrt(2) * 1e30, sin desbordamiento.
Parte B — El experimento¶
En norms.py:
- Genera
A = np.random.randn(M, N)conM=64, N=64. Calcula su SVD:U, S, V = np.linalg.svd(A, full_matrices=False). - Muestrea
1000vectores unitarios aleatoriosx_i ∈ R^N(gaussianos y luego normalizados). Calcular_i = ||A x_i||_2 / (||A||_2 · ||x_i||_2). - Dibuja un histograma de
r_i. Todos los valores deben ser ≤ 1. - Caso de igualdad: define
x_top = V.T[:, 0](vector singular derecho superior). Calcular_top = ||A x_top||_2 / (||A||_2 · ||x_top||_2). Debería ser≈ 1(dentro del ulp de fp32). - Dibuja el histograma con
r_topmarcado. Anótalo.
Bloque C — qué registrar¶
En results.json:
{
"matrix_shape": [64, 64],
"matrix_seed": 42,
"n_random_samples": 1000,
"sigma_max": ...,
"ratios": {
"min": ...,
"max": ...,
"mean": ...,
"ratio_at_top_singular_vector": ...
}
}
Bloque D — interpretar¶
En README.md, responde:
- ¿Cuál es el máximo de las razones? Debería ser muy cercano a 1 (el caso del vector singular superior).
- ¿Cuál es la media? Para un vector unitario aleatorio,
E[r] ≈ ||A||_F / (sqrt(N) · ||A||_2). Calcula esto y compara. - Verifica la ortogonalidad de la SVD: comprueba que
U.T @ U ≈ IyV @ V.T ≈ Icon tolerancia fp32. - ¿Qué pasa si reemplazas
||·||_2por||·||_F? ¿Se cumple||Ax||_F ≤ ||A||_F · ||x||_F? (Pista: sí, pero es una cota más débil.)
Bloque E — manifest¶
Manifest estándar. Documenta la semilla de la matriz para reproducibilidad.
Restricciones¶
- fp32 en todo. Coincide con el resto del currículo.
- Sin
torch.linalg.norm. NumPy puro. - Hilo único. Añade
OPENBLAS_NUM_THREADS=1al manifest.
Escollos¶
r_topligeramente > 1. Posible debido a quenp.linalg.svden fp32 devuelve unS[0]ligeramente demasiado pequeño. Si supera 1 por más de1e-5, tuop_normestá mal. Si es por menos, es ruido de fp32.- Vectores unitarios aleatorios:
np.random.randn(N) / np.linalg.norm(...)es la forma estándar. No uses un vector uniforme en[0, 1]— está sesgado hacia la esquina todo-positiva. - Histograma con muy pocas barras. Usa ~30 bins para 1000 muestras.
Condiciones de parada¶
- Todas las normas implementadas; todos los tests pasan.
- El histograma muestra razones en
[0, 1]con el caso de igualdad en≈ 1. - El README responde las cuatro preguntas de interpretación.
Cuándo consultar solutions/¶
Tras hacer commit del histograma + tests. solutions/03-norms-by-experiment-ref.md (en la apertura de la fase) discute la concentración de la medida (por qué la mayoría de las razones aleatorias se agrupan muy por debajo de 1 en alta dimensión) y enlaza hacia adelante con la intuición de optimización en pérdidas anisotrópicas de la Fase 4.
Fin del laboratorio de la Fase 3. Próxima fase: docs/phase-04-calculus-optimization/.