Lección 8 de 10 · La arquitectura completa · 16 min
Resultados y ablaciones
Qué es BLEU, calculado a mano; las tablas 2 y 3 del paper; y tres ablaciones repetidas en chico
Notebook del episodio
El código de esta lección, para correrlo y modificarlo en Google Colab, gratis y con tu cuenta. Para guardar tus cambios: Archivo → Guardar una copia en Drive.
Attention is all you need. Episodio ocho: resultados y ablaciones. Un paper no se cree por la arquitectura: se cree por los números. Hoy, qué mide el número que todos citan, calculado a mano en una frase. Después, las dos tablas del paper: la de traducción y la de ablaciones, que saca o cambia una pieza por vez. Y al final, tres de esas ablaciones repetidas en nuestra tarea de juguete.
Parte 1 · Qué es BLEU
BLEU, bilingual evaluation understudy: la métrica de todo el paper. No es un acierto: es cuántos pedazos de la traducción coinciden con una de referencia.
BLEU en cuatro ideas
- Compara la traducción con una de referencia, hecha por una persona
- Cuenta n-gramas: pedazos de 1, 2, 3 y 4 palabras seguidas
- Recorta: una palabra de la referencia se usa una sola vez
- Castiga las traducciones más cortas que la referencia
Understudy es el suplente de un actor: BLEU es un suplente automático del evaluador humano. Necesita una traducción de referencia, hecha por una persona. Cuenta n-gramas: un n-grama son n palabras seguidas. Para cada largo, de uno a cuatro, mira qué fracción de los n-gramas de la traducción aparece en la referencia. Con un recorte: si la referencia tiene una vez la palabra the, la traducción no puede cobrarla siete veces. Y una penalidad por brevedad: si no, la mejor estrategia sería traducir dos palabras seguras y nada más.
BLEU de una frase, a mano
la precisión de los -gramas, recortada
: largo de la traducción · : de la referencia
pesos iguales,
Una frase. Referencia: el gato negro duerme sobre la alfombra roja de la casa. Traducción: la misma, con en en vez de sobre. p sub n es la precisión de los n-gramas: cuántos de la traducción aparecen en la referencia, sobre cuántos hay. Count clip es la cuenta recortada. Diez de once palabras; ocho de diez pares; seis de nueve tríos; cuatro de ocho cuartetos. Una sola palabra distinta rompe todos los n-gramas que la tocan. La penalidad por brevedad, BP: c es el largo de la traducción y r el de la referencia. Si la traducción es más corta, e a la uno menos r sobre c. En el dibujo, con cuatro palabras de once, cero coma diecisiete. BLEU es BP por la exponencial del promedio de los logaritmos: la media geométrica de las cuatro precisiones. En el dibujo, los cuatro términos suman menos cero coma tres cinco cuatro: BLEU vale cero coma setecientos dos.
BLEU en veinte líneas
Los n-gramas de una frase, con su cuenta, en un Counter. El recorte: cada n-grama cobra como mucho las veces que aparece en la referencia. La penalidad por brevedad. Y la media geométrica, con logaritmos. Las cuatro precisiones del dibujo, penalidad uno porque los largos son iguales, y BLEU cero coma setecientos dos. Los papers lo multiplican por cien: setenta coma dos. Y otra diferencia: el BLEU de un paper no es el promedio por frase; junta los n-gramas de todo el conjunto de test y calcula una sola vez.
def ngramas(palabras, n):
return Counter(tuple(palabras[i:i + n]) for i in range(len(palabras) - n + 1))
def precision(cand, ref, n): # modified n-gram precision
c, r = ngramas(cand, n), ngramas(ref, n)
recortado = sum(min(k, r[g]) for g, k in c.items()) # Count_clip
return recortado, sum(c.values())
def bleu(cand, ref, N=4):
cand, ref = cand.split(), ref.split()
p = [a / b for a, b in (precision(cand, ref, n) for n in range(1, N + 1))]
bp = 1 if len(cand) > len(ref) else math.exp(1 - len(ref) / len(cand))
return bp * math.exp(sum(math.log(x) / N for x in p)), p, bp
ref = "el gato negro duerme sobre la alfombra roja de la casa"
cand = "el gato negro duerme en la alfombra roja de la casa"
b, p, bp = bleu(cand, ref)
print("p1..p4:", [f"{x:.3f}" for x in p], f"· BP {bp:.2f}")
print(f"BLEU = {b:.3f} → {100 * b:.1f} en la escala del paper")
p1..p4: ['0.909', '0.800', '0.667', '0.500'] · BP 1.00
BLEU = 0.702 → 70.2 en la escala del paper
Por qué una media geométrica
el exponencial de un promedio de logaritmos
si ningún cuarteto coincide, cero
¿Por qué logaritmos? El exponencial de un promedio de logaritmos es la raíz cuarta del producto: la media geométrica. A diferencia del promedio común, castiga fuerte a la precisión más baja. Y si alguna es cero, el logaritmo es menos infinito y BLEU da cero, aunque las otras tres sean buenas. Por eso BLEU por frase suelta es tan inestable, y se calcula sobre todo el conjunto.
El recorte y la penalidad, aislados
Las dos protecciones, por separado. El ejemplo dos del paper de BLEU: una traducción que repite the siete veces. La precisión común y la recortada. Sin recorte, siete de siete: perfecta. Recortada, dos de siete, porque the aparece dos veces en la referencia. Y la penalidad para dos traducciones cortas: con cuatro palabras de once, cero coma ciento setenta y cuatro; con siete, cero coma quinientos sesenta y cinco. Una traducción corta puede tener precisión perfecta y la penalidad igual la hunde.
ref = "the cat is on the mat".split() # ejemplo 2 del paper de BLEU
cand = "the the the the the the the".split()
c, r = ngramas(cand, 1), ngramas(ref, 1)
print("precisión común:", sum(k for g, k in c.items() if g in r), "/", len(cand))
print("modified (recortada):", sum(min(k, r[g]) for g, k in c.items()),
"/", len(cand))
ref = "el gato negro duerme sobre la alfombra roja de la casa".split()
for cand in ["el gato negro duerme", "el gato negro duerme en la alfombra"]:
c = len(cand.split())
print(f"{c:2} palabras de {len(ref)}: BP = e^(1 − r/c) ="
f" {math.exp(1 - len(ref) / c):.3f}")
precisión común: 7 / 7
modified (recortada): 2 / 7
4 palabras de 11: BP = e^(1 − r/c) = 0.174
7 palabras de 11: BP = e^(1 − r/c) = 0.565
Papineni et al., 2002 — BLEU: a Method for Automatic Evaluation of Machine Translation · fuente
N = 4, wₙ = 1/N · «a reference word should be considered exhausted after a matching candidate word is identified.»
El paper de BLEU es de dos mil dos, y no está en arXiv: está en la antología de la ACL. La idea del recorte, en sus palabras: una palabra de la referencia se agota cuando una de la traducción la usó. Y en su configuración base, la que usa todo el mundo desde entonces: n-gramas hasta cuatro, con pesos iguales.
Parte 2 · La Tabla 2: traducción
Dos tareas del WMT, workshop on machine translation, de dos mil catorce: inglés a alemán e inglés a francés.
Inglés → alemán, BLEU (paper, Tabla 2)
El WMT es una competencia anual de traducción. Inglés a alemán, newstest dos mil catorce. GNMT con RL, reinforcement learning, el traductor de Google de entonces: veinticuatro coma seis. ConvS2S, una red convolucional: veinticinco coma dieciséis. MoE, mixture of experts: veintiséis. Y un ensemble de ConvS2S, varios modelos promediados: veintiséis coma treinta y seis, el mejor hasta entonces. El transformer base, un solo modelo, ya le gana: veintisiete coma tres. El big, veintiocho coma cuatro: más de dos puntos arriba del mejor ensemble.
- GNMT + RL: 24,6
- ConvS2S: 25,16
- MoE: 26,03
- ConvS2S ens.: 26,36
- Transformer base: 27,3
- Transformer big: 28,4
Inglés → francés, BLEU (paper, Tabla 2)
Inglés a francés, con treinta y seis millones de frases de entrenamiento. GNMT, treinta y nueve coma nueve. ConvS2S, cuarenta coma cinco. MoE, cuarenta coma seis. El ensemble, cuarenta y uno coma tres. Acá el base no gana: treinta y ocho coma uno. El big, cuarenta y uno coma ocho. Y el base costó tres coma tres por diez a la dieciocho operaciones de punto flotante, menos que cualquier otro modelo de la tabla. Un detalle para leer con cuidado: la tabla y el abstract dicen cuarenta y uno coma ocho, y el texto de la sección seis punto uno dice cuarenta y uno coma cero. Citamos la tabla.
- GNMT + RL: 39,92
- ConvS2S: 40,46
- MoE: 40,56
- ConvS2S ens.: 41,29
- Transformer base: 38,1
- Transformer big: 41,8
Perplexity: la otra columna
a la pérdida promedio por token
dudar entre opciones iguales da
el modelo base, en el conjunto de desarrollo
La Tabla tres trae, además de BLEU, la perplexity, que en el episodio siete definimos de pasada. Es e a la pérdida promedio por token, donde la pérdida de cada token es menos el logaritmo de la probabilidad que el modelo le dio al correcto. En el dibujo, cuatro tokens con promedio uno coma cincuenta y nueve. Si el modelo le diera siempre probabilidad uno sobre k, la pérdida sería log de k, y la perplexity, k: duda como si eligiera entre k opciones iguales. El base tiene cuatro coma noventa y dos: como dudar entre unas cinco piezas de palabra. El big, cuatro coma treinta y tres.
Parte 3 · La Tabla 3: ablaciones
Una ablación saca o cambia una sola pieza y mide cuánto empeora. Todo sobre el modelo base, en el conjunto de desarrollo.
Variantes del modelo base, BLEU dev (paper, Tabla 3)
Ocho filas de la tabla tres, sobre newstest dos mil trece. El base: veinticinco coma ocho. Fila A: una sola head, con d sub k de quinientos doce para que el costo no cambie: veinticuatro coma nueve. Treinta y dos heads chiquitas: veinticinco coma cuatro. Ni muy pocas ni demasiadas. Fila B: achicar solo d sub k, la dimensión de las keys, empeora. Fila C: más ancho es mejor, veintiséis. Fila D: sin dropout, veinticuatro coma seis; es la pieza que más pesa de la tabla. Sin label smoothing, veinticinco coma tres. Fila E: una tabla de posiciones aprendida en vez de senos, veinticinco coma siete. Casi igual, como vimos en el episodio cuatro.
| Fila | Qué cambia | BLEU |
|---|---|---|
| base | h = 8, d_k = 64, P_drop 0,1, εₗₛ 0,1 | 25,8 |
| (A) | 1 head, d_k = 512 | 24,9 |
| (A) | 32 heads, d_k = 16 | 25,4 |
| (B) | d_k = 16, resto igual | 25,1 |
| (C) | d_model = 1024 | 26,0 |
| (D) | P_drop = 0 | 24,6 |
| (D) | εₗₛ = 0 | 25,3 |
| (E) | positional embedding aprendido | 25,7 |
Fila (A): cuántas heads, BLEU dev (paper, Tabla 3)
La fila A completa, en barras. Con h por d sub k siempre igual a quinientos doce, el costo es el mismo en las cinco, como contamos en el episodio tres. Una head sola pierde nueve décimas. De ocho a dieciséis no cambia nada, y con treinta y dos vuelve a bajar: cada head tiene solo dieciséis números para comparar query y key.
- h = 1: 24,9
- h = 4: 25,5
- h = 8 (base): 25,8
- h = 16: 25,8
- h = 32: 25,4
Vaswani et al., 2017 — Attention Is All You Need, sección 6.2 · arXiv:1706.03762
1 head: −0,9 BLEU · «While single-head attention is 0.9 BLEU worse than the best setting, quality also drops off with too many heads.»
El paper lo dice así. Una sola head es cero coma nueve BLEU peor que la mejor configuración, y la calidad también cae con demasiadas heads. Y sobre la fila D: el dropout es muy útil para evitar el overfitting, el sobre-aprendizaje de los datos de entrenamiento. Guardá esa frase para dentro de un rato.
Parte 4 · Tres ablaciones, en chico
La tarea del episodio siete, ordenar diez dígitos, con la misma receta. Cuatrocientos pasos y una sola semilla: alcanza para ver tendencias, no para afirmar décimas.
Fila (A): cuántas heads
Una, cuatro y ocho heads. Siempre con d sub model treinta y dos, así que d sub k baja de treinta y dos a ocho y a cuatro: el costo no cambia, como en la fila A. Medimos secuencias enteras bien y dígitos bien. Con una head, cuarenta y tres por ciento de secuencias bien. Con cuatro, noventa y tres coma cinco. Con ocho, noventa y cinco. La misma dirección que el paper, mucho más marcada: para ordenar, cada token tiene que mirar varias cosas a la vez, y con una sola head las promedia.
# fila (A): d_model fijo en 32, cambia cuántas heads lo parten
for h in (1, 4, 8):
torch.manual_seed(0)
m = entrenar(Ordenador(d=32, h=h), pasos=400)
r = evaluar(m)
print(f"h = {h} (d_k = {32 // h:2}): secuencias bien {r['secuencia']:.1%}"
f" · dígitos {r['digito']:.1%}")
h = 1 (d_k = 32): secuencias bien 43.4% · dígitos 93.2%
h = 4 (d_k = 8): secuencias bien 93.5% · dígitos 99.3%
h = 8 (d_k = 4): secuencias bien 95.0% · dígitos 99.5%
Fila (E): qué positional encoding
Tres variantes: los senos del paper, una tabla aprendida, o ningún positional encoding. El resto, igual. Senos, noventa y tres coma cinco. Aprendida, ochenta y dos coma cuatro: en cuatrocientos pasos, la tabla todavía no terminó de aprender. Y sin positional encoding, noventa y cuatro coma cinco. Sorpresa: para ordenar, el orden de la entrada no importa, solo qué dígitos hay. Y el decoder puede saber cuál le toca mirando lo que ya escribió. Para invertir, como en el episodio cinco, sería otra historia.
# fila (E): senos fijos, una tabla aprendida, o nada
for pe_tipo in ("seno", "aprendido", "ninguno"):
torch.manual_seed(0)
m = entrenar(Ordenador(pe_tipo=pe_tipo), pasos=400)
r = evaluar(m)
print(f"{pe_tipo:9}: secuencias bien {r['secuencia']:.1%}"
f" · dígitos {r['digito']:.1%}")
seno : secuencias bien 93.5% · dígitos 99.3%
aprendido: secuencias bien 82.4% · dígitos 98.1%
ninguno : secuencias bien 94.5% · dígitos 99.4%
Fila (D): cuánto dropout
Dropout de cero, cero coma uno y cero coma tres. Ojo con un detalle: en cada paso generamos secuencias nuevas. Sin dropout, noventa y ocho coma uno. Con cero coma uno, noventa y tres coma cinco. Con cero coma tres, doce por ciento. Al revés que el paper. Y tiene sentido: el modelo nunca ve dos veces el mismo ejemplo, así que no puede memorizar, no hay overfitting que evitar, y dropout solo agrega ruido. En WMT los datos son finitos y el modelo los recorre muchas veces.
# fila (D): P_drop, con secuencias nuevas en cada paso
for p in (0.0, 0.1, 0.3):
torch.manual_seed(0)
m = entrenar(Ordenador(p=p), pasos=400)
r = evaluar(m)
print(f"P_drop = {p}: secuencias bien {r['secuencia']:.1%}"
f" · dígitos {r['digito']:.1%}")
P_drop = 0.0: secuencias bien 98.1% · dígitos 99.8%
P_drop = 0.1: secuencias bien 93.5% · dígitos 99.3%
P_drop = 0.3: secuencias bien 12.3% · dígitos 84.8%
El paper contra nuestra tarea
Lado a lado. Las heads: misma dirección en las dos. La tabla aprendida: en el paper empata; en chico y con pocos pasos, pierde. Sin posición: el paper no lo prueba; en nuestra tarea no hace falta. Y dropout: ayuda en el paper y molesta en la nuestra. La lección de una ablación es siempre sobre una tarea y unos datos: la misma pieza puede ser clave en una y sobrar en otra.
| Ablación | Paper (BLEU dev) | Ordenar (secuencias) |
|---|---|---|
| 1 head vs. 8 | 24,9 vs. 25,8 | 43,4 % vs. 95,0 % |
| Tabla aprendida vs. senos | 25,7 vs. 25,8 | 82,4 % vs. 93,5 % |
| Sin positional encoding | — | 94,5 % |
| Sin dropout vs. 0,1 | 24,6 vs. 25,8 | 98,1 % vs. 93,5 % |
Resumiendo
- BLEU: precisión de 1 a 4-gramas, recortada, media geométrica × BP
- Nuestra frase: = 0,91 · 0,80 · 0,67 · 0,50 → BLEU 70,2
- Tabla 2: big 28,4 (EN-DE) y 41,8 (EN-FR); base 27,3 y 38,1
- Tabla 3: 1 head −0,9; sin dropout 24,6; tabla aprendida ≈ senos
- En chico: 1 head 43 %; sin dropout mejora; sin posición, igual
- Próximo: del transformer de 2017 a Gemma
Papers del episodio
¿Qué tal esta lección?
Sé el primero en calificarla
¿Terminaste la lección?
Márcala para sumar +50 XP y mantener tu racha.
Tutor IA
Contexto: Resultados y ablaciones
Conectando con el tutor…