本文へスキップ
ひもとくAI

ミニプロジェクト:Self-Attention を自分で作る

レッスン 7/7

ミニプロジェクト:Self-Attention を自分で作る

Transformer の心臓部である、マスク付きの Self-Attention を、NumPy だけで作ります。

作るもの

入力は、3つの単語の埋め込みベクトル(それぞれ2個の数)を並べた表 XX(3行 × 2列)です。

  1. Q=XWQQ = X W_Q、K=XWKK = X W_K、V=XWVV = X W_V で、クエリ・キー・バリューを作る
  2. QK⊤d\frac{Q K^{\top}}{\sqrt{d}} で、すべての単語の組み合わせの点数の表(3行 × 3列)を作る
  3. (マスクありのとき)自分より後ろの位置の点数を −∞-\infty にする
  4. 表の 行ごと にソフトマックスをとり、注目の重みにする
  5. 注目の重み @ VV で、各単語が取り出す情報を計算する

マスクの表

np.tril は、行列の左下(対角線を含む)だけを残す関数です。3単語なら、次の表の True(○)の位置だけを使います。

1語目を見る2語目を見る3語目を見る
1語目○××
2語目○○×
3語目○○○

np.where(mask, scores, -np.inf) で、× の位置の点数を −∞-\infty にします。e−∞=0e^{-\infty} = 0 なので、その位置の重みは0になります。

行ごとのソフトマックス

点数の表は3行あり、各行が「その単語が、ほかのどの単語に注目するか」です。そのため、ソフトマックスは 行ごと に計算します。NumPy では、axis=1(横方向)に計算し、keepdims=True で形を保ったまま割ります。

e = np.exp(scores - scores.max(axis=1, keepdims=True))   # 行ごとに最大値を引く
w = e / e.sum(axis=1, keepdims=True)                      # 行ごとの合計で割る → 各行の合計が1

keepdims=True がないと、行ごとの合計が「3個の数の列」ではなく「3個の数の並び」になり、割り算の向きがずれてしまいます(第11章のミニプロジェクトのブロードキャストと同じ注意です)。

実行の結果(演習の例)

マスクなしの注目の重みマスクありの注目の重み
1語目0.401・0.198・0.4011.000・0・0
2語目0.164・0.164・0.6730.5・0.5・0
3語目0.178・0.088・0.7340.178・0.088・0.734

マスクありでは、1語目は自分だけに、2語目は1語目と自分だけに注目しています。3語目は、もともと全部の単語が「自分より前か自分」なので、マスクの有無で変わりません。どの行も、合計は1です。

この章の振り返り:前の情報を、どう使うか

PyTorch と比べて確かめる

演習で作る関数は、PyTorch の F.scaled_dot_product_attention と同じ計算です。運営側で、でたらめなクエリ・キー・バリューを使って、マスクあり・なしの両方で、NumPy の結果と PyTorch の結果が一致することを確かめています。実際の Transformer では、この計算を、ヘッドの数だけ並べ(マルチヘッド)、何段も重ねています。

モデルの比べ方

モデル前の情報の使い方得意なこと弱点
RNN隠れ状態に、順番にまとめて渡す仕組みが単純。短い系列長い系列で勾配が消えたり爆発したりする。順番にしか計算できない
LSTM・GRUゲートで、覚える・忘れる・出すを調節するRNN より長い系列設定しだいで学習が難しい。順番にしか計算できない
seq2seq + Attentionデコーダが、入力のどこに注目するかを決める翻訳・要約RNN の部分は順番にしか計算できない
TransformerSelf-Attention で、全部の位置を同時に見る長い文脈、大量のデータでの学習、並べての計算系列の長さの2乗に比例して計算が増える

この章の振り返り

  1. 系列データと単語の表し方: 順番に意味があるデータ。one-hot と埋め込み、分布仮説、word2vec
  2. RNN: 隠れ状態 ht=tanh⁡(xtWx+ht−1Wh+b)h_t = \tanh(x_t W_x + h_{t-1} W_h + b)、同じ重みの繰り返し、BPTT。単純な方法(ベースライン)と比べる
  3. 勾配消失と LSTM・GRU: さかのぼるほど勾配が小さくなる(大きくなる)。ゲートとセル、勾配クリッピング
  4. seq2seq と Attention: エンコーダ・デコーダ、Teacher forcing。内積 → ソフトマックス → 重み付きの平均
  5. Transformer: Self-Attention、d\sqrt{d} で割る理由、マルチヘッド、位置エンコーディング、マスク、残差接続と層正規化。BERT と GPT
  6. 言語モデル: 次の単語の予測、パープレキシティ、温度。大規模言語モデルの注意点
  7. Self-Attention を自分で作る: 行ごとのソフトマックスと、因果マスク

第5章で学んだ「確率を予測して、交差エントロピーで学習する」という考え方は、画像の CNN から、今の大規模言語モデルまで、同じように使われています。

演習

演習を読み込んでいます…