English · Español
Lab 02 — Visualiza y sondea las embeddings entrenadas¶
Lee
theory/03-similarity-and-visualization.md. No consultessolutions/.
Objetivo¶
Proyecta las embeddings entrenadas a 2D con UMAP; produce un scatter plot que muestre clustering por tiempo / verbo / idioma. Construye un heatmap de similitud coseno de las formas infinitivas de los 20 verbos. Sondea una "dirección de tiempo" lineal en el espacio de embedding. Estas visualizaciones son el diagnóstico — si no muestran estructura, el corpus o el entrenamiento tienen un bug.
Setup¶
- El
Embeddingguardado del Lab 01. - El tokenizer de la Fase 12 (para mapear ids ↔ cadenas de forma verbal).
- Librería:
umap-learn(añadida enpyproject.toml),matplotlib,numpy.
Tareas¶
Tarea 1 — proyección UMAP¶
import umap
emb = Embedding.load(path)
E_matrix = emb.E.value # (V, d) = (64, 32)
reducer = umap.UMAP(n_neighbors=15, min_dist=0.1, n_components=2, random_state=42)
E_2d = reducer.fit_transform(E_matrix) # (V, 2)
Guarda la proyección como experiments/<date>-phase-13-visualize/umap.npy para reutilizar.
Tarea 2 — scatter plot anotado¶
Construye un scatter plot donde:
- Cada punto es un token del vocabulario.
- Color codifica la identidad del verbo (un color por verbo, con un color "otros" para tokens no verbales).
- Forma del marcador codifica el tiempo (infinitivo = círculo, presente = triángulo, pasado = cuadrado, participio pasado = rombo, futuro = estrella). Tokens no verbales usan 'x'.
- Cada punto se etiqueta con la cadena del token (o un subconjunto pequeño para legibilidad).
Guarda como experiments/<date>-phase-13-visualize/umap_scatter.png (alta resolución, al menos 1200×900).
Patrón esperado:
- Las 5 formas de tiempo de cada verbo quedan próximas (un clúster pequeño por verbo).
- Las formas inglesa y española del mismo verbo quedan próximas (p. ej.,
workcerca detrabajar). - Un eje de tiempo es visible — todas las formas de pasado están desplazadas en una dirección respecto a sus infinitivos.
- Los tokens no verbales (puntuación, pronombres, artículos) forman su propio clúster, separado de los verbos.
Si no ves (1), el entrenamiento CBOW no capturó la identidad del verbo — probablemente demasiados pocos epochs o LR mal puesta. Si no ves (2), las plantillas del corpus no hicieron las formas EN/ES suficientemente intercambiables. Documenta ambos casos.
Tarea 3 — heatmap de similitud coseno¶
Calcula la matriz de similitud coseno pareada para las formas infinitivas de los 20 verbos solo (así comparamos identidad del verbo, no mezcla de tiempos).
infinitives = [tokenizer.encode(v)[0] for v in twenty_verbs]
E_inf = E_matrix[infinitives] # (20, 32)
norms = np.linalg.norm(E_inf, axis=1, keepdims=True)
E_norm = E_inf / norms
cos_sim = E_norm @ E_norm.T # (20, 20)
Plotea como heatmap con verbos como etiquetas de ambos ejes. Usa un colormap divergente centrado en 0. Guarda como experiments/<date>-phase-13-visualize/cosine_heatmap.png.
Esperado: la diagonal es 1,0 (autosimilitud). Los valores fuera de la diagonal son positivos (las embeddings están mayormente en el mismo hemisferio). Algunos pares de verbos deberían verse visiblemente más próximos que otros: p. ej., walk / work / play (todas acciones simples en plantillas similares) > walk / be (verbos muy distintos).
Tarea 4 — coseno vs Euclídea: top-10 vecinos de work¶
Calcula los 10 vecinos más cercanos de work (el infinitivo) bajo ambas métricas. Tabula:
| Rank | Cosine NN | Cosine sim | Euclidean NN | Euclidean dist |
|---|---|---|---|---|
| 1 | walk | 0.78 | . | 0.43 |
| 2 | talk | 0.74 | , | 0.51 |
| ... | ... | ... | ... | ... |
Guarda como experiments/<date>-phase-13-visualize/work_neighbors.csv.
Esperado: las dos columnas difieren significativamente. El coseno da verbos en contextos similares. La Euclídea queda dominada por tokens de alta frecuencia (puntuación, artículos) por la confusión norma-frecuencia.
Escribe 1-2 frases en tus notas de lab explicando la diferencia.
Tarea 5 — sonda lineal para la dirección de tiempo¶
Este es el test más riguroso. Procedimiento:
past_ids = [tokenizer.encode(f) for f in all_past_forms]
future_ids = [tokenizer.encode(f) for f in all_future_forms]
infinitive_ids = [tokenizer.encode(v) for v in twenty_verbs]
mu_past = E_matrix[past_ids].mean(axis=0)
mu_future = E_matrix[future_ids].mean(axis=0)
direction = mu_past - mu_future
direction = direction / np.linalg.norm(direction) # normalise
# Project each verb-form token onto the direction.
projections = E_matrix @ direction # (V,)
# Sort tokens by projection; check that past tokens cluster at one end,
# future at the other, and infinitives in the middle.
Plotea un scatter 1D de las proyecciones, coloreado por tiempo. Guarda como experiments/<date>-phase-13-visualize/tense_probe.png.
Pasa: las medias de los grupos pasado, infinitivo y futuro están visiblemente separadas, con pasado en un extremo, futuro en el otro, infinitivo entre medias.
Falla: los grupos se solapan completamente. Esto sugeriría que la embedding aprendió identidad por verbo pero no tiempo. Documéntalo y nota que el entrenamiento de la Fase 18 del mini-GPT completo probablemente lo arregle.
Tarea 6 — breve discusión en las notas de lab¶
En learners/borja/phase-13/notes.md, 2-3 párrafos:
- ¿Qué estructura encontraste? (Cita clusters o direcciones concretos.)
- ¿Qué te sorprendió? (P. ej., ¿
beclusterizó con los otros verbos o con la puntuación? ¿Por qué?) - ¿Qué cambiarías del corpus o el entrenamiento si lo ejecutaras de nuevo?
Esta nota pasa a formar parte de PHASE_13_REPORT.md.
Mediciones a capturar¶
- Proyección UMAP guardada.
- Scatter plot guardado.
- Heatmap coseno guardado.
- Tabla de vecinos coseno vs Euclídea guardada.
- Scatter 1D de la sonda de tiempo guardado.
- Notas de lab escritas.
Aceptación¶
- Las cinco visualizaciones guardadas.
- Al menos las cinco formas de tiempo de un verbo clusterizan visiblemente en el scatter UMAP.
- Las listas de vecinos coseno y Euclídea difieren significativamente.
- La proyección de tiempo separa las medias de pasado / infinitivo / futuro.
- Notas escritas.
Escollos esperables¶
- No determinismo de UMAP. Distintos
random_statedan distintos layouts. Fijarandom_state=42para reproducibilidad. No esperes que el layout coincida visualmente con el de las soluciones del Lab — solo la estructura de clustering debería coincidir. - Fallos de UMAP con pocos puntos. Con solo 64 tokens, UMAP puede producir layouts extraños (sobreclusterizados o sobreesparcidos). Prueba
n_neighbors=10si 15 se ve mal;n_neighbors=5si sigue mal. Documenta cualquier ajuste. - Similitud coseno sobre vectores de norma cero. Si un token nunca aparece en el entrenamiento (algunos tokens especiales), su embedding queda en escala de init y puede tener norma anormalmente pequeña. La similitud coseno sigue estando definida; comprueba
NaN. - Sondeo como sesgo de confirmación. La sonda de "dirección de tiempo" solo funciona si predefiniste la dirección antes de mirar la proyección. No elijas la dirección a ojo desde el UMAP y luego afirmes que es evidencia. El procedimiento de la Tarea 5 calcula la dirección a partir de etiquetas de entrenamiento (pertenencia al tiempo), no por inspección — eso es lo que lo hace riguroso.
Siguiente: Fase 14 — Modelos de Secuencia Pre-Transformer (tras /quiz 13 y /phase-report 13).