Saltar ao contido
8/30Capítulo 8 de 30

Predición do seguinte token: embeddings e que significa a perplexidade

Adestra un modelo de caracteres con 32.033 nomes e descubre por que as perplexidades raramente coinciden.

Nesta páxina

Aquí tes dez nomes producidos por un programa que nunca viu unha palabra:

TEXT
cexze   momakurailezitynn   konimittain   llayn   ka
da      moliellavo          emia          sade    ftlsp

Ningún deles é un nome. Case todos o intentan. Son pronunciables, rematan onde rematan os nomes, e un deles — emia — está a unha soa letra dun real. O programa que os produciu garda 729 números, non ten noción de palabra, sílaba nin persoa, e axustouse cunha única pasada de reconto de pares adxacentes de letras.

Ao final deste capítulo, unha rede neuronal reducirá nun terzo a puntuación dese programa na mesma medida. A parte pola que paga a pena quedar é o que fai primeiro a rede: reproduce a táboa de recontos con tres decimais en cada fila ben poboada, sen que ninguén llo pida, porque os dous obxectos son respostas á mesma pregunta. Todo o que vén despois é o que o reconto nunca podería facer.

O obxectivo é unha identidade, non unha elección de deseño

Ligazón á sección: O obxectivo é unha identidade, non unha elección de deseño

O capítulo 7 deixoute cunha secuencia de enteiros e sen ningunha razón para que un seguise a outro. Aquí está a razón, e é unha liña do capítulo 2.

Un modelo de linguaxe é unha función que toma os tokens ata agora e devolve unha distribución sobre que token vén a continuación: un número por entrada do vocabulario, non negativo, que suma un. Nada máis. Para pasar diso a unha probabilidade dun documento enteiro, aplica a regra da cadea da probabilidade:

P(x1,x2,,xT)=t=1TP(xtx1,,xt1)P(x_1, x_2, \ldots, x_T) = \prod_{t=1}^{T} P(x_t \mid x_1, \ldots, x_{t-1})

Isto é unha identidade, certa para calquera secuencia de calquera cousa, sen supostos engadidos. Así que un modelo que fai o traballo pequeno — seguinte token dados os anteriores — xa fixo o traballo grande de asignarlle unha probabilidade a cada documento posible, exacta e de balde. A formulación popular disto como un truco barato («só predí a seguinte palabra») ten a lóxica ao revés: predicir o seguinte token é modelar a distribución conxunta. Nunca houbo unha segunda cousa que facer.

A loss sae coa mesma mecánica. En cada posición, o modelo produce unha distribución qq e a verdade é un único token coñecido, así que a entropía cruzada do capítulo 4 aplícase sen cambios:

L=1Tt=1Tlogqθ(xtx<t)L = -\frac{1}{T}\sum_{t=1}^{T} \log q_\theta(x_t \mid x_{<t})

Isto é a verosimilitude logarítmica negativa media: a receita do capítulo 2 cunha distribución categórica no lugar onde estaba a gaussiana. E como a distribución verdadeira é one-hot, a súa entropía é cero, así que, pola identidade do capítulo 4, a entropía cruzada é igual á diverxencia KL: baixar este número e achegar as crenzas do modelo ás dos datos son o mesmo acto.

Unha consecuencia merece a súa propia frase, porque é o feito económico baixo todo o campo. As etiquetas son os datos, desprazados unha posición. Ninguén anota nada. Un billón de tokens de texto é un billón de exemplos xa etiquetados, e por iso o corpus de adestramento dun modelo moderno é «internet» e non «un dataset que alguén construíu».

Antes de calquera rede, a baseline: 32.033 nomes, un por liña, e a tarefa de producir máis, unha letra cada vez.1

O vocabulario son 26 letras máis un símbolo de límite . que marca tanto o comezo como o final dun nome, así que o modelo ten que aprender onde empezan os nomes e onde paran. Son 27 símbolos, e o modelo máis pequeno posible é unha táboa de cantas veces cada símbolo seguiu a cada outro símbolo.

bigram.pyPYTHON
N = torch.zeros((27, 27), dtype=torch.int32)
for w in words:
    cs = ["."] + list(w) + ["."]
    for a, b in zip(cs, cs[1:]):
        N[stoi[a], stoi[b]] += 1

P = N.float()
P = P / P.sum(1, keepdim=True)            # one distribution per row   

Dúas liñas de aritmética e o modelo queda axustado — e non é unha heurística: dividir os recontos polos totais de fila é a estimación de máxima verosimilitude para unha distribución categórica, que é a receita do capítulo 2 coa análise xa feita.

