Предсказване на следващия token: embedding-и и какво означава перплексията
Обучете символен модел върху 32 033 имена и вижте как gradient descent преоткрива таблица с брояния — и защо perplexity рядко съвпада.
На тази страница
Ето десет имена, произведени от програма, която никога не е виждала дума:
cexze momakurailezitynn konimittain llayn ka
da moliellavo emia sade ftlspНито едно от тях не е име. Почти всички обаче се опитват. Произносими са, завършват там, където завършват имената, а едно от тях — emia — е само на една буква от истинско. Програмата, която ги е произвела, съдържа 729 числа, няма понятие за дума, сричка или човек и е напасната с едно-единствено преминаване на броене на съседни двойки букви.
До края на тази глава една невронна мрежа ще намали оценката на тази програма с една трета по същата мярка. Частта, заради която си струва да останете, е какво прави мрежата първо: тя възпроизвежда таблицата с брояния до три знака след десетичната запетая във всеки добре запълнен ред, без prompt, защото двата обекта са отговори на един и същ въпрос. Всичко след това е онова, което броенето никога не би могло да направи.
Целта е тъждество, не дизайнерски избор
Връзка към раздела: Целта е тъждество, не дизайнерски изборГлава 7 ви остави с редица от цели числа и без причина едно да следва друго. Ето причината, и тя е един ред от Глава 2.
Езиковият модел е функция, която взема tokens дотук и връща разпределение за това кой token идва следващ: по едно число за всеки елемент от речника, неотрицателно, със сбор едно. Нищо друго. За да стигнете от това до вероятност за цял документ, приложете верижното правило на вероятностите:
Това е тъждество, вярно за всяка редица от каквото и да било, без никакви допускания. Затова модел, който върши малката задача — следващ token при дадени предишните — вече е свършил голямата задача да присвои вероятност на всеки възможен документ, точно и безплатно. Популярното представяне на това като евтин трик („той само предсказва следващата дума“) обръща логиката наопаки: предсказването на следващия token е моделиране на съвместното разпределение. Никога не е имало второ нещо за правене.
Загубата следва също толкова механично. На всяка позиция моделът произвежда разпределение , а истината е един известен token, така че крос-ентропията от Глава 4 се прилага без промяна:
Това е средната отрицателна log-likelihood — рецептата от Глава 2 с категорийно разпределение в слота, където беше гаусовото. И понеже истинското разпределение е one-hot, ентропията му е нула, така че по тъждеството от Глава 4 крос-ентропията е равна на KL дивергенцията: да намалявате това число и да придърпвате убежденията на модела към данните е един и същ акт.
Едно следствие заслужава собствено изречение, защото е икономическият факт под цялата област. Етикетите са данните, изместени с една позиция. Никой не анотира нищо. Един трилион tokens текст са един трилион предварително етикетирани примера, затова обучителният корпус на съвременен модел е „интернетът“, а не „набор от данни, който някой е построил“.
Честната базова линия: броене
Връзка към раздела: Честната базова линия: броенеПреди всяка мрежа — базовата линия: 32 033 имена, по едно на ред, и задачата да се произвеждат още такива, буква по буква.1
Речникът е 26 букви плюс граничен символ ., който маркира и началото, и края на име, така че моделът трябва да научи къде започват имената и къде спират. Това са 27 символа, а най-малкият възможен модел е таблица на това колко често всеки символ е следвал всеки друг символ.
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 Два реда аритметика и моделът е напаснат — и това не е евристика: деленето на броянията на сумите по редове е оценката по максимално правдоподобие за категорийно разпределение, тоест рецептата от Глава 2 с вече свършеното смятане.
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Вземете проби от него — изберете буква от реда на текущата буква, преминете към този ред, повтаряйте, докато се появи граничният символ — и получавате имената в началото на тази глава. Те се провалят по конкретен и информативен начин: локално правдоподобни, глобално безсмислени. Всяка съседна двойка букви в momakurailezitynn е двойка, която се среща в истински имена; просто тук има седемнадесет такива поред. Моделът има памет от една буква, затова не може да знае, че продължава прекалено дълго.
Перплексия и как да я четем
Връзка към раздела: Перплексия и как да я четемЗагубата върху отделените за проверка имена е 2.4546 ната. Това число само по себе си не означава нищо, затова съществува perplexity:
Изписано изцяло, без библиотека да върши работата:
@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()) Експоненцирането отменя логаритъма и връща числото в единиците на броене на неща. Чистият начин да видите какво брои е да измерите модел, който не знае абсолютно нищо — такъв, който присвоява вероятност на всеки символ независимо от контекста:
uniform over 27 symbols loss 3.2958 nats ppl 27.000
bigram counts, add-one smoothed loss 2.4546 nats ppl 11.642Точно 27.000, защото . Perplexity е ефективният брой еднакво вероятни опции, между които моделът избира. Perplexity от 27 означава „нямам представа, може да е всичко“. 11.642 за модела с броене означава, че една буква контекст го оставя толкова несигурен, колкото някой, който избира на сляпо между около дванадесет опции вместо двадесет и седем — затова се цитира perplexity, а не суровата загуба.
Две неща се объркват при него, а второто се обърква и в публикувани статии.
Нулевите вероятности са фатални. От 729 клетки в таблицата 113 никога не се срещат при обучението — 15.5 % от нея е празна. Това е наред, докато отделеният набор не попадне в такава клетка, а седем bigrams във валидацията го правят, сред тях d→q, z→j и q→o два пъти. Вероятност нула означава log , което означава безкрайна загуба и безкрайна perplexity: едно име на три хиляди унищожава метриката. Обичайният пластир е да се добави 1 към всяко броене преди нормализиране, което тук почти не струва нищо (2.4546 вместо 2.4524). Но пластирът е признание. Моделът с броене изобщо не може да обобщава. Няма как да подозира, че q→o е правдоподобно, защото q→u е често, а o се държи като u на други места, понеже няма понятие, че два символа могат да си приличат. Всяка клетка се учи отделно и поправянето на това е смисълът на останалата част от тази глава.
Perplexity е цена на token, а token е свободен параметър. Това е грешката, която постоянно се появява при сравняване на модели, и се вижда лесно, щом погледнете. Вземете същия корпус от английска проза от Глава 7, същия интерполиран bigram модел, и променете само как се нарязва текстът:
| единица | речник | tokens в теста | крос-ентропия | perplexity | битове на символ |
|---|---|---|---|---|---|
| символи | 76 | 14,469 | 2.5217 | 12.45 | 3.6378 |
| BPE, 512 сливания | 329 | 6,871 | 3.8547 | 47.21 | 2.6407 |
| BPE, 2,048 сливания | 1,820 | 4,233 | 5.7468 | 313.20 | 2.4254 |
| думи | 2,991 | 6,284 | 3.5627 | 35.26 | 2.2322 |
Perplexity варира 25 пъти между тези редове. Нищо в модела не се е променило; промени се само размерът на нещото, което се предсказва. Предсказването на цяла дума е по-трудно от предсказването на буква, затова струва повече на предсказване — и има по-малко предсказвания за правене.
Сега прочетете последната колона, която вместо това дели общата цена на броя символи и я преобразува в битове. Тя пренарежда таблицата. По perplexity класацията е символи, думи, BPE-512, BPE-2048; по битове на символ тя е думи, BPE-2048, BPE-512, символи. Символният модел пада от първо на последно място. Моделът с 2,048 сливания, който по perplexity изглежда 6.6 пъти по-лош от този с 512 сливания, всъщност е по-добрият от двата — 2.4254 бита срещу 2.6407.
Затова perplexity е сравнима само между два модела, които споделят tokenizer, а модели с различни tokenizers могат да се сравняват само в битове на символ — величината, която Шанън измерва през 1951 г., като кара участници да отгатват следващата буква в английски текст, и която ограничава приблизително до един бит на символ.2 Най-добрият ни bigram е на 2.23 бита, което е честно обобщение на това колко път още има тази глава.
Същото нещо, научено
Връзка към раздела: Същото нещо, наученоСега изградете същия модел като мрежа. Ще са му нужни порядъци повече аритметика, за да стигне до същото място, а стигането до същото място е целият смисъл.
Заменете таблицата с една матрица от тегла с форма . Превърнете текущата буква в one-hot вектор, умножете и наречете резултата logits — ненормализираните оценки от Глава 4. После softmax, после крос-ентропия, после gradient descent.
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Маркираният ред съдържа дефиниция, която си струва да имате. Умножаването на one-hot вектор по матрица избира един неин ред, така че умножението е lookup — и всяка имплементация пропуска аритметиката и прави lookup директно, което е W[xs].
Това е embedding таблица. Матрица с по един ред за всеки елемент от речника, индексирана по token id. Без геометрия, без семантика, без отделен алгоритъм: lookup таблица, чието съдържание просто се учи чрез gradient descent заедно с всичко останало. Всяко мистично твърдение за „embedding space“ стига в основата си дотук.
Обучете я и вижте накъде отива:
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Последната колона е най-голямата абсолютна разлика между която и да е клетка на softmax(W) и съответстващата клетка от таблицата с брояния, и тя отива към нула. След 3,000 стъпки най-голямото разминаване където и да е сред 729-те клетки е 0.004048, а средното е 0.000224. Най-лошата клетка е q→i, видяна дванадесет пъти в целия обучителен набор; сред 22-та реда с повече от хиляда срещания най-лошото разминаване е 0.000562.
count table network
a -> '.' 0.1945 0.1945
a -> 'n' 0.1601 0.1601
a -> 'r' 0.0967 0.0967Gradient descent, започвайки от случайни числа и без да му е казано нищо освен „направи log-вероятността на следващата буква голяма“, преоткри таблицата с брояния. И трябваше: броянията са оценката по максимално правдоподобие, крос-ентропията е отрицателната log-likelihood, така че и двете процедури оптимизират една и съща цел, а тази цел има един оптимум. Мрежата не научи нещо подобно на броене. Тя конвергира към броене, бавно.
Това повдига справедливия въпрос защо изобщо някой би си направил труда. Защото таблицата с брояния няма накъде да отиде оттук, а мрежата има.
Context е тесният участък, не капацитетът
Връзка към раздела: Context е тесният участък, не капацитетътРазширете модела така, че да гледа повече от един предишен символ. Това е архитектурата на Бенжио от 2003 г., директният предшественик на всеки модел в останалата част от този курс:4 вземете последните три символа, прекарайте всеки през embedding таблица до 10-мерен ред, конкатенирайте редовете в 30 числа, прекарайте ги през скрития слой от Глава 5 и завършете с изходен слой, който произвежда по един logit за всеки елемент от речника.
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)Забележете кое е ново и кое не е. Скритият слой е този от Глава 5, без промяна; загубата е тази от Глава 4, без промяна. Новостите са embedding таблицата отпред и изходен слой, широк колкото речника от Глава 7 — а именно вторият е скъпата част на всеки езиков модел, строен някога, защото истинският речник има 100,000 елемента и това матрично умножение се изпълнява на всяка позиция.
Същият код, обучен по същия начин, като е променен само размерът на context window:
| context | параметри | валидационна загуба | валидационна perplexity |
|---|---|---|---|
| броене, 1 символ | 729 | 2.4546 | 11.642 |
| невронен, 1 символ | 7,897 | 2.4577 | 11.678 |
| невронен, 3 символа | 11,897 | 2.1145 | 8.285 |
| невронен, 8 символа | 21,897 | 2.0506 | 7.773 |
Вторият ред е интересният. Мрежа със скрит слой от 200 единици и единадесет пъти повече параметри от таблицата с брояния се представя точно толкова добре, колкото таблицата с брояния, и нито малко по-добре. Капацитетът никога не е бил ограничението. Един символ context позволява определена загуба и нищо, което добавите отгоре, не може да падне под нея, защото информацията не е там.
Дайте ѝ три символа и perplexity пада от 11.68 на 8.29 — намаление с 29 %, купено с 4,000 допълнителни параметра. Тук тя побеждава броенето точно по причината, диагностицирана по-рано: модел с броене върху трисимволни контексти се нуждае от реда, повечето от тях празни или с едно-единствено наблюдение, и учи всеки самостоятелно. Мрежата споделя. Ако a, e и i се окажат с подобни embedding редове, това, което научи след bra, се пренася към bre, без някога да е виждала bre. Този пренос е цялата стойност на embedding таблицата и той е разликата между редове две и три.
Пробите се подобряват съответно:
deliah nellara joce kael quintis
salayson reety khyrmin mahnen madiaryxiaВсе още не е списък с истински имена. Но deliah, nellara и kael не биха изглеждали неуместно в такъв, а чудовищата без край са изчезнали: най-дългото от двадесет проби от модела с броене е деветнадесет букви, най-дългото от двадесет от този модел е тринадесет.
Какво всъщност има вътре в embedding таблицата
Връзка към раздела: Какво всъщност има вътре в embedding таблицатаТаблицата е : по един ред от десет числа за всеки символ, всички инициализирани случайно и местени само от gradient на загубата за следващ символ. Никой не е сложил нищо вътре. И така, какво се е озовало там?
Инструментът за питане е косинусова близост, тоест скаларното произведение от Глава 1 с разделени дължини:
Тя измерва ъгъла между два вектора и игнорира дължините им, което е нужно, когато дължината на реда отразява колко често се е появявал неговият token, а не какво означава. Първо нормализирайте всеки вектор до дължина 1 — както правят реалните системи, веднъж, по време на индексиране — и косинусовата близост е просто скаларното произведение.
Ето най-близките съседи на няколко символа в обучената таблица:
'c' -> 'k':+0.598 'j' -> 'z':+0.650 'i' -> 'y':+0.541
'u' -> 'e':+0.482 'a' -> 'h':+0.367 '.' -> 'q':+0.077Част от това е, което фолклорът обещава. c и k са взаимозаменяеми в имена, както и i и y; j и z са редки, предимно начални съгласни, които се държат сходно. Граничният символ . не е близо до нищо — 0.077 до най-близката буква — защото е единственият символ, който маркира позиция, а не звук.
А част от това не е така. Най-близкият съсед на a е h, не друга гласна. Осреднено върху всички двойки:
mean cosine, vowel to vowel : +0.1889
mean cosine, consonant to consonant : +0.0765
mean cosine, vowel to consonant : -0.0042Гласните си приличат повече една на друга, отколкото на съгласните, и ефектът е реален, но малък. Тествано срещу 2,000 случайно избрани групи от пет букви, 58 от тези групи се отделят поне толкова чисто — разлика, значима на около . Значи е реална, но изобщо не прилича на ясния геометричен остров, който популярните разкази за embeddings внушават.
Това е честното описание на embedding таблица и си струва да го запазите за останалата част от курса. Тя не е карта на значение. Тя е смяна на координати, научена вместо проектирана, чиято единствена работа е да улесни работата на следващия слой — същото изречение, което Глава 5 използва за скрития слой, който сгъна равнината, за да реши XOR. Всяка структура, която намерите в нея, е там, защото е намалила загубата, а структура, която не намалява загубата, просто я няма.
word2vec, GloVe и аритметиката, която всички цитират
Връзка към раздела: word2vec, GloVe и аритметиката, която всички цитиратАко полезната част е таблицата, можете да преследвате директно нея. Това е word2vec: запазете embedding lookup, изхвърлете езиковия модел.5
Целта skip-gram with negative sampling е един ред. За реална двойка (център, context), извлечена от корпуса, бутнете скаларното им произведение нагоре; за фалшиви двойки, извлечени от шумово разпределение, бутнете го надолу:6
Това е бинарна класификация — „срещали ли са се тези две думи наистина заедно?“ — и е евтина точно защото никога не докосва целия речник, което направи практично обучението върху милиарди думи през 2013 г. GloVe стига до подобни вектори от другата посока, като факторизира матрицата на глобалните брояния на съвместни срещания, вместо да минава потоково през примери.7 И двете се напасват към точно статистиката, от която беше построена таблицата с брояния. Те са броене, компресирано.
Обучени върху text8 — 17,005,207 думи от английската Wikipedia, 71,290 от тях срещащи се поне пет пъти, 100 измерения, три преминавания — векторите излизат със свойството, което ги направи известни:
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Никой не е подал категория за инструменти или за числителни. Сега известната част: вземете king, извадете man, добавете woman и намерете най-близкия вектор до резултата.
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)Най-близкият вектор до king - man + woman е king. Това не е странност на един пример. Оценъчният набор на Миколов задава въпроси от формата a : b :: c : ? — 8,869 семантични (paris : france :: rome : italy) и 10,675 синтактични (walking : walked :: swimming : swam) — и сред 4,103 семантични въпроса, на които този речник може да отговори, победителят е една от трите входни думи 99.8 % от времето. Публикуваните демонстрации не го споменават, защото стандартното правило за оценяване изтрива a, b и c преди търсенето. Това е легитимно правило и то върши повече работа от аритметиката:
| как се избира отговорът | семантични | синтактични |
|---|---|---|
| offset, с изключени входове (стандартно) | 17.0 % | 11.9 % |
| offset, без нищо изключено | 0.1 % | 0.4 % |
най-близък съсед само на c, входове изключени | 13.1 % | 9.3 % |
най-близък съсед само на b, входове изключени | 2.3 % | 0.4 % |
Третият ред е този, с който трябва да поседите. Изхвърлете a и b, не правете никаква аритметика, върнете каквото е най-близо до c — и запазвате 77 % от семантичния резултат. Повечето от това, което изглежда като аналогично разсъждение, е близост плюс правило, което забранява очевидните отговори — точно това измери Линзен върху правилно обучени вектори и което базовите линии по-горе възпроизвеждат.8 Тези конкретни вектори са малки — 17 милиона думи срещу милиардите зад публикуваните модели — така че четете процентите като форма, не като state of the art. Формата е това, което оцелява при всеки мащаб: аритметиката е реална и далеч по-слаба от единствената демонстрация, която всички цитират.
Статични и контекстуални: един вектор на дума или един на срещане
Връзка към раздела: Статични и контекстуални: един вектор на дума или един на срещанеВсичко дотук има твърда граница, вградена в структурата на данните. Таблицата има един ред на token. Думата bank получава един вектор, същият в изречение за река и в изречение за ипотека — по необходимост, защото lookup по id не може да зависи от нищо друго.
Поправката е да спрете да четете вектора от таблицата и да започнете да го изчислявате от изречението. Това е contextual embedding, въведен от ELMo през 2018 г. и превърнат в стандарт от BERT същата година.910 Измерени върху реалния модел, числата са по-ясни от обяснението:
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Първият ред е точен, не приблизителен: статичният вектор за bank е същите 768 числа и в двете изречения, така че косинусът е 1 по конструкция. Девет слоя по-късно двете срещания са на 0.43, докато bank в две различни речни изречения остава на 0.87. Никой никъде не е етикетирал значение в този процес; значенията се разделиха, защото разделянето им прави обучителната цел — отгатване на скрит token от съседите му — по-лесна за удовлетворяване.
Две подробности заслужават внимание. Слой 0 вече е 0.9512, а не 1.0, защото са добавени positional embeddings и думата стои на различно място във всяко изречение. И близостта пак се покачва в слоеве 11 и 12: финалните слоеве на pretrained модел са специализирани към неговата обучителна цел и често не са най-доброто място, от което да вземете representation.
Покажи подробности
По избор: weight tying.
В bert-base-uncased embedding таблицата е — 23,440,896 числа, 21.4 % от 109,482,240-те параметъра на модела. В малък езиков модел делът е още по-голям, затова един трик е почти универсален: входната таблица и изходният слой, който произвежда logits, са една и съща матрица, използвана веднъж чрез lookup по редове и веднъж транспонирана.11 Изходният слой вече присвоява вектор на всеки елемент от речника — той взема скаларно произведение срещу всеки от тях — а tying казва, че векторът, използван за четене на token, и векторът, използван за писането му, трябва да са един и същ обект. Това едновременно намалява параметрите и подобрява perplexity, което е достатъчно рядко, за да се отбележи.
Embedding model не е езиков модел
Връзка към раздела: Embedding model не е езиков моделЗа да търсите в корпус по смисъл, ви трябва по един вектор за изречение. Щом ги имате, търсенето е тривиално — това е цялата semantic retrieval, а Глава 19 е за всичко около нея:
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]Така че единственият реален въпрос е откъде идва embed. Очевидният ход е да вземете pretrained езиков модел, да прекарате всяко изречение през него и да осредните token векторите. Ето този метод срещу четири алтернативи, оценени по два начина: ранговата корелация между косинусова близост и човешки оценки за сходство върху 1,379-те двойки от STS benchmark, и top-1 retrieval върху индекс, построен от 200-те най-силно парафразирани двойки — едната страна на всяка двойка е индексирана, другата се използва като query.
| как е embedded изречението | рангова корелация | top-1 върху индекс от 200 изречения |
|---|---|---|
| бинарно припокриване на думи (без модел изобщо) | 0.5500 | 89.0 % |
| средно на статичните вектори, обучени по-горе | 0.5263 | 85.5 % |
BERT, token [CLS] | 0.2030 | 67.0 % |
| BERT, средно на token вектори | 0.4729 | 84.0 % |
| MiniLM, обучен контрастивно | 0.8203 | 92.0 % |
Прочетете средните три реда спрямо първите два. Pretrained transformer със 109 милиона параметъра, използван по очевидния начин, е по-лош в оценяването на сходство между изречения, отколкото броенето на това колко думи споделят две изречения — и по-лош от осредняване на 100-мерните text8 вектори, обучени преди малко. Token [CLS], който уроците още препоръчват, защото BERT е бил pretrained с прикрепена към него цел на ниво изречение, е по-лош от половината от това.
Това не е дефект в BERT. Това е целта. Езиковият модел се обучава така, че неговите hidden states да предсказват token; нищо там не иска две парафрази да се окажат близо една до друга и нищо не възнаграждава геометрия, в която косинусът означава „същото значение“. Последният ред е модел с една пета от размера (22,713,216 параметъра), обучен върху напълно различна загуба: контрастивно обучение, при което примерите са двойки — въпрос и неговият отговор, изречение и неговата парафраза — а целта придърпва истинските двойки заедно и отблъсква sampled negatives. Това е приносът на Sentence-BERT и произходът на цялата индустрия на embedding model.12 Dense Passage Retrieval прилага същата рецепта директно към търсенето, с един encoder за заявки и един за пасажи.13
И така, практическото правило:
Embedding model не е езиков модел с премахнат последен слой. Това е различен модел с различна цел, обикновено много по-малък, чийто косинус означава това, което искате да означава, защото е обучен върху двойки, при които това е било target. Таблицата по-горе е цената на замяната на едното с другото.
И семейството се проваля при реда на думите. „The dog bit the man“ и „the man bit the dog“ имат идентични торби от думи, така че припокриването на думи и средното на статичните вектори им дават косинус точно 1.000000, а mean-pooled BERT, който все пак вижда позиция, пак стига почти дотам — и контрастивно обученият MiniLM все пак ги поставя на 0.979. Ако retrieval задачата ви зависи от това кой какво е направил на кого, никакъв косинусов праг няма да ви спаси.
Глава 19 изгражда production retrieval система върху тази основа и стига до конкретен косинусов праг. Последното измерване в тази глава е това, което прави такова число защитимо, а не магическо.
Проклятието на размерността в една таблица
Връзка към раздела: Проклятието на размерността в една таблицаРеалните embeddings имат стотици или хиляди компоненти, а разстоянията там горе се държат странно. Вземете 1,000 случайни точки в единичния куб с измерения и погледнете отношението между най-голямото и най-малкото разстояние между които и да е две от тях:
| измерения | най-близка двойка | най-далечна двойка | отношение |
|---|---|---|---|
| 2 | 0.0007 | 1.3612 | 1921.66 |
| 10 | 0.2361 | 2.3397 | 9.91 |
| 100 | 3.0047 | 5.1752 | 1.72 |
| 1,000 | 11.7809 | 14.0306 | 1.19 |
| 10,000 | 39.6152 | 42.0125 | 1.06 |
В десет хиляди измерения най-далечната двойка точки е само с 6 % по-далеч една от друга от най-близката двойка. Всичко е приблизително равноотдалечено от всичко останало, „най-близък съсед“ спира да носи много информация и това е проклятието на размерността — както и една причина големите векторни бази данни да не правят exact nearest-neighbour search. Другата страна на същата монета е това, което прави косинусовите прагове работещи: измерено върху хиляда двойки случайни единични вектори, средният косинус стои на в 100 измерения и в 768, със стандартни отклонения 0.0968 и 0.0357 — а в 768 измерения само 0.2 % от случайните двойки надвишават 0.1 по абсолютна стойност. Следователно измерена близост 0.4 не е „40 % сходни“; тя е далеч извън всичко, което случайността произвежда, затова праговете между 0.3 и 0.7 отделят сигнала от шума, вместо да стоят по средата му.
Накъде продължаваме
Връзка към раздела: Накъде продължавамеМоделът в тази глава чете фиксиран брой предишни символи, прави lookup на всеки от тях и слепва резултатите в ред. Този дизайн има два проблема, и те са един и същ проблем.
Погледнете отново таблицата за context: преминаването от три символа към осем почти удвои параметрите и купи 0.06 ната. Цената расте линейно с context — всяка допълнителна позиция се нуждае от собствен блок от първата матрица с тегла — а ползата не. Избутайте го до хиляда tokens и само първият слой тежи повече от останалата част на модела, като по-голямата част е изразходвана за позиции, които нямат значение за дадено предсказване.
Което е вторият проблем: моделът няма как да реши кои от предишните tokens имат значение. Позиция две получава свои тегла и позиция седем получава свои, завинаги, каквото и да има в тях. Когато моделът изписва nell, решаващият символ е този непосредствено преди него. Когато изречение съдържа местоимение, думата, която определя референта му, може да е четиридесет tokens назад — и на „четиридесет назад“ не може да се присвои фиксиран слот, защото следващия път ще бъде шест.
Това, което искаме, е модел, който изчислява за всяко предсказване колко трябва да тежи всеки по-ранен token — тегла върху context, произведени от съдържанието, а не фиксирани от оформлението. Запишете го внимателно и то започва като нещо съвсем обикновено: средно върху предишните tokens. После оставете теглата на това средно да се учат и да зависят от това кой token задава въпроса.
Това е attention и е Глава 9.
Източници и метод
Връзка към раздела: Източници и методСъщо си струва да четете паралелно: глава 3 от Speech and Language Processing на Jurafsky и Martin, която разглежда n-gram модели, изглаждане и perplexity много по-внимателно, отколкото има място тук, включително защо интерполацията и back-off побеждават добавянето на едно; бележките на Stanford CS229 §17.1–17.2 за езиково моделиране от вероятностната страна; и статията на Linzen по-горе, която е кратка и си струва да бъде прочетена изцяло.
Препратки
Връзка към раздела: Препратки-
Примерът за генериране на имена, наборът от данни и прогресията от таблица с брояния до мрежа в стил Бенжио следват поредицата building makemore на Andrej Karpathy, чиито първи две части са най-добрият спътник към тази глава. ↩
-
Shannon, C. E. Prediction and Entropy of Printed English. Bell System Technical Journal 30(1), pp. 50–64 (1951). Участници, които отгатват следващата буква в английски текст, и първоначалното измерване в битове на символ. ↩
-
Shannon, C. E. A Mathematical Theory of Communication. Bell System Technical Journal 27 (1948). Теоремата за кодиране на източник и отъждествяването на предсказването с компресията. ↩
-
Bengio, Y., Ducharme, R., Vincent, P. and Jauvin, C. A Neural Probabilistic Language Model. Journal of Machine Learning Research 3, pp. 1137–1155 (2003). Архитектурата, използвана по-горе: embedding на дума, конкатениран върху фиксиран прозорец, през скрит слой, до softmax върху речника. ↩
-
Mikolov, T., Chen, K., Corrado, G. and Dean, J. Efficient Estimation of Word Representations in Vector Space. arXiv:1301.3781 (2013). CBOW и skip-gram, както и наборът с аналогии, използван по-горе. ↩
-
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, subsampling на чести думи и шумовото разпределение, повдигнато на степен 3/4, използвано по-горе. ↩
-
Pennington, J., Socher, R. and Manning, C. GloVe: Global Vectors for Word Representation. EMNLP 2014. Вектори на думи от факторизация на глобалната матрица на съвместни срещания вместо от поточни локални прозорци. ↩
-
Linzen, T. Issues in evaluating semantic spaces using word analogies. RepEval 2016, arXiv:1606.07736. Източникът на offset-free базовите линии, възпроизведени по-горе. ↩
-
Peters, M. et al. Deep contextualized word representations. arXiv:1802.05365 (2018). ELMo: един вектор на срещане, изчислен от двупосочен езиков модел. ↩
-
Devlin, J., Chang, M.-W., Lee, K. and Toutanova, K. BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding. arXiv:1810.04805 (2018). Моделът, измерен в експеримента с bank. ↩
-
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). Два независими аргумента за един и същ трик. ↩
-
Reimers, N. and Gurevych, I. Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks. arXiv:1908.10084 (2019). Началното му измерване — mean-pooled BERT се представя по-слабо от осреднени статични вектори при сходство между изречения — е това, което таблицата по-горе възпроизвежда. ↩
-
Karpukhin, V. et al. Dense Passage Retrieval for Open-Domain Question Answering. arXiv:2004.04906 (2020). Контрастивно обучение на retriever с два encoder-а; директният предшественик на retrieval стека от Глава 19. ↩