みんなのAI
機械学習AI論文
読み込み中…

学ぶ

🏅マイ実績

Ch.02

Transformer:位置エンコーディングとフィードフォワード

セルフアテンションはトークン同士の関係を捉えますが、文中の何番目かという順序情報は単体では弱いことがあります。そこでトランスフォーマーはトークン埋め込みに位置エンコーディング(PE)を足し、「どの位置の単語か」をモデルに伝えます。ブロック内で関係を混ぜたあと、フィードフォワード(FFN)が各トークン表現を深く更新します。本章では正弦・余弦型PEの直感、学習型位置埋め込みとの違い、FFNのトークンごとのMLP役割を初心者向けに整理します。

数式の読み方

ht(0)=xt+PE(t)h_t^{(0)} = x_t + PE(t)ht(0)​=xt​+PE(t) で、xtx_txt​ はトークン埋め込み、PE(t)PE(t)PE(t) は位置 ttt のベクトルです。内容と順番(何番目かを数にした情報)を足して入力を作ります。正弦・余弦PEは PE(t,2i)=sin⁡(t/100002i/d)PE(t,2i)=\sin(t/10000^{2i/d})PE(t,2i)=sin(t/100002i/d)、PE(t,2i+1)=cos⁡(t/100002i/d)PE(t,2i+1)=\cos(t/10000^{2i/d})PE(t,2i+1)=cos(t/100002i/d) の形で、複数の周波数 iii で位置を符号化します。ddd は dmodeld_{model}dmodel​、ttt はトークンインデックスです。FFN(h)=W2 σ(W1h+b1)+b2\mathrm{FFN}(h)=W_2\,\sigma(W_1 h+b_1)+b_2FFN(h)=W2​σ(W1​h+b1​)+b2​ で、σ\sigmaσ は非線形、W1W_1W1​ は dmodel→dffd_{model}\to d_{ff}dmodel​→dff​、W2W_2W2​ は dff→dmodeld_{ff}\to d_{model}dff​→dmodel​ です。重み共有(各位置で同じFFN)は汎化を助け、実装を簡単にします。
上
左から右に読み、各マスで 意味 と 何番目かを数にした情報(PE) を 足す。
下
本同士は 混ぜず、同じ計算ブロック(同じ重み・同じ演算)を 4 本が それぞれ 一度ずつ通ります。
論文ではこの計算ブロックを FFN と呼びます。

① 入力を作る →(中間は省略)→ ② 本ごとに同じFFN

①のあと
②が、同じブロックの中で順に進みます。
1ブロック内の順番
①→②
① まず 意味+順番(PE) を足して 入力を作ります。(間の注意は図では省略)
② そのあと 同じFFN を本ごとに一度ずつ通します。本同士は混ぜません。
① 意味と順の数(PE)を一つにまとめる
文の中で何番目の語かを数で書き留めるのに近いです。
A→B→C→D0番号意味+順の値Aの合成意味+順の値1番号意味+順の値Bの合成意味+順の値2番号意味+順の値Cの合成意味+順の値3番号意味+順の値Dの合成意味+順の値
↓② 同じ計算ブロックで一本ずつ整える(FFN)3本は混ぜず、同じ計算ブロックだけ通過本 1入力広い層非線形出力本 2入力広い層非線形出力本 3入力広い層非線形出力本 4入力広い層非線形出力
4本とも 同じ計算ブロック(W₁, W₂ 共有)
① 意味と順の数(PE)を一つにまとめる
文の中で何番目の語かを数で書き留めるのに近いです。
A→B0番号意味+順の値Aの合成意味+順の値1番号意味+順の値Bの合成意味+順の値C→D2番号意味+順の値Cの合成意味+順の値3番号意味+順の値Dの合成意味+順の値
↓② 同じ計算ブロックで一本ずつ整える(FFN)3本は混ぜず、同じ計算ブロックだけ通過本 1入力広い層非線形出力本 2入力広い層非線形出力本 3入力広い層非線形出力本 4入力広い層非線形出力
4本とも 同じ計算ブロック(W₁, W₂ 共有)
番号意味順の値計算ブロック(FFN)