TEXT
names: 32033        train/val/test: 25626 / 3203 / 3204
training bigrams: 182583

the six most likely letters after 'a':
    a -> '.'  0.1944   a -> 'n'  0.1600   a -> 'r'  0.0967
    a -> 'l'  0.0749   a -> 'h'  0.0690   a -> 'y'  0.0606

Mostrea dela — escolle unha letra da fila da letra actual, móvete a esa fila, repite ata que apareza o símbolo de límite — e obtés os nomes do comezo deste capítulo. Fallan dun xeito específico e informativo: localmente plausibles, globalmente sen sentido. Cada par adxacente de letras en momakurailezitynn é un par que aparece en nomes reais; simplemente hai dezasete seguidos. O modelo ten unha letra de memoria, así que non pode saber que leva demasiado tempo avanzando.

A loss en nomes reservados é de 2,4546 nats. Ese número non significa nada por si só, e por iso existe a perplexidade:

PPL=exp ⁣(1Ttlogq(xtx<t))=eL\mathrm{PPL} = \exp\!\left(-\frac{1}{T}\sum_t \log q(x_t \mid x_{<t})\right) = e^{L}

Escrito completo, sen ningunha biblioteca facendo o traballo:

perplexity.pyPYTHON
@torch.no_grad()
def perplexity(logits, Y):
    logp = F.log_softmax(logits, dim=1)          # log q for every symbol
    chosen = logp[torch.arange(len(Y)), Y]       # log q of the one that came next   
    return torch.exp(-chosen.mean())             

Exponenciar desfai o logaritmo e devolve o número ás unidades de contar cousas. A forma limpa de ver o que conta é medir un modelo que non sabe absolutamente nada: un que asigna probabilidade 1/271/27 a cada símbolo, independentemente do context:

TEXT
uniform over 27 symbols            loss 3.2958 nats   ppl  27.000
bigram counts, add-one smoothed    loss 2.4546 nats   ppl  11.642

Exactamente 27,000, porque elog27=27e^{\log 27} = 27. A perplexidade é o número efectivo de opcións igualmente probables entre as que escolle o modelo. Unha perplexidade de 27 significa «nin idea, podería ser calquera cousa». O 11,642 do modelo de reconto significa que unha letra de context déixao tan incerto como alguén escollendo ás cegas entre unhas doce opcións en vez de vinte e sete — e por iso se cita a perplexidade e non a loss bruta.

Dúas cousas saen mal con ela, e a segunda sae mal en artigos publicados.

As probabilidades cero son fatais. Das 729 celas da táboa, 113 nunca aparecen no adestramento: o 15,5 % está baleiro. Iso está ben ata que o conxunto reservado cae nunha delas, e sete bigramas na validación fano, entre eles dq, zj e qo dúas veces. Probabilidade cero significa log -\infty, o que significa loss infinita e perplexidade infinita: un nome de cada tres mil destrúe a métrica. O parche habitual é engadir 1 a cada reconto antes de normalizar, o que aquí custa case nada (2,4546 en vez de 2,4524). Pero o parche é unha confesión. Un modelo de reconto non pode xeneralizar en absoluto. Non ten forma de sospeitar que qo é plausible porque qu é común e o se comporta como u noutros lugares, xa que non ten noción de que dous símbolos poidan parecerse. Cada cela apréndese soa, e arranxar iso é para o que serve o resto deste capítulo.

A perplexidade é un prezo por token, e o token é un parámetro libre. Este é o erro que aparece constantemente cando se comparan modelos, e é fácil velo en canto miras. Colle o mesmo corpus de prosa inglesa do capítulo 7, o mesmo modelo de bigramas interpolado, e cambia só como se corta o texto:

unidadevocabulariotokens en testentropía cruzadaperplexidadebits por carácter
caracteres7614.4692,521712,453,6378
BPE, 512 merges3296.8713,854747,212,6407
BPE, 2.048 merges1.8204.2335,7468313,202,4254
palabras2.9916.2843,562735,262,2322

A perplexidade varía por un factor de 25 entre esas filas. Nada do modelo cambiou; só o tamaño da cousa que se predí. Predicir unha palabra enteira é máis difícil ca predicir unha letra, así que custa máis por predición — e hai menos predicións que facer.

