Next-Token Prediction:embeddingとperplexityの意味
32,033件の名前で文字モデルを訓練し、gradient descentがカウント表を小数4桁まで再発見する様子と、perplexityが一致しにくい理由を解説。
このページの内容
ここに、単語を一度も見たことがないプログラムが生成した10個の名前があります。
cexze momakurailezitynn konimittain llayn ka
da moliellavo emia sade ftlspどれも名前ではありません。けれど、ほとんどすべてが名前になろうとしています。発音できそうで、名前が終わるところで終わっており、そのうち1つ — emia — は実在する名前まであと1文字です。それらを生成したプログラムは729個の数値を持ち、単語も、音節も、人も理解しておらず、隣り合う文字のペアを1回数え上げるだけで当てはめられました。
この章の終わりまでに、neural networkは同じ測定値でそのプログラムのスコアを3分の1削ります。見届ける価値があるのは、networkが最初に何をするかです。networkは、promptなしに、十分なデータがあるすべての行でカウント表を小数3桁まで再現します。なぜなら、その2つの対象は同じ問いへの答えだからです。その後に起きることはすべて、単なるカウントには決してできなかったことです。
目的関数は設計上の選択ではなく恒等式です
セクション「目的関数は設計上の選択ではなく恒等式です」へのリンク第7章では、整数の列と、ある整数の次に別の整数が来る理由のなさが残りました。ここでその理由が出てきます。そしてそれは第2章の1行です。
language modelとは、これまでのtokensを受け取り、次に来るtokenの分布を返す関数です。vocabularyの各項目に1つの数値があり、非負で、合計は1になります。それ以外ではありません。そこから文書全体の確率へ行くには、確率の連鎖律を適用します。
これは恒等式です。どんなもののどんな列にも成り立ち、追加の仮定はありません。つまり、小さな仕事 — 前のものが与えられたとき次のtokenを予測すること — をするモデルは、すでに、あり得るすべての文書へ確率を割り当てるという大きな仕事を、正確に、しかもただで終えています。これを安いトリックとして語るよくある見方(「次の単語を予測しているだけ」)は、論理が逆です。次のtokenを予測することこそが同時分布をモデル化することです。やるべき2つ目のことなど、最初からありませんでした。
lossも同じように機械的に従います。各位置でモデルは分布 を出し、真値は既知の単一tokenなので、第4章のcross-entropyがそのまま適用されます。
これは平均negative log-likelihoodです。第2章の手順で、Gaussianが入っていた場所にcategorical distributionを入れただけです。そして真の分布はone-hotなので、そのentropyはゼロです。したがって第4章の恒等式により、cross-entropyはKL divergenceそのものになります。この数値を下げることと、モデルの信念をデータへ近づけることは、同じ行為です。
1つの帰結は、独立した文として述べる価値があります。分野全体の下にある経済的事実だからです。ラベルは、データを1位置ずらしたものです。 誰も何も注釈しません。1兆tokensのテキストは、1兆個の事前ラベル付き例です。だから現代モデルのtraining corpusは「インターネット」であり、「誰かが作ったdataset」ではないのです。
正直なbaseline:数える
セクション「正直なbaseline:数える」へのリンクnetworkの前にbaselineです。32,033件の名前が1行に1つずつあり、そこから1文字ずつ、もっと名前を生成する仕事です。1
vocabularyは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行の算術でモデルは当てはめられます。そしてこれはheuristicではありません。countを行合計で割ることは、categorical distributionに対するmaximum-likelihood estimateであり、第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そこからsampleします。現在の文字の行から次の文字を選び、その行へ移り、境界記号が出るまで繰り返します。すると、この章の冒頭にあった名前が得られます。それらは特定の、そして情報量のある失敗をしています。局所的にはもっともらしく、全体としては意味不明です。momakurailezitynn の隣り合う文字ペアはどれも実在の名前に出てくるペアです。ただ、それが17個も連続しているだけです。モデルの記憶は1文字分なので、自分が長く続けすぎていることを知るすべがありません。
perplexityと、その読み方
セクション「perplexityと、その読み方」へのリンクheld-outの名前に対するlossは2.4546 natsです。この数値だけでは何も意味しません。だからperplexityがあります。
libraryに作業をさせず、書き下すとこうです。
@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()) 指数を取ると対数が取り消され、数値はものを数える単位へ戻ります。それが何を数えているかを見る一番きれいな方法は、何も知らないモデルを測ることです。contextに関係なく、すべての記号へ確率 を割り当てるモデルです。
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なら、「何も分からない、何でもあり得る」という意味です。countモデルの11.642は、1文字のcontextによって、不確実性が27択ではなく約12択から盲目的に選ぶ程度まで下がったことを意味します。だからperplexityは引用され、生のlossは引用されないのです。
これには2つの問題が起きます。そして2つ目は論文でも起きます。
ゼロ確率は致命的です。 表の729セルのうち、113セルはtrainingに一度も現れません。表の15.5 %が空です。held-out setがそこに着地するまでは、それでも構いません。そしてvalidationでは7個のbigramsがそうなります。その中には d→q、z→j、そして2回出る q→o があります。確率ゼロはlog を意味し、それは無限lossと無限perplexityを意味します。3,000件に1件の名前がmetricを破壊します。よくある応急処置は、正規化前にすべてのcountへ1を足すことです。ここではほとんどコストがありません(2.4524ではなく2.4546)。しかしこの処置は告白でもあります。countモデルはまったくgeneraliseできません。 q→o がもっともらしいと疑う方法がありません。q→u が一般的で、o が他の場所で u のように振る舞うから、という発想を持てないのです。2つの記号が似ているという概念がないからです。各セルは単独で学習されます。それを直すことが、この章の残りの目的です。
perplexityはtokenあたりの価格であり、tokenは自由パラメータです。 これはモデル比較で常に見かける誤りで、実際に見ると簡単に分かります。第7章と同じ英語散文corpus、同じ補間bigramモデルを取り、テキストの切り方だけを変えます。
| unit | vocabulary | tokens in test | cross-entropy | perplexity | bits per character |
|---|---|---|---|---|---|
| characters | 76 | 14,469 | 2.5217 | 12.45 | 3.6378 |
| BPE, 512 merges | 329 | 6,871 | 3.8547 | 47.21 | 2.6407 |
| BPE, 2,048 merges | 1,820 | 4,233 | 5.7468 | 313.20 | 2.4254 |
| words | 2,991 | 6,284 | 3.5627 | 35.26 | 2.2322 |
perplexityはこれらの行の間で25倍変わります。モデルについては何も変わっていません。予測されるものの大きさだけが変わっています。単語全体を予測するのは文字を予測するより難しいので、1回の予測あたりのコストは高くなります。そして行う予測の回数は少なくなります。
では最後の列を読んでください。こちらは総コストを文字の数で割り、bitsに変換しています。これにより表の順位が入れ替わります。 perplexityでは順位はcharacters、words、BPE-512、BPE-2048です。bits per characterではwords、BPE-2048、BPE-512、charactersです。characterモデルは1位から最下位になります。perplexityでは512-mergeモデルより6.6倍悪く見える2,048-mergeモデルは、実際には2.6407に対して2.4254 bitsで、2つのうち良い方です。
したがってperplexityは、同じtokenizerを共有する2つのモデル間でしか比較できません。tokenizerが異なるモデルは、bits per characterでしか比較できません。これは、Shannonが1951年に人間の被験者へ英語テキストの次の文字を推測させて測定し、およそ1 bit per characterを上限とした量です。2 私たちの最良のbigramは2.23 bitsに位置しており、この章がまだどれだけ先へ進む必要があるかを要約するには十分です。
同じものを、学習で得る
セクション「同じものを、学習で得る」へのリンク次に、同じモデルをnetworkとして作ります。同じ場所へ到達するために桁違いに多くの算術を使います。そして、同じ場所へ到達すること自体が重要です。
表を、形状 の1つのweight matrix で置き換えます。現在の文字をone-hot vectorにし、掛け算し、その結果をlogits — 第4章の未正規化スコア — と呼びます。次にsoftmax、次にcross-entropy、次に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 vectorにmatrixを掛けると、そのmatrixの1行が選ばれます。つまり、この掛け算はlookupです。そしてすべての実装は算術を省き、直接lookupを行います。それが W[xs] です。
これがembedding tableです。 vocabularyの各項目に1行を持ち、token idでindexされるmatrixです。幾何も、意味論も、別のalgorithmもありません。中身がたまたま他のすべてと一緒にgradient descentで学習されるlookup tableです。「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) の任意のセルと、count tableの対応するセルとの最大絶対差です。そしてそれはゼロへ向かいます。3,000 steps後、729セルのどこを見ても最大の不一致は0.004048で、平均は0.000224です。最悪のセルは q→i で、training set全体で12回だけ見られたものです。1,000回を超える出現を持つ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-probabilityを大きくせよ」とだけ言われて、カウント表を再発見しました。そしてそうならざるを得ませんでした。countsはmaximum-likelihood estimateであり、cross-entropyはnegative log-likelihoodなので、2つの手順は同じ目的関数を最適化しており、その目的関数には1つのoptimumがあります。networkはカウントに似たものを学んだのではありません。ゆっくりと、カウントへ収束したのです。
すると、なぜそんなことをするのかという当然の疑問が出ます。count tableはここから先へ進む場所がありませんが、networkにはあるからです。
ボトルネックは容量ではなくcontextです
セクション「ボトルネックは容量ではなくcontextです」へのリンクモデルを拡張し、直前の1文字だけでなく、複数の過去文字を見るようにします。これはBengioの2003年のarchitectureで、このコースの残りに出てくるすべてのモデルの直接の祖先です。4 直前3文字を取り、それぞれをembedding tableで10次元の行へ写し、行を連結して30個の数値にし、第5章のhidden layerに通し、最後にvocabularyの各項目につき1つのlogitを出すoutput layerで終えます。
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)何が新しく、何が新しくないかに注目してください。hidden layerは第5章のものそのままです。lossは第4章のものそのままです。新しいのは前段のembedding tableと、第7章のvocabularyと同じ幅を持つoutput layerです。そして2つ目こそ、これまで作られたすべてのlanguage modelで高価な部分です。現実のvocabularyには100,000項目があり、このmatrix multiplyはすべての位置で走るからです。
同じcodeを、同じように訓練し、context windowのサイズだけを変えます。
| context | parameters | validation loss | validation perplexity |
|---|---|---|---|
| counting, 1 character | 729 | 2.4546 | 11.642 |
| neural, 1 character | 7,897 | 2.4577 | 11.678 |
| neural, 3 characters | 11,897 | 2.1145 | 8.285 |
| neural, 8 characters | 21,897 | 2.0506 | 7.773 |
興味深いのは2行目です。200-unitのhidden layerを持ち、count tableの11倍ものparametersを持つnetworkが、count tableとまったく同じくらいで、それ以上ではない性能を出しています。制約は容量ではありませんでした。1文字のcontextが許すlossには限界があり、何を継ぎ足してもそれを下回れません。情報がそこにないからです。
3文字を与えると、perplexityは11.68から8.29へ落ちます。29 %の削減で、4,000個の追加parametersによって買われています。ここでcountingを上回る理由は、前に診断したものそのものです。3文字context上のcountモデルは 行を必要とし、その大半は空か、単一の観測しか持ちません。そしてそれぞれを単独で学習します。networkは共有します。もし a、e、i が似たembedding行になるなら、bra の後で学んだことは、bre を見たことが一度もなくても bre へ移ります。この転移こそがembedding tableの価値全体であり、2行目と3行目の差です。
samplesもそれに応じて改善します。
deliah nellara joce kael quintis
salayson reety khyrmin mahnen madiaryxiaまだ実在の名前リストではありません。しかし deliah、nellara、kael は、そのリストにあっても場違いには見えないでしょう。そして延々と続く怪物は消えました。countモデルの20 samplesで最長は19文字、このモデルの20 samplesで最長は13文字です。
embedding tableの中には実際に何があるのか
セクション「embedding tableの中には実際に何があるのか」へのリンク表は です。各文字につき10個の数値からなる1行があり、すべてランダムに初期化され、次文字lossのgradientだけで動かされました。誰もそこに何かを入れていません。では、そこに何が入ったのでしょうか。
それを問うtoolがcosine similarityです。これは第1章のdot productから長さを割り除いたものです。
2つのvectorsの角度を測り、長さを無視します。これは、ある行の長さが、そのtokenがどれだけ頻繁に現れたかを反映し、意味ではない場合に望むものです。まずすべてのvectorを長さ1へ正規化します — 実際のsystemがindexing時に一度行うように — するとcosine similarityは単なるdot productになります。
訓練済み表で、いくつかの文字のnearest neighboursを示します。
'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 のnearest neighbourは、別の母音ではなく**h**です。すべてのペアで平均するとこうです。
mean cosine, vowel to vowel : +0.1889
mean cosine, consonant to consonant : +0.0765
mean cosine, vowel to consonant : -0.0042母音同士は、子音と比べるより互いに似ています。その効果は実在しますが小さいです。ランダムに選んだ5文字のgroupを2,000個使って検定すると、それらのgroupのうち58個は少なくとも同じくらいきれいに分離します — およそ で有意な差です。つまり実在はしますが、embeddingに関する一般的な説明が示唆するような、くっきりした幾何的な島とはまったく違います。
これがembedding tableの正直な説明であり、このコースの残りを通じて持ち続ける価値があります。それは意味の地図ではありません。設計ではなく学習された座標変換であり、その唯一の仕事は次のlayerの仕事を簡単にすることです。これは、XORを解くために平面を折り畳んだhidden layerについて第5章で使った文と同じです。そこに見つかる構造は、lossを下げたからそこにあります。lossを下げない構造は、単に存在しません。
word2vec、GloVe、そして誰もが引用する算術
セクション「word2vec、GloVe、そして誰もが引用する算術」へのリンク有用な部分が表なら、それを直接狙えます。それがword2vecです。embedding lookupは残し、language modelは捨てます。5
skip-gram with negative samplingの目的関数は1行です。corpusから取った本物の(中心語、context)ペアについてはdot productを上げ、noise distributionから取った 個の偽ペアについては下げます。6
これはbinary classificationです。「この2つの単語は本当に一緒に現れたか?」という問題です。そして安いのは、full vocabularyに一度も触れないからです。だから2013年に数十億語でのtrainingが実用的になりました。GloVeは反対側から似たvectorsへ到達します。examplesをstreamする代わりに、global co-occurrence countsのmatrixをfactoriseするのです。7 どちらも、count tableが作られたのとまったく同じ統計量に当てはめられています。それらは、圧縮されたcountingです。
text8 — English Wikipediaの17,005,207 words、そのうち少なくとも5回出現する71,290語、100 dimensions、3 passes — で訓練すると、vectorsにはそれらを有名にした性質が現れます。
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誰も楽器や数詞のcategoryを与えていません。では有名な部分です。king を取り、man を引き、woman を足し、その結果に最も近いvectorを探します。
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 に最も近いvectorは**kingです。これは1つの例の癖ではありません。Mikolovの評価setは a : b :: c : ? という形式の問題を出します。8,869個のsemantic問題(paris : france :: rome : italy)と10,675個のsyntactic問題(walking : walked :: swimming : swam)です。そしてこのvocabularyが答えられる4,103個のsemantic問題全体で、勝者は入力3語のうちの1つであることが99.8 %**あります。公開デモはそれに触れません。なぜなら標準の採点規則は、探す前に a、b、c を削除するからです。それは正当な規則です。そしてその規則は、算術よりも多くの仕事をしています。
| how the answer is chosen | semantic | syntactic |
|---|---|---|
| offset, with the inputs excluded (standard) | 17.0 % | 11.9 % |
| offset, with nothing excluded | 0.1 % | 0.4 % |
nearest neighbour of c alone, inputs excluded | 13.1 % | 9.3 % |
nearest neighbour of b alone, inputs excluded | 2.3 % | 0.4 % |
じっくり見るべきは3行目です。a と b を捨て、算術を一切せず、c に最も近いものを返す。それだけでsemantic scoreの77 %が残ります。analogical reasoningのように見えるものの大半は、近さと、明らかな答えを禁じる規則です。これはLinzenが適切に訓練されたvectorsで測定したことであり、上のbaselinesが再現していることです。8 これらの特定のvectorsは小規模です。公開モデルの背後にある数十億語に対して1,700万語なので、percentagesはstate of the artではなく形として読んでください。その形はあらゆるscaleで残ります。算術は実在します。そして、誰もが引用する1つのデモよりずっと弱いのです。
Staticとcontextual:単語ごとに1 vectorか、出現ごとに1 vectorか
セクション「Staticとcontextual:単語ごとに1 vectorか、出現ごとに1 vectorか」へのリンクここまでのすべてには、data structureに組み込まれた厳しい限界があります。表にはtokenごとに1行があります。 bankという単語には1つのvectorが与えられます。川についての文でも、mortgageについての文でも同じvectorです。idによるlookupは、それ以外に依存できないので、必然的にそうなります。
解決策は、表からvectorを読み出すのをやめ、文からそれを計算し始めることです。これがcontextual embeddingです。2018年にELMoで導入され、同じ年に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のstatic vectorは両方の文で同じ768個の数値なので、cosineは構成上1です。9 layers後には2つの出現は0.43に位置し、一方で2つの異なる川の文に出るbankは0.87のままです。この過程のどこにも語義ラベルはありません。語義が分かれたのは、それらを分ける方がtraining objective — neighboursから隠されたtokenを推測すること — を満たしやすくするからです。
2つのdetailは注意に値します。Layer 0はすでに1.0ではなく0.9512です。position embeddingsが加えられ、単語が各文で異なる位置にあるからです。そしてsimilarityはlayers 11と12で再び上昇します。pretrained modelのfinal layersはtraining objectiveに特化しており、representationを取り出す最良の場所ではないことが多いのです。
詳細を表示
任意:weight tying。
bert-base-uncased ではembedding tableは — 23,440,896個の数値で、**モデルの109,482,240 parametersの21.4 %**です。小さなlanguage modelでは、この割合はさらに大きくなります。だから、ほぼ普遍的なtrickがあります。入力tableと、logitsを生成するoutput layerを同じmatrixにするのです。一度は行lookupとして使い、もう一度は転置して使います。output layerはすでにvocabularyの各項目へvectorを割り当てています。各項目とのdot productを取るからです。tyingは、tokenを読むために使うvectorと、それを書くために使うvectorを同じobjectにすべきだと言います。parametersを減らし、同時にperplexityを改善します。これは気づくに値するほど珍しいことです。
embedding modelはlanguage modelではありません
セクション「embedding modelはlanguage modelではありません」へのリンク意味でcorpusを検索するには、文ごとに1つのvectorが必要です。それらが与えられれば検索は単純です。これが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 language modelを取り、各文を通し、token vectorsを平均することです。その方法を4つの代替案と比べます。採点は2通りです。STS benchmarkの1,379 pairsにおいてcosineと人間のsimilarity judgmentsのrank correlationを見る方法と、そのpairsのうち最も強いparaphrase 200組から作ったindexでtop-1 retrievalを見る方法です。各pairの一方をindexし、もう一方をqueryとして使います。
| how the sentence is embedded | rank correlation | top-1 on a 200-sentence index |
|---|---|---|
| binary word overlap (no model at all) | 0.5500 | 89.0 % |
| mean of the static vectors trained above | 0.5263 | 85.5 % |
BERT, the [CLS] token | 0.2030 | 67.0 % |
| BERT, mean of token vectors | 0.4729 | 84.0 % |
| MiniLM, trained contrastively | 0.8203 | 92.0 % |
中央の3行を最初の2行と比べて読んでください。109-million-parameterのpretrained transformerを明らかな方法で使うと、2つの文が共有する単語数を数えるよりも、文similarityの判断が下手です。そして少し前に訓練した100-dimensionalの text8 vectorsを平均するよりも悪いです。BERTには文levelの目的関数が付いてpretrainedされたため、tutorialでは今でも [CLS] tokenが推奨されることがありますが、それはその半分より悪いのです。
これはBERTの欠陥ではありません。目的関数の問題です。language modelは、そのhidden statesがtokenを予測するように訓練されます。そこには、2つのparaphrasesが互いに近くなることを求めるものも、cosineが「同じ意味」を表すgeometryに報酬を与えるものもありません。最後の行は、サイズが5分の1(22,713,216 parameters)のモデルで、まったく別のlossで訓練されています。contrastive learningです。examplesはpair — 質問とその答え、文とそのparaphrase — であり、目的関数は真のpairsを引き寄せ、sampled negativesを引き離します。これがSentence-BERTの貢献であり、embedding-model産業全体の起点です。11 Dense Passage Retrievalは同じrecipeを検索へ直接適用し、queries用とpassages用に1つずつencoderを持ちます。12
したがって実務上の規則はこうです。
embedding modelは、最後のlayerを取り除いたlanguage modelではありません。 それは別の目的関数上の別のモデルで、通常はずっと小さく、そのcosineが望む意味を持つのは、その意味がtargetであるpairs上で訓練されたからです。上の表は、一方をもう一方で代用したときのコストです。
そしてこのfamilyは語順に弱いです。 「The dog bit the man」と「the man bit the dog」はbag of wordsが同一なので、word overlapとstatic-vector平均はcosineが正確に1.000000になります。positionを見ているmean-pooled BERTでさえ、ほぼそこに着地します。そしてcontrastively trained MiniLMでさえ0.979に置きます。あなたのretrieval taskが、誰が誰に何をしたかに依存するなら、どんなcosine thresholdも救ってくれません。
第19章はこの土台の上にproduction retrieval systemを構築し、具体的なcosine cut-offへ到達します。この章の最後の測定は、そのような数値を魔法ではなく弁護可能なものにします。
次元の呪いを、1つの表で
セクション「次元の呪いを、1つの表で」へのリンク実際のembeddingsには数百から数千のcomponentsがあり、その空間では距離が奇妙に振る舞います。 次元のunit cubeに1,000個のrandom pointsを取り、そのうち任意の2点間の最大距離と最小距離の比を見ます。
| dimensions | nearest pair | farthest pair | ratio |
|---|---|---|---|
| 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 |
10,000次元では、最も遠い点のペアは最も近い点のペアより6 %しか離れていません。すべてがほぼ等距離になり、「nearest neighbour」はあまり情報を運ばなくなります。これが次元の呪いです。そして、大規模vector databasesがexact nearest-neighbour searchを行わない理由の1つでもあります。同じコインの裏側により、cosine thresholdsは実用になります。random unit vectorsのpairsを1,000組測ると、mean cosineは100次元で 、768次元で にあり、standard deviationsは0.0968と0.0357です。そして768次元では、random pairsのうち絶対値で0.1を超えるのは0.2 %だけです。したがって測定されたsimilarity 0.4は「40 %似ている」ではありません。偶然が生むものからはるかに外れた値です。だから0.3から0.7のthresholdsは、noiseの真ん中に座るのではなく、signalとnoiseを分けられるのです。
次はどこへ進むか
セクション「次はどこへ進むか」へのリンクこの章のモデルは、固定個数の過去文字を読み、それぞれをlookupし、結果を順番につなぎ合わせます。この設計には2つの問題があり、それらは同じ問題です。
context tableをもう一度見てください。3文字から8文字へ増やすとparametersはほぼ倍になり、得られたのは0.06 natsでした。コストはcontextに対して線形に増えます。追加位置ごとに最初のweight matrixの専用の塊が必要だからです。一方、benefitはそう増えません。これを1,000 tokensまで押し上げると、最初のlayerだけでモデルの残りを上回り、その大半は任意の予測にとって重要でない位置に費やされます。
これが2つ目の問題です。モデルには、以前のtokensのどれが重要かを決める方法がありません。位置2には位置2専用のweightsがあり、位置7には位置7専用のweightsがあり、それは中身が何であれ永久に固定です。モデルが nell を綴っているとき、決定的な文字は直前の1文字です。文に代名詞が含まれるとき、その指示対象を決める語は40 tokens前かもしれません。そして「40個前」に固定slotを割り当てることはできません。次回は6個前かもしれないからです。
私たちが欲しいのは、各予測について、それ以前の各tokenをどれだけ数えるべきかを計算するモデルです。layoutで固定されたものではなく、contentによって生成されるcontext上のweightsです。それを丁寧に書き下すと、始まりはまったく平凡なものになります。過去tokensの平均です。そこから、その平均のweightsを学習可能にし、weightsが、どのtokenが問いかけているかに依存するようにします。
それがattentionであり、第9章です。
Sources and method
セクション「Sources and method」へのリンク併せて読む価値があるもの:Jurafsky and MartinのSpeech and Language Processing第3章。n-gram models、smoothing、perplexityを、ここで扱う余地があるよりはるかに丁寧に説明しており、adding oneよりinterpolationとback-offが優れる理由も含みます。確率側からのlanguage modellingについてはStanford CS229 notes §17.1–17.2。そして上記のLinzenのpaperは短く、全文読む価値があります。
参考文献
セクション「参考文献」へのリンク-
名前生成の例、dataset、count tableからBengio-style networkへの進行は、Andrej Karpathyのbuilding makemoreシリーズに従っています。最初の2部はこの章の最良の伴走資料です。 ↩
-
Shannon, C. E. Prediction and Entropy of Printed English. Bell System Technical Journal 30(1), pp. 50–64 (1951). 人間の被験者による英語の次文字予測と、元のbits-per-character測定。 ↩
-
Shannon, C. E. A Mathematical Theory of Communication. Bell System Technical Journal 27 (1948). source coding theorem、および予測と圧縮の同一視。 ↩
-
Bengio, Y., Ducharme, R., Vincent, P. and Jauvin, C. A Neural Probabilistic Language Model. Journal of Machine Learning Research 3, pp. 1137–1155 (2003). 上で使ったarchitecture:単語ごとのembeddingを固定window上で連結し、hidden layerを通して、vocabulary上の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、および上で使ったanalogy set。 ↩
-
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乗されたnoise distribution。 ↩
-
Pennington, J., Socher, R. and Manning, C. GloVe: Global Vectors for Word Representation. EMNLP 2014. streamed local windowsの代わりにglobal co-occurrence matrixのfactorisationから得るword vectors。 ↩
-
Linzen, T. Issues in evaluating semantic spaces using word analogies. RepEval 2016, arXiv:1606.07736. 上で再現したoffset-free baselinesの出典。 ↩
-
Peters, M. et al. Deep contextualized word representations. arXiv:1802.05365 (2018). ELMo:bidirectional language modelによって計算される、出現ごとに1つのvector。 ↩
-
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実験で測定したモデル。 ↩
-
Reimers, N. and Gurevych, I. Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks. arXiv:1908.10084 (2019). 冒頭の測定 — sentence similarityにおいてmean-pooled BERTが平均static vectorsを下回ること — が、上の表で再現したものです。 ↩
-
Karpukhin, V. et al. Dense Passage Retrieval for Open-Domain Question Answering. arXiv:2004.04906 (2020). two-encoder retrieverのcontrastive training。第19章のretrieval stackの直接の祖先。 ↩