トランスフォーマー: 位置エンコーディングとフィードフォワード

1. 概念: なぜ位置エンコーディングか
セルフアテンションは系列全体を見ますが、入力が埋め込みの並びだけだと先頭と末尾の区別が弱くなります。位置エンコーディングは各位置 ppp に長さ dmodeld_{model}dmodel​ のベクトル PE(p)PE(p)PE(p) を作り、埋め込みに足して順序を伝えます。
直感: 映画館の座席に列・番がないと迷います。PEは各トークン席に番号札を付けます。
数式: トークン埋め込みを xtx_txt​ とすると、多くの場合 ht(0)=xt+PE(t)h_t^{(0)} = x_t + PE(t)ht(0)​=xt​+PE(t) です。
応用: 翻訳・要約・QAでは語順が意味を変えるため、BERT/GPT 系は位置情報を必ず入れます。
2. 概念: 正弦・余弦 PE(時計のたとえ)
まず直感だけ: アナログ時計を想像してください。秒針は速く、分針は中くらい、時針はとてもゆっくり動きます。3本の針の向きの組み合わせで「今何時何分」が分かるように、文の何番目のトークンかも数字のパターンで区別しやすくします。針の回る速さが違うので、2つの時刻が近いか遠いか(相対距離)も読み取りやすくなります。正弦・余弦 PE も、遅い波と速い波をいくつも重ねて位置ごとに違うベクトルを作る発想に近いです。
もう一歩だけ: 古典的トランスフォーマーは、次元を分けて sin⁡\sinsin 型・対になる cos⁡\coscos 型の繰り返す(周期的な)値を入れ、複数の周波数帯で近い位置と遠い位置を分けやすくします。
数式(暗記不要・参照用): PE(t,2i)=sin⁡(t/100002i/dmodel)PE(t,2i)=\sin(t/10000^{2i/d_{model}})PE(t,2i)=sin(t/100002i/dmodel​)、PE(t,2i+1)=cos⁡(t/100002i/dmodel)PE(t,2i+1)=\cos(t/10000^{2i/d_{model}})PE(t,2i+1)=cos(t/100002i/dmodel​) など。ttt は位置番号、iii は次元インデックス、dmodeld_{model}dmodel​ はベクトルの長さです。
かんたん解説: 式全体は「何番目(ttt)ごとに、数字の位置パターン(指紋)を1本作る」イメージで十分です。ベクトルは長さ dmodeld_{model}dmodel​ のたくさんの成分で、隣り合う2成分ずつが回る速さの違う波になります。tttは「文の何番目のトークンか」、iiiは「どの周波数帯(遅い波〜速い波)を使うか」に近いです。dmodeld_{model}dmodel​は全体の長さで、指数の中で波が極端に速すぎ/遅すぎにならないようスケールを合わせます。隣の位置では値が少しずつしか変わらず、離れた位置ほどパターンが違いやすく、「前後の距離感」を読み取りやすくなります。sin⁡\sinsin と cos⁡\coscos のペアは、針の向き(角度)を2つの数で書くのに似て、1本の波だけより安定して位置を表せます(細部は暗記不要)。
応用: 長い文脈のエンコーダ、その後 RoPE などへ発展。
3. 概念: フィードフォワード(FFN) — トークンごとの「個別面談」
一行: 注意(アテンション) はトークン同士が混ざり合う段階、FFN はそのあと 各位置の列を分けたまま、同じ小さなネットを列ごとに1回ずつ通す段階です(上の図の緑の計算ブロックに近いです)。
たとえ: 全員ミーティング(注意)のあと、一人ずつブースに入って個別ヒアリング(FFN)を受けるイメージです。ベクトル幅 dmodeld_{model}dmodel​ をいったん広げて(中間が太い)また元の幅に戻す砂時計型が一般的です。
なぜ必要? 注意だけだと「掛け算・足し算」中心になりがちです。FFN に ReLU(max⁡(0,⋅)\max(0,\cdot)max(0,⋅))などの非線形を入れて、直線だけでは表せない複雑な形を学べます。
数式(参照): FFN(x)=max⁡(0,xW1+b1)W2+b2\mathrm{FFN}(x)=\max(0,xW_1+b_1)W_2+b_2FFN(x)=max(0,xW1​+b1​)W2​+b2​。W1,W2W_1,W_2W1​,W2​ は多くの場合全位置で共有です。
応用: 感情分析・NER など。注意が文脈を集め、FFN が各トークンを磨く。
4. 概念: ブロック内の流れ — コンベアの一駅
一行: エンコーダブロック1つは、工場の一駅のように、いつも同じ順番で処理します。
かんたんな順序:
1. 準備: 埋め込みに PE を足し、「何番目か」が載った状態にする。
2. 混ぜる: 注意でトークン間が文脈を交換する。
3. つなぐ: Add & Norm — 手前の値を足す(残差)のと、層正規化でスケールをそろえる。
4. 列ごと: FFNで各位置を非線形に更新する。
5. もう一度 Add & Norm で締める。
数式(参照): まず h′=LayerNorm(h+Attn(h))h'=\mathrm{LayerNorm}(h+\mathrm{Attn}(h))h′=LayerNorm(h+Attn(h))、つづけて h′′=LayerNorm(h′+FFN(h′))h''=\mathrm{LayerNorm}(h'+\mathrm{FFN}(h'))h′′=LayerNorm(h′+FFN(h′))。このかたまりを何十回も積む。
応用: 検索・チャット・コード生成など。

なぜ重要か

順序は意味を変える
「ごはんを食べた」と語順を変えると文法・意味が変わります。PEがないと一貫して保つのが難しくなります。金融ログでも時系列は不正検知の要です。
FFNが非線形を担う
注意は主に線形変換とソフトマックスの組み合わせですが、FFNは高次元へ広げて ReLU/GELU などを入れ、複雑な規則を学びます。
計算のトレードオフ
dffd_{ff}dff​ や層数を上げると表現力は上がりますがGPUコストと遅延も増えます。
最新モデルへの土台
絶対位置埋め込み、正弦PE、RoPE、ALiBiなど進化は続きますが、「順序をテンソルに載せる」考え方は同じです。

どう使うか

実務: トークン化 → 埋め込み → +PE
トークン化し、埋め込み行列をかけ、位置ベクトルを足します。学習可能なPEテーブルは max_position_embeddings などで長さを決めます。長文QAではコンテキスト長も一緒に設計します。
FFNのハイパーパラメータ
intermediate_size (dffd_{ff}dff​)、活性化(GELU)、ドロップアウトなど。例: dmodel=768d_{model}=768dmodel​=768 なら dff=3072d_{ff}=3072dff​=3072 がよく使われます。
デコーダの注意
マスクで未来を隠しても、PEは左から右への順序を伝えます。
デバッグのヒント
順序が重要ならPE/RoPE/文脈長を確認し、表現が単調ならFFN幅・深さ・活性化を見ます。

まとめ

注意機構が強力でも、各トークンがどの位置かを安定して伝えるには、順序情報を別途ベクトルで載せる必要があります。正弦・余弦PEは複数の周波数で位置パターンを作り、埋め込みに足して初期表現を完成させます。その後、注意がトークン間を調整し、FFNが各位置で同じ非線形変換を繰り返して表現を練ります。拡張してから戻すFFNは、品質と計算コストの現実的なつまみです。

解法のための説明

まとめ — PEは埋め込みに順序を足し、正弦PEは複数周波数で位置を符号化し、FFNは各位置で共有MLPを通して非線形表現を積みます。dffd_{ff}dff​・層数・文脈長は性能とコストと一緒に動きます。
  • タイプPEの目的
  • ヒント(キーワード → 考え方)順序・絶対/相対の手がかり → 「埋め込み+PE」
  • タイプ正弦PE
  • ヒント(キーワード → 考え方)偶数 sin⁡\sinsin、奇数 cos⁡\coscos の対応
  • タイプ加算型
  • ヒント(キーワード → 考え方)h=x+PE(pos)h = x + PE(pos)h=x+PE(pos)
  • タイプFFN
  • ヒント(キーワード → 考え方)トークンごとMLP、多くは dff>dmodeld_{ff} > d_{model}dff​>dmodel​
  • タイプ共有
  • ヒント(キーワード → 考え方)位置ごとに別パラメータではないことが多い
  • タイプトレードオフ
  • ヒント(キーワード → 考え方)幅・深さ ↔ 計算・遅延
タイプヒント(キーワード → 考え方)
PEの目的順序・絶対/相対の手がかり → 「埋め込み+PE」
正弦PE偶数 sin⁡\sinsin、奇数 cos⁡\coscos の対応
加算型h=x+PE(pos)h = x + PE(pos)h=x+PE(pos)
FFNトークンごとMLP、多くは dff>dmodeld_{ff} > d_{model}dff​>dmodel​
共有位置ごとに別パラメータではないことが多い
トレードオフ幅・深さ ↔ 計算・遅延
例(概念理解)
「セルフアテンションだけで順序が常に完全に表れる。」
① 正
② 部分的にだけ
③ 順序はどうでもよい
完全ではないのでPEなどで補います。→ 2

「典型的な正弦・余弦PEで、偶数次元 2i2i2i によく使うのは?」
① コサインだけ
② サイン
③ 恒等写像
PE(t,2i)=sin⁡(⋯ )PE(t,2i)=\sin(\cdots)PE(t,2i)=sin(⋯) 形が一般的です。→ 2

「トークン埋め込み xxx と位置ベクトル PEPEPE を合わせる一般的な方法は?」
① 足し算 x+PE(pos)x+PE(pos)x+PE(pos)
② 連結だけ
③ 要素ごとの積だけ
加算型PEが一般的です。→ 1

「FFN(フィードフォワード)ブロックの役割に最も近いのは?」
① トークン間の関係を作る注意
② 各トークン表現を位置ごとに非線形変換
③ ドロップアウトだけ
トークンごとのMLPに近いです。→ 2

「同じレイヤーで各位置のFFNを使う一般的な方法は?」
① 位置ごとに別の W1,W2W_1,W_2W1​,W2​
② 全位置で同じFFN重みを共有
③ PE行列だけ共有
パラメータ共有が一般的です。→ 2

「中間次元 dffd_{ff}dff​ やブロックの深さを増やすと、一緒に見ることが多いコストは?」
① 常に速度だけ上がる
② 計算量・メモリ・遅延
③ ラベル数
表現力とコストのトレードオフです。→ 2

例(○×)
「FFNはトークンごとに必ず別の重みが必要。」正=1、誤=0。
通常は共有重みです。→ 0

例(シナリオ)
「診療記録で投与前後の順序が重要。まず強化すべき入力は?」
① 埋め込み+PE
② ピクセルだけ
③ ファイル名だけ
順序信号が必要です。→ 1

例(投票・カウント)
「指示ベクトル [1,1,0,1,0] で 1 の個数は?」
1+1+0+1+0=31+1+0+1+0=31+1+0+1+0=3。→ 3

例(予測の集約)
「3ブロックのスコア [2,1,2] の合計は?」
2+1+2=52+1+2=52+1+2=5。→ 5

例(構成・計算)
「トークン数が10のとき、セルフアテンションのスコア行列の要素数は?」
10×10=10010\times10=10010×10=100。→ 100

例(層を積む/アンサンブル原理)
「多くの層を積む目的に最も近いのは?」
① 段階的な抽象化
② データ削除
③ 入力禁止
層を重ねて表現を深めます。→ 1