Agora le a última columna, que divide o custo total polo número de caracteres e o converte a bits. Reordena a táboa. Por perplexidade, a clasificación é caracteres, palabras, BPE-512, BPE-2048; por bits por carácter é palabras, BPE-2048, BPE-512, caracteres. O modelo de caracteres pasa do primeiro posto ao último. O modelo de 2.048 merges, que por perplexidade parece 6,6 veces peor ca o de 512 merges, é en realidade o mellor dos dous: 2,4254 bits fronte a 2,6407.

Así que unha perplexidade só é comparable entre dous modelos que comparten tokenizer, e os modelos con tokenizers diferentes só se poden comparar en bits por carácter: a magnitude que Shannon mediu en 1951 facendo que persoas adiviñasen a seguinte letra dun texto inglés, e que acoutou arredor dun bit por carácter.2 O noso mellor bigrama queda en 2,23 bits, que é un bo resumo de canto camiño lle queda aínda a este capítulo.

Agora constrúe o mesmo modelo como unha rede. Levaralle ordes de magnitude máis aritmética chegar ao mesmo sitio, e chegar ao mesmo sitio é precisamente o punto.

Substitúe a táboa por unha matriz de pesos WW con forma 27×2727 \times 27. Converte a letra actual nun vector one-hot, multiplica, e chama logits ao resultado: as puntuacións sen normalizar do capítulo 4. Despois softmax, despois entropía cruzada, despois gradient descent.

neural_bigram.pyPYTHON
W = torch.randn((27, 27), requires_grad=True)

for step in range(3000):
    logits = W[xs]                            
    loss = F.cross_entropy(logits, ys)
    W.grad = None
    loss.backward()
    W.data -= 50.0 * W.grad

A liña destacada contén unha definición que paga a pena ter. Multiplicar un vector one-hot por unha matriz selecciona unha fila dela, así que a multiplicación é unha consulta — e cada implementación salta a aritmética e fai a consulta directamente, que é o que é W[xs].

Isto é unha táboa de embedding. Unha matriz cunha fila por entrada do vocabulario, indexada por id de token. Sen xeometría, sen semántica, sen algoritmo separado: unha táboa de consulta cuxo contido resulta ser aprendido por gradient descent xunto con todo o demais. Toda afirmación mística sobre o «espazo de embedding» remata aquí.

Adéstraa e observa cara a onde vai:

TEXT
  step     1   train 3.7550   val 3.3882   max gap to the count table 0.757269
  step   100   train 2.4732   val 2.4726   max gap to the count table 0.388354
  step  1000   train 2.4557   val 2.4549   max gap to the count table 0.041862
  step  3000   train 2.4547   val 2.4544   max gap to the count table 0.004048

A última columna é a maior diferenza absoluta entre calquera cela de softmax(W) e a cela correspondente da táboa de recontos, e vai a cero. Despois de 3.000 pasos, o maior desacordo en calquera das 729 celas é 0,004048 e a media é 0,000224. A peor cela é qi, vista doce veces en todo o conxunto de adestramento; entre as 22 filas con máis de mil aparicións, o peor desacordo é 0,000562.

TEXT
                 count table   network
    a -> '.'        0.1945     0.1945
    a -> 'n'        0.1601     0.1601
    a -> 'r'        0.0967     0.0967

Gradient descent, empezando con números aleatorios e sen recibir máis instrución ca «fai grande a log-probabilidade da seguinte letra», redescubriu a táboa de recontos. E tiña que facelo: os recontos son a estimación de máxima verosimilitude, a entropía cruzada é a verosimilitude logarítmica negativa, así que ambos procedementos optimizan o mesmo obxectivo e ese obxectivo ten un único óptimo. A rede non aprendeu algo parecido a contar. Converxeu a contar, lentamente.

O que suscita a pregunta xusta de por que alguén se molestaría. Porque a táboa de recontos non ten a onde ir desde aquí, e a rede si.

O context é o colo de botella, non a capacidade

Ligazón á sección: O context é o colo de botella, non a capacidade

Amplía o modelo para mirar máis dun carácter anterior. Esta é a arquitectura de Bengio de 2003, a antepasada directa de todos os modelos do resto deste curso:4 colle os tres últimos caracteres, mapea cada un mediante unha táboa de embedding a unha fila de 10 dimensións, concatena as filas en 30 números, pásaas pola capa oculta do capítulo 5, e remata cunha capa de saída que produce un logit por entrada do vocabulario.

mlp.pyPYTHON
C  = torch.randn((27, 10))          # the embedding table
W1 = torch.randn((3 * 10, 200))     # the hidden layer from Chapter 5
W2 = torch.randn((200, 27))         # one output per vocabulary entry

