機械学習エンジニアのためのTransformers
---
Transformersがここまで普及した理由は、その性能だけでなく、使いやすいライブラリがあったことに起因するのは間違いないでしょう。そのライブラリこそまさに本書のタイトルにもあるTransformersです。Transformersを利用することで、機械学習エンジニアは事前学習済みモデルを利用した学習を簡単にできるようになりました。それに加えて、学習したモデルを共有することも容易にできることが、研究から実用までのサイクルがこれまでとは桁違いに早くなった要因と言えるでしょう p3
エンコーダの仕事は、入力系列から与えられる情報を、最後の隠れ状態(last hidden state)と呼ばれる数値表現にエンコードすることです 分類タスク等のHeadに差し込まれる前の出力
p8
出現済みの単語を元に次の単語を予測するタスクを学習します。このタスクは言語モデルと呼ばれています。 言語体系自体をモデリングしたものが言語モデルであり、教師無しの事前学習で行われる(言語体系の関係性を捉えるわけなので)
Transformerじゃなくても実現できる
p30
最大コンテキストサイズと呼ばれる最大入力系列長があります。
p33
テキスト文字列→トークン化→各トークンにID割り当て→IDはone-hotベクトル化 p37
tokenizer.vocab_sizeで語彙数。one-hotベクトルは語彙数の長さと一致する?→ Yes tokenizer.model_max_lengthで最大コンテキストサイズ
p40
トークンエンコーディング:テキストをトークン分割しone-hotベクトルの系列に変換する 各one-hotベクトルは自分のトークンにのみ1が立つので語彙の大きさがベクトルの大きさと一致する トークン埋め込み:大きなone-hotベクトルそれぞれをトークン埋め込みに変換する これがEncoderに渡され隠れ層に変換され、Headによってタスクが実行される p41
特徴抽出器として使う場合、ボディの重みを凍結してその後回帰とかに繋げば良い
p43
p44
CLSトークン、つまり文字列の先頭に相当する隠れ層のみを分類タスクに使うので取り出している (1, 6, 768)を(1, 768)に変換(6はトークン数)
なぜCLSを使うと分類問題を学習できるのか、というのは論理が逆になっている気がするmiyamonz.icon
とにかく
特殊なCLSトークンを作り、
先頭をこれで確保して、
それを分類問題用のレイヤに接続して学習を回したから、
その部分が分類問題に使えるようになっただけ、とも言える
p45-46
隠れ層768次元を可視化。UMAPを使って2次元に射影。Transfomer出力の可視化! 感情が分類できている(ようにみえる)
この何とも言えない分離できてそうな出力を回帰モデルに突っ込んだりとか、何かしらのモデルに入れ込むことで分類ができる
p50
ただし分類Headがデフォで付いていないモデルだとランダムでHead部分が初期化される
p64
Embeddingベクトルの長さはBERTなら768次元。これが隠れ状態の出力それぞれと一致する 768×トークン長で投げ込む
マルチヘッドアテンションとFFNNの組み合わせで構成
例えばAppleという言葉がKeynoteやPhoneの近くに登場すると「より会社らしい表現 = ベクトル」に更新されるイメージ
p65
セルフアテンション、Attentionのお気持ちが分かった。BERTの場合、「私は日本人です」という文字列をTokenizerに入れると例えば(8,768)のテンソルになる(8はトークン長)。これをBERTに入れると(8,768)のテンソルを吐く。同じく「私はお寿司が好きなアメリカ人です」は例えば(13,768)に変換され、BERTにて(13,768)のテンソルを吐く。つまり、768次元のEmbeddingを768次元のEmbeddingにして吐くというこの構造が大事。8とか13とかの長さは関係なくて、一緒に入力された別のベクトル(=トークン)との関係を捉えて、「私」というEmbeddingは文脈を捉えたEmbeddingに変換される。各Embedding自体に文脈を捉えさせるというこの構造への理解が重要(当初語彙数に応じて語彙同士の繋がりを学習すると思っていたので) NNは次元数を理解できたら強い
p66
スケール化ドット積アテンション
いわゆるQKV。各Embedding(ベクトル)をQKVというベクトルに射影する
p67
BertVizはTransformerのアテンションを様々な面で可視化するために使える関数を提供 ここの可視化すごく分かりやすい。QKのそれぞれのベクトルを作り、ドット積を取るのでスカラーが出る。このスカラーが系列長seq_lenの個数だけある(正確には組み合わせなのでseq_len × seq_len。この行列がアテンションスコア)。このそれぞれの値をVと掛け算する。ドット積は関連度の強さになっているので、これをVに掛けることで関係を強められる。これもEmbedding自体に関係性を内在させる処理 Q、K、V:それぞれseq_len, head_dim
ドット積:seq_len, seq_len
ドット積の大きさの組み合わせで単語間の関連度が分かるってスンポー
p72
実際には各QKVはそのままベクトル化するのではなくNNをかませる
で、同一層にQKVは複数準備する(マルチヘッドアテンション)
NNの出力次元はアテンションヘッドの数で割るのが一般的
BERTであれば768次元あり、ヘッドが12個あるので768/12=64
p73にも連結する実装あり
p76
レイヤー正規化
平均0、分散1に変更
スキップ接続
処理せずに流す
p81
エンコーダ・デコーダアテンションがあるのでセルフアテンションという言葉の意味がわかる
p83
次の単語の予測はムズイ。でも全文を知ってるEncoderくんにヒントもらう
p84
Encoder系はNLP系のタスク。それこそ分類とかマスクとか要約とか
Decoderはテキスト生成
p131
ほかの自己回帰言語モデル(autoregressive)または因果的言語モデル(causal language model)と同様に、GPT-2はテキストに出現するトークン列y=y1,y2,...ytの確率P(y|x)を推定するように事前学習されます。 generate等もついてるっぽい
与えた初期プロンプト + 今までに登場したトークン列を与えた状態での条件付き確率
どうやって次のトークンを採用するか?
貪欲法:語彙全体を見て最もlogitsが高い語彙を採用 系列を出し切ることで確率の積で比較できる(同時確率)
p141
サンプリング
貪欲法やビームサーチと同様に次のトークンの選定をどうするか?
貪欲法やビームサーチは決定論的だが、確率的に揺らがせるのがサンプリング
サンプリングの方が人間的なゆらぎを与えることができる
top-kとかはサンプリングする集団を絞る手法。全語彙じゃなくて確率の高い集団からのみサンプリングする
ありえない単語も中には含まれる。ロングテールをカットする
p192
Retrieverにはスパースと密なタイプがある。単語の頻度を用いて各文書とクエリをスパースなベクトルにするのと、Encoderとか使うの
前者がTF-IDF、後者がEmbedding