はじめに: トランスフォーマー レボリューション
I トランスフォーマー論文「Attending Is All You Need」(2017)で紹介された、 AIに革命をもたらした。 GPT から BERT へ、DALL-E から安定拡散へ、クロードからジェミニへ: すべてはい Transformer アーキテクチャに基づいています。彼らの成功の秘密はそのメカニズムにあります。 自意識これにより、ファイルなしで長距離の依存関係をキャプチャできます。 繰り返しネットワークの制限。
何を学ぶか
- クエリ、キー、値: 3 つの線形投影
- スケーリングされたドット積の注意: 中心的な公式
- なぜdの根で割るのか
- マルチヘッドアテンション: 複数の視点
- 位置エンコーディング: 繰り返しなしで順序を追加します。
- NumPy での段階的な実装
Q、K、V 予測: データに関する 3 つの視点
アテンション メカニズムは、入力の 3 つの線形変換で動作します。 \\mathbf{X} \\in \\mathbb{R}^{n \\times d_{\\text{model}}}:
どこ \\mathbf{W}^Q, \\mathbf{W}^K \\in \\mathbb{R}^{d_{\\text{model}} \\times d_k} e \\mathbf{W}^V \\in \\mathbb{R}^{d_{\\text{model}} \\times d_v}.
直感:
- クエリ (\\mathbf{Q}): 「何を探しているの?」 - 各トークンが尋ねる質問
- Key (\\mathbf{K}): 「何を提供しますか?」 - 各トークンのラベル
- 価値 (\\mathbf{V}): 「私のコンテンツは何ですか?」 - 実際の情報
アテンション メカニズムは、各クエリとすべてのキーの間の類似性を計算し、これらを使用します。 類似性を重みとして使用し、対応する値を結合します。
スケーリングされたドット積の注意
トランスフォーマーの中心となる公式:
段階的に:
- \\mathbf{Q} \\mathbf{K}^T \\in \\mathbb{R}^{n \\times n}: すべてのトークン間の類似度行列 (ドット積)
- 除算 \\sqrt{d_k}: 数値安定性のためのスケーリング
- ソフトマックス 行ごと: スコアを合計が 1 になる重み (確率) に変換します。
- 乗算 \\mathbf{V}: 値の加重平均
なぜスケーリング係数なのか?
それなし \\sqrt{d_k}、内積はベクトルのサイズとともに増加します。 もし q e k IDを持っています平均 0 e のコンポーネント 分散 1 の場合:
大きな値の場合 d_k、スカラー積は非常に大きな値を持ちます。 大きいか非常に小さいかによって、ソフトマックスが飽和領域 (勾配がほぼゼロ) になります。 で割る \\sqrt{d_k}、分散は 1 に戻ります。
import numpy as np
def softmax(x, axis=-1):
exp_x = np.exp(x - np.max(x, axis=axis, keepdims=True))
return exp_x / np.sum(exp_x, axis=axis, keepdims=True)
def scaled_dot_product_attention(Q, K, V, mask=None):
"""Scaled Dot-Product Attention."""
d_k = Q.shape[-1]
# 1. Calcola punteggi di similarità
scores = Q @ K.transpose(0, 2, 1) if Q.ndim == 3 else Q @ K.T
scores = scores / np.sqrt(d_k)
# 2. Applica mask (opzionale, per decoder)
if mask is not None:
scores = np.where(mask == 0, -1e9, scores)
# 3. Softmax per ottenere pesi di attenzione
attention_weights = softmax(scores)
# 4. Media pesata dei Value
if Q.ndim == 3:
output = attention_weights @ V
else:
output = attention_weights @ V
return output, attention_weights
# Esempio: sequenza di 4 token, dimensione 8
np.random.seed(42)
seq_len, d_model, d_k = 4, 8, 8
X = np.random.randn(seq_len, d_model)
# Matrici di proiezione
W_Q = np.random.randn(d_model, d_k) * 0.1
W_K = np.random.randn(d_model, d_k) * 0.1
W_V = np.random.randn(d_model, d_k) * 0.1
# Proiezioni
Q = X @ W_Q
K = X @ W_K
V = X @ W_V
# Attention
output, weights = scaled_dot_product_attention(Q, K, V)
print(f"Input shape: {X.shape}")
print(f"Attention weights:\n{np.round(weights, 3)}")
print(f"Output shape: {output.shape}")
複数の頭による注意: 複数の視点
トランスフォーマーは、単一のアテンション メカニズムの代わりに、 h teste (ヘッド) を並列に配置し、それぞれに独自の射影行列を持ちます。
すべての頭には次元がある d_k = d_{\\text{モデル}} / 時間。 8 ヘッド付き e d_{\\text{モデル}} = 512、各ヘッドは 64 次元の空間で動作します。
なぜもっと頭が多いのですか? 各ヘッドは、異なるタイプの関係をキャプチャできます。 ある頭は構文に焦点を当て、別の頭はセマンティクスに焦点を当て、別の頭は相互参照に焦点を当てる可能性があります。
import numpy as np
def multi_head_attention(X, n_heads, d_model):
"""Multi-Head Attention implementazione semplificata."""
d_k = d_model // n_heads
seq_len = X.shape[0]
# Proiezioni per ogni testa
heads_output = []
all_weights = []
for h in range(n_heads):
W_Q = np.random.randn(d_model, d_k) * 0.1
W_K = np.random.randn(d_model, d_k) * 0.1
W_V = np.random.randn(d_model, d_k) * 0.1
Q = X @ W_Q
K = X @ W_K
V = X @ W_V
# Scaled dot-product attention
scores = Q @ K.T / np.sqrt(d_k)
weights = softmax(scores)
head_out = weights @ V
heads_output.append(head_out)
all_weights.append(weights)
# Concatena le teste
concat = np.concatenate(heads_output, axis=-1) # (seq_len, d_model)
# Proiezione output
W_O = np.random.randn(d_model, d_model) * 0.1
output = concat @ W_O
return output, all_weights
np.random.seed(42)
seq_len, d_model, n_heads = 6, 16, 4
X = np.random.randn(seq_len, d_model)
output, weights = multi_head_attention(X, n_heads, d_model)
print(f"Input: {X.shape}, Output: {output.shape}")
print(f"Numero teste: {n_heads}, d_k per testa: {d_model // n_heads}")
位置エンコーディング: 反復のない順序
注目は 順列不変: トークンの順序を区別しません。のために 位置情報を追加するには、 位置エンコーディング ベースの 正弦関数について:
なぜサインとコサインなのでしょうか?なぜ PE{pos+k} 次のように表現できます の線形変換 PE{正}、モデルに次のことを許可します。 固定された相対距離を「見る」ことを簡単に学びます。
import numpy as np
def positional_encoding(max_len, d_model):
"""Sinusoidal Positional Encoding."""
PE = np.zeros((max_len, d_model))
position = np.arange(max_len)[:, np.newaxis]
div_term = np.exp(np.arange(0, d_model, 2) * -(np.log(10000.0) / d_model))
PE[:, 0::2] = np.sin(position * div_term) # Indici pari: seno
PE[:, 1::2] = np.cos(position * div_term) # Indici dispari: coseno
return PE
# Genera positional encoding
max_len, d_model = 100, 64
PE = positional_encoding(max_len, d_model)
print(f"PE shape: {PE.shape}")
print(f"PE[0, :8]: {np.round(PE[0, :8], 4)}")
print(f"PE[1, :8]: {np.round(PE[1, :8], 4)}")
# L'embedding finale e: token_embedding + positional_encoding
token_embedding = np.random.randn(10, d_model) # 10 token
input_with_position = token_embedding + PE[:10]
print(f"\nEmbedding + PE shape: {input_with_position.shape}")
層の正規化と残留接続
Transformer の各サブレイヤーは、 残りの接続 e レイヤーの正規化:
レイヤーの正規化は、フィーチャの次元に沿って正規化します。
どこ \\mu e \\シグマ について計算されます 各サンプル、e \\ガンマ、\\ベータ これらは学習可能なパラメータです。
まとめ
覚えておくべき重要なポイント
- 注意: \\text{ソフトマックス}(QK^T / \\sqrt{d_k}) V - トークン間の重み付けされた類似性
- スケーリング \\sqrt{d_k}: ソフトマックスの飽和を防ぎます
- マルチヘッド: h 並列したヘッドがさまざまな関係を捉える
- 位置エンコーディング: サイン/コサイン加算順序
- 残差 + LayerNorm: ディープネットワークのトレーニングを安定化します
- アーキテクチャ全体は線形代数とソフトマックス演算で構成されています
次の記事で: を探索してみます データ拡張 e 合成データ生成技術。 SMOTE、Mixup、画像とテキストの拡張、 そして増強が本当に役立つとき。