emb = C[X].view(-1, 30)             # three lookups, concatenated   
h = torch.tanh(emb @ W1 + b1)
logits = h @ W2 + b2                
loss = F.cross_entropy(logits, Y)

Fíxate no que é novo e no que non. A capa oculta é a do capítulo 5, sen cambios; a loss é a do capítulo 4, sen cambios. As novidades son a táboa de embedding ao principio e unha capa de saída tan ancha como o vocabulario do capítulo 7 — e esa segunda é a parte cara de todo modelo de linguaxe que se construíu, porque un vocabulario real ten 100.000 entradas e esta multiplicación matricial execútase en cada posición.

O mesmo código, adestrado de forma idéntica, cambiando só o tamaño da context window:

contextparámetrosloss de validaciónperplexidade de validación
reconto, 1 carácter7292,454611,642
neuronal, 1 carácter7.8972,457711,678
neuronal, 3 caracteres11.8972,11458,285
neuronal, 8 caracteres21.8972,05067,773

A segunda fila é a interesante. Unha rede cunha capa oculta de 200 unidades e once veces máis parámetros ca a táboa de recontos rende exactamente igual ca a táboa de recontos e nada mellor. A capacidade nunca foi a limitación. Un carácter de context permite unha certa loss e nada do que lle engadas pode baixar dela, porque a información non está aí.

Dálle tres caracteres e a perplexidade baixa de 11,68 a 8,29: unha redución do 29 %, comprada con 4.000 parámetros extra. Supera o reconto aquí exactamente pola razón diagnosticada antes: un modelo de reconto sobre contexts de tres caracteres precisa 273=19,68327^3 = 19{,}683 filas, a maioría baleiras ou cunha soa observación, e aprende cada unha por separado. A rede comparte. Se a, e e i acaban con filas de embedding semellantes, o que aprende despois de bra transfírese a bre sen que nunca vise bre. Esa transferencia é todo o valor da táboa de embedding, e é a fenda entre as filas dúas e tres.

As mostras melloran en consecuencia:

TEXT
deliah   nellara   joce     kael      quintis
salayson  reety    khyrmin  mahnen    madiaryxia

Aínda non é unha lista de nomes reais. Pero deliah, nellara e kael non desentoarían nunha, e os monstros interminables desapareceron: o máis longo de vinte mostras do modelo de reconto ten dezanove letras; o máis longo de vinte deste ten trece.

Que hai realmente dentro da táboa de embedding

Ligazón á sección: Que hai realmente dentro da táboa de embedding

A táboa é 27×1027 \times 10: unha fila de dez números por carácter, todos inicializados ao azar e movidos só polo gradient da loss do seguinte carácter. Ninguén puxo nada aí dentro. Entón, que acabou nela?

A ferramenta para preguntalo é a similitude coseno, que é o produto escalar do capítulo 1 coas lonxitudes divididas:

cos(a,b)=abab\cos(\mathbf{a}, \mathbf{b}) = \frac{\mathbf{a} \cdot \mathbf{b}}{\lVert \mathbf{a} \rVert \, \lVert \mathbf{b} \rVert}

Mide o ángulo entre dous vectores e ignora as súas lonxitudes, que é o que queres cando a lonxitude dunha fila reflicte cantas veces apareceu o seu token máis que o que significa. Normaliza primeiro cada vector a lonxitude 1 — como fan os sistemas reais, unha vez, no momento de indexar — e a similitude coseno é simplemente o produto escalar.

Aquí están os veciños máis próximos dalgúns caracteres na táboa adestrada:

TEXT
  'c' -> 'k':+0.598      'j' -> 'z':+0.650      'i' -> 'y':+0.541
  'u' -> 'e':+0.482      'a' -> 'h':+0.367      '.' -> 'q':+0.077

Parte diso é o que promete o folclore. c e k son intercambiables en nomes, e tamén i e y; j e z son ambas consoantes raras, sobre todo iniciais, que se comportan de xeito parecido. O símbolo de límite . non está preto de nada — 0,077 á súa letra máis próxima — porque é o único símbolo que marca unha posición en vez dun son.

E parte diso non. O veciño máis próximo de a é h, non outra vogal. De media sobre todos os pares:

TEXT
mean cosine, vowel to vowel         : +0.1889
mean cosine, consonant to consonant : +0.0765
mean cosine, vowel to consonant     : -0.0042

As vogais parécense máis entre si ca ás consoantes, e o efecto é real pero pequeno. Probado contra 2.000 grupos de cinco letras escollidos ao azar, 58 deses grupos sepáranse polo menos igual de limpos: unha fenda significativa arredor de p=0.03p = 0.03. Real, entón, pero nada parecido á illa xeométrica nítida que suxiren os relatos populares sobre embeddings.

Esa é a descrición honesta dunha táboa de embedding, e paga a pena gardala para o resto do curso. Non é un mapa do significado. É un cambio de coordenadas, aprendido en vez de deseñado, cuxo único traballo é facer doado o traballo da seguinte capa: a mesma frase que o capítulo 5 usou para a capa oculta que pregou o plano para resolver XOR. Calquera estrutura que atopes nela está aí porque baixou a loss, e a estrutura que non baixa a loss simplemente non está.

word2vec, GloVe e a aritmética que todo o mundo cita

Ligazón á sección: word2vec, GloVe e a aritmética que todo o mundo cita

Se a parte útil é a táboa, podes perseguila directamente. Iso é word2vec: conserva a consulta de embedding, tira o modelo de linguaxe.5

O obxectivo de skip-gram with negative sampling é unha liña. Para un par real (centro, context) extraído do corpus, empurra cara arriba o seu produto escalar; para kk pares falsos extraídos dunha distribución de ruído, empúrrao cara abaixo:6

logσ(vcvo)+i=1klogσ(vcvni)\log \sigma(\mathbf{v}_c \cdot \mathbf{v}_o) + \sum_{i=1}^{k} \log \sigma(-\mathbf{v}_c \cdot \mathbf{v}_{n_i})

Iso é unha clasificación binaria — «apareceron realmente xuntas estas dúas palabras?» — e é barato precisamente porque nunca toca o vocabulario completo, que foi o que fixo práctico adestrar con miles de millóns de palabras en 2013. GloVe chega a vectores semellantes desde o outro lado, factorizando a matriz de recontos globais de coocorrencia en vez de pasar por exemplos en streaming.7 Ambos se axustan exactamente á estatística coa que se construíu a táboa de recontos. Son reconto, comprimido.

Adestrados en text8 — 17.005.207 palabras da Wikipedia inglesa, 71.290 delas aparecendo polo menos cinco veces, 100 dimensións, tres pasadas — os vectores saen coa propiedade que os fixo famosos:

TEXT
king     -> charles 0.700, son 0.693, queen 0.686, henry 0.669, throne 0.667
physics  -> chemistry 0.672, electromagnetism 0.661, quantum 0.654, theoretical 0.624
guitar   -> bass 0.733, vocals 0.732, acoustic 0.728, guitars 0.703, drums 0.685
three    -> seven 0.892, two 0.877, one 0.875, five 0.871, four 0.870

Ninguén forneceu unha categoría para instrumentos nin para numerais. Agora a parte famosa: colle king, resta man, suma woman, e atopa o vector máis próximo ao resultado.

TEXT
king - man + woman
   nothing excluded : king 0.693, elizabeth 0.657, wife 0.629, woman 0.607
   a, b, c excluded : elizabeth 0.657, wife 0.629, mary 0.607   (queen is 4th, 0.604)

O vector máis próximo a king - man + woman é king. Non é unha rareza dun exemplo. O conxunto de avaliación de Mikolov formula preguntas da forma a : b :: c : ? — 8.869 semánticas (paris : france :: rome : italy) e 10.675 sintácticas (walking : walked :: swimming : swam) — e, entre as 4.103 preguntas semánticas que este vocabulario pode responder, a gañadora é unha das tres palabras de entrada o 99,8 % das veces. As demostracións publicadas non o mencionan, porque a regra de puntuación estándar elimina a, b e c antes de mirar. É unha regra lexítima, e fai máis traballo ca a aritmética:

como se escolle a respostasemánticasintáctica
offset, coas entradas excluídas (estándar)17,0 %11,9 %
offset, sen excluír nada0,1 %0,4 %
veciño máis próximo só de c, entradas excluídas13,1 %9,3 %
veciño máis próximo só de b, entradas excluídas2,3 %0,4 %

A terceira fila é a que hai que asimilar. Tira a e b, non fagas ningunha aritmética, devolve o que estea máis preto de c — e conservas o 77 % da puntuación semántica. A maior parte do que parece razoamento analóxico é proximidade máis unha regra que prohibe as respostas obvias, que é o que Linzen mediu con vectores ben adestrados e o que replican as baselines de arriba.8 Estes vectores concretos son pequenos — 17 millóns de palabras fronte aos miles de millóns detrás dos modelos publicados — así que le as porcentaxes como unha forma, non como o estado da arte. A forma é o que sobrevive a calquera escala: a aritmética é real, e moito máis feble ca a demostración que todo o mundo cita.

Estático e contextual: un vector por palabra, ou un por aparición

Ligazón á sección: Estático e contextual: un vector por palabra, ou un por aparición

Todo o visto ata agora ten un límite duro incorporado á estrutura de datos. Unha táboa ten unha fila por token. A palabra bank recibe un vector, o mesmo nunha frase sobre un río e nunha frase sobre unha hipoteca — necesariamente, porque unha consulta por id non pode depender de nada máis.

A solución é deixar de ler o vector da táboa e empezar a computalo desde a frase. Iso é un contextual embedding, introducido por ELMo en 2018 e convertido en estándar por BERT ese mesmo ano.910 Medidos no modelo real, os números son máis nítidos ca a explicación:

TEXT
sentence A: "He sat on the bank of the river and watched the water go by."
sentence B: "She deposited the cheque at the bank on the corner of the street."

static vector for 'bank' (a row of the input embedding table)
    cosine A vs B ........................ 1.000000

contextual vector for 'bank', layer by layer
    layer  |  A vs B  |  A vs another river sentence  |  B vs another money sentence
        0  |  0.9512  |            0.9512             |            0.9359
        4  |  0.5647  |            0.8987             |            0.7716
        9  |  0.4284  |            0.8699             |            0.7568
       12  |  0.5278  |            0.8702             |            0.7335

A primeira fila é exacta, non aproximada: o vector estático de bank son os mesmos 768 números nas dúas frases, así que o coseno é 1 por construción. Nove capas máis tarde, as dúas aparicións quedan en 0,43, mentres que bank en dúas frases diferentes sobre ríos queda en 0,87. Ninguén etiquetou ningún sentido en ningún momento deste proceso; os sentidos separáronse porque separalos fai que o obxectivo de adestramento — adiviñar un token oculto a partir dos seus veciños — sexa máis doado de satisfacer.

Dous detalles merecen atención. A capa 0 xa é 0,9512 en vez de 1,0, porque se engadiron embeddings de posición e a palabra está nun lugar distinto en cada frase. E a similitude volve subir nas capas 11 e 12: as capas finais dun modelo preadestrado están especializadas no seu obxectivo de adestramento, e adoitan non ser o mellor lugar do que tomar unha representación.

Mostrar detalles

Opcional: weight tying.

En bert-base-uncased a táboa de embedding é 30,522×76830{,}522 \times 768: 23.440.896 números, o 21,4 % dos 109.482.240 parámetros do modelo. Nun modelo de linguaxe pequeno, a fracción aínda é maior, e por iso un truco é case universal: a táboa de entrada e a capa de saída que produce os logits son a mesma matriz, usada unha vez mediante consulta de filas e outra vez transposta.11 A capa de saída xa asigna un vector a cada entrada do vocabulario — toma un produto escalar contra cada unha — e tying di que o vector usado para ler un token e o vector usado para escribilo deben ser o mesmo obxecto. Reduce parámetros e mellora a perplexidade ao mesmo tempo, algo o bastante raro como para reparalo.

Un embedding model non é un modelo de linguaxe

Ligazón á sección: Un embedding model non é un modelo de linguaxe

Para buscar nun corpus por significado precisas un vector por frase. Téndoos, a busca é trivial: isto é todo o semantic retrieval, e o capítulo 19 trata sobre todo o que hai arredor del:

search.pyPYTHON
E = normalise(embed(sentences))       # (200, d), every row of length 1
q = normalise(embed([query]))         # (1, d)
scores = q @ E.T                      # one matrix multiply   
top5 = scores[0].argsort()[::-1][:5]

Así que a única pregunta real é de onde sae embed. O movemento obvio é coller un modelo de linguaxe preadestrado, pasar cada frase por el e facer a media dos vectores de token. Aquí está ese método fronte a catro alternativas, puntuado de dúas maneiras: a correlación de rangos entre coseno e xuízos humanos de similitude nos 1.379 pares do benchmark STS, e recuperación top-1 nun índice construído cos 200 pares máis fortemente parafraseados deses pares: un lado de cada par indexado, o outro usado como query.

como se embedde a frasecorrelación de rangostop-1 nun índice de 200 frases
solapamento binario de palabras (sen modelo ningún)0,550089,0 %
media dos vectores estáticos adestrados arriba0,526385,5 %
BERT, o token [CLS]0,203067,0 %
BERT, media dos vectores de token0,472984,0 %
MiniLM, adestrado de forma contrastiva0,820392,0 %

Le as tres filas do medio contra as dúas primeiras. Un transformer preadestrado de 109 millóns de parámetros, usado da forma obvia, é peor para xulgar a similitude entre frases ca contar cantas palabras comparten dúas frases — e peor ca facer a media dos vectores text8 de 100 dimensións adestrados hai un momento. O token [CLS], que os titoriais aínda recomendan porque BERT se preadestrou cun obxectivo a nivel de frase asociado a el, é peor ca a metade diso.

Isto non é un defecto de BERT. É o obxectivo. Un modelo de linguaxe adéstrase para que os seus estados ocultos predigan un token; nada aí pide que dúas paráfrases acaben preto unha da outra, e nada recompensa unha xeometría na que coseno signifique «mesmo significado». A última fila é un modelo dunha quinta parte do tamaño (22.713.216 parámetros) adestrado cunha loss totalmente distinta: aprendizaxe contrastiva, onde os exemplos son pares — unha pregunta e a súa resposta, unha frase e a súa paráfrase — e o obxectivo achega os pares verdadeiros mentres afasta negativos mostreados. Esa é a achega de Sentence-BERT e a orixe de toda a industria dos embedding models.12 Dense Passage Retrieval aplica a mesma receita directamente á busca, cun encoder para queries e outro para pasaxes.13

Así que, a regra práctica:

Un embedding model non é un modelo de linguaxe coa última capa retirada. É un modelo diferente cun obxectivo diferente, normalmente moito máis pequeno, cuxo coseno significa o que queres que signifique porque foi adestrado con pares nos que iso era o obxectivo. A táboa de arriba é o custo de substituír un polo outro.

E a familia falla coa orde das palabras. «The dog bit the man» e «the man bit the dog» teñen bolsas de palabras idénticas, así que o solapamento de palabras e a media de vectores estáticos danlles coseno exactamente 1,000000, e BERT con mean pooling, que si ve a posición, aínda queda case aí — e MiniLM adestrado de forma contrastiva aínda as pon en 0,979. Se a túa tarefa de retrieval depende de quen fixo que a quen, ningún limiar de coseno te salvará.

O capítulo 19 constrúe un sistema de retrieval de produción sobre esta base e chega a un corte de coseno concreto. A última medida deste capítulo é o que fai que ese número sexa defendible en vez de máxico.

A maldición da dimensionalidade, nunha táboa

Ligazón á sección: A maldición da dimensionalidade, nunha táboa

Os embeddings reais teñen centos ou miles de compoñentes, e as distancias compórtanse de forma estraña alá arriba. Colle 1.000 puntos aleatorios no cubo unidade de dd dimensións e mira a razón entre a maior e a menor distancia entre calquera dous deles:

dimensiónspar máis próximopar máis afastadorazón
20,00071,36121921,66
100,23612,33979,91
1003,00475,17521,72
1.00011,780914,03061,19
10.00039,615242,01251,06

En dez mil dimensións, o par de puntos máis afastado está só un 6 % máis lonxe ca o par máis próximo. Todo está aproximadamente equidistante de todo o demais, «veciño máis próximo» deixa de transportar moita información, e esa é a maldición da dimensionalidade — ademais dunha das razóns polas que as grandes bases de datos vectoriais non fan busca exacta de veciño máis próximo. A outra cara da mesma moeda é o que fai viables os limiares de coseno: medido sobre mil pares de vectores unidade aleatorios, o coseno medio queda en 0.0052-0.0052 en 100 dimensións e +0.0003+0.0003 en 768, con desviacións estándar de 0,0968 e 0,0357 — e en 768 dimensións só o 0,2 % dos pares aleatorios supera 0,1 en valor absoluto. Unha similitude medida de 0,4, polo tanto, non é «40 % semellante»; está moi fóra do que produce o azar, e por iso limiares entre 0,3 e 0,7 separan sinal de ruído en vez de quedar no medio del.

O modelo deste capítulo le un número fixo de caracteres anteriores, consulta cada un e pega os resultados en orde. Ese deseño ten dous problemas, e son o mesmo problema.

Mira de novo a táboa de context: pasar de tres caracteres a oito case duplicou os parámetros e comprou 0,06 nats. O custo medra linealmente co context — cada posición extra precisa a súa propia prancha da primeira matriz de pesos — e o beneficio non. Lévao a mil tokens e só a primeira capa xa pesa máis ca o resto do modelo, a maior parte gastada en posicións que non importan para ningunha predición dada.

E ese é o segundo problema: o modelo non ten ningunha forma de decidir cales dos tokens anteriores importan. A posición dúas recibe os seus propios pesos e a posición sete recibe os seus, permanentemente, sexa o que sexa o que conteñan. Cando o modelo está a deletrear nell, o carácter decisivo é o inmediatamente anterior. Cando unha frase contén un pronome, a palabra que fixa o seu referente pode estar corenta tokens atrás — e non se pode asignar unha ranura fixa a «corenta atrás», porque a próxima vez serán seis.

O que queremos é un modelo que compute, para cada predición, canto debe contar cada token anterior: pesos sobre o context producidos polo contido, non fixados pola disposición. Escríbeo con coidado e empeza como algo totalmente mundano: unha media sobre os tokens anteriores. Despois deixa que os pesos desa media se aprendan, e deixa que dependan de que token está a preguntar.

Iso é attention, e é o capítulo 9.


Tamén paga a pena ler ao lado: o capítulo 3 de Speech and Language Processing de Jurafsky e Martin, que trata os modelos n-gram, smoothing e perplexidade con moito máis coidado do que cabe aquí, incluído por que a interpolación e o back-off superan engadir un; as notas de Stanford CS229 §17.1–17.2 para o modelado de linguaxe desde o lado probabilístico; e o artigo de Linzen citado arriba, que é curto e paga a pena ler enteiro.

  1. O exemplo de xeración de nomes, o dataset e a progresión desde unha táboa de recontos ata unha rede ao estilo Bengio seguen a serie building makemore de Andrej Karpathy, cuxas dúas primeiras partes son o mellor acompañamento para este capítulo.

  2. Shannon, C. E. Prediction and Entropy of Printed English. Bell System Technical Journal 30(1), pp. 50–64 (1951). Persoas adiviñando a seguinte letra do inglés escrito, e a medición orixinal de bits por carácter.

  3. Shannon, C. E. A Mathematical Theory of Communication. Bell System Technical Journal 27 (1948). O teorema de codificación de fontes, e a identificación da predición coa compresión.

  4. Bengio, Y., Ducharme, R., Vincent, P. and Jauvin, C. A Neural Probabilistic Language Model. Journal of Machine Learning Research 3, pp. 1137–1155 (2003). A arquitectura usada arriba: un embedding por palabra, concatenado sobre unha xanela fixa, a través dunha capa oculta, ata un softmax sobre o vocabulario.

  5. Mikolov, T., Chen, K., Corrado, G. and Dean, J. Efficient Estimation of Word Representations in Vector Space. arXiv:1301.3781 (2013). CBOW e skip-gram, e o conxunto de analoxías usado arriba.

  6. Mikolov, T., Sutskever, I., Chen, K., Corrado, G. and Dean, J. Distributed Representations of Words and Phrases and their Compositionality. arXiv:1310.4546 (2013). Negative sampling, submostraxe de palabras frecuentes, e a distribución de ruído elevada á potencia 3/4 usada arriba.

  7. Pennington, J., Socher, R. and Manning, C. GloVe: Global Vectors for Word Representation. EMNLP 2014. Vectores de palabras a partir dunha factorización da matriz global de coocorrencia en vez de xanelas locais en streaming.

  8. Linzen, T. Issues in evaluating semantic spaces using word analogies. RepEval 2016, arXiv:1606.07736. A fonte das baselines sen offset replicadas arriba.

  9. Peters, M. et al. Deep contextualized word representations. arXiv:1802.05365 (2018). ELMo: un vector por aparición, computado por un modelo de linguaxe bidireccional.

  10. Devlin, J., Chang, M.-W., Lee, K. and Toutanova, K. BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding. arXiv:1810.04805 (2018). O modelo medido no experimento de bank.

  11. Press, O. and Wolf, L. Using the Output Embedding to Improve Language Models. arXiv:1608.05859 (2016), and Inan, H., Khosravi, K. and Socher, R. Tying Word Vectors and Word Classifiers. arXiv:1611.01462 (2016). Dous argumentos independentes para o mesmo truco.

  12. Reimers, N. and Gurevych, I. Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks. arXiv:1908.10084 (2019). A súa medición inicial — BERT con mean pooling rendendo peor ca vectores estáticos promediados en similitude de frases — é o que reproduce a táboa de arriba.

  13. Karpukhin, V. et al. Dense Passage Retrieval for Open-Domain Question Answering. arXiv:2004.04906 (2020). Adestramento contrastivo dun retriever de dous encoders; o antepasado directo da pila de retrieval do capítulo 19.

Listo para deixar que LIA escolla por ti?

Crea con todos os modelos de IA nun só sitio: empeza gratis hoxe mesmo.