深層学習とLLM
目次
- 概要
- 深層学習とは何か
- ニューラルネットワークの基本
- 逆伝播と学習
- 正則化と安定化
- 表現学習
- 生成モデル
- Transformer
- Transformer の詳細構造
- LLMの基本構造
- LLMアーキテクチャの進化
- LLMの学習と適応
- Transformer アーキテクチャの詳細
- 大言語モデル(LLM)の設計
- 効率化テクニック
- 評価メトリクス
- LLMの評価と安全性
- GPU章とのつながり
- Attentionの直感
- 学習と推論の違い
- Fine-tuning、RAG、promptingの使い分け
- 評価の分解
- LLM スケーリングと推論最適化
- 事前学習と微調整
- Attention メカニズム の数学的詳細
- Positional Encoding の設計選択
- Transformer の計算複雑度と最適化
- 層正規化と活性化関数
- 勾配爆発・消失問題
- Beam Search とテキスト生成
- Transfer Learning と事前学習モデル
- 確率的勾配降下法(SGD)と最適化アルゴリズム
- 正則化と過学習対策
- 不均衡データセット への対応
- 詳細な実装例集
- まとめ
- 参考文献
概要
表現学習、ニューラルネット、Transformerをひとつの流れで理解する
深層学習は、多層の表現変換を通じて複雑な関係を学ぶ方法です。現在のLLMは、その延長線上でTransformerと大規模事前学習を組み合わせたものとして理解できます。この章では、ニューラルネットの基本から、正則化、表現学習、生成モデル、LLMまでをつなげて整理します。
深層学習の本質は「特徴量を人が全部作るのではなく、表現そのものを学ぶ」点にあります。LLMはその延長線上にある、大規模な系列モデルです。
この章で重視すること
- ニューラルネットを、重み付き計算と非線形変換の繰り返しとして捉える
- 深層学習と古典的機械学習の違いを、表現学習の有無で整理する
- LLMを単体モデルではなく、学習・推論・評価・運用を含むシステムとして見る
深層学習とは何か
古典的機械学習では、人が特徴量を強く設計することが多くありました。深層学習では、その特徴表現そのものを多層ネットワークで学びます。
この違いが、画像、音声、自然言語のような高次元データで深層学習が強い理由です。
ニューラルネットワークの基本
最も基本的な構造は、
- 線形変換
- 非線形活性化
- 層の積み重ね
です。
多層パーセプトロン(MLP)は、この最小形として理解しやすいモデルです。ここで重要なのは、層を重ねることで単純な線形モデルでは表せない関係を扱えるようになる点です。
逆伝播と学習
深層学習では、損失を減らすために各重みを更新します。逆伝播は、そのために「どの重みがどのくらい損失に効いたか」を連鎖律で後ろから伝える仕組みです。
ここで学ぶべき点は、
- 勾配が流れること
- 深くなると不安定になりやすいこと
- 最適化と初期化が重要になること
です。
正則化と安定化
深層学習では、表現力が高いぶん、過学習や不安定さも大きくなります。代表的な対策は次です。
- weight decay
- dropout
- batch normalization / layer normalization
- early stopping
- データ拡張
正則化は単に「性能を落とさないための保険」ではなく、未知データで壊れにくいモデルを作るための設計要素です。
表現学習
表現学習は、入力を別の空間に埋め込み、扱いやすい特徴へ変換する考え方です。
- 埋め込みベクトル
- オートエンコーダ
- 自己教師あり学習
画像、音声、自然言語では、この「どんな表現空間を学ぶか」が性能を大きく左右します。
生成モデル
生成モデルは、データを分類するのではなく、データの分布や生成過程を学びます。
代表例:
- Autoencoder / VAE
- GAN
- Diffusion Model
生成モデルを学ぶと、「入力からラベルを当てる」以外のAIの見方が広がります。
Transformer
Transformerは、系列データを扱う現代の中心的な構造です。自己注意機構によって、系列内のどの位置同士が強く関係するかを学びます。
RNNと比べたときの利点:
- 並列化しやすい
- 長距離依存を扱いやすい
- スケールしやすい
Vaswani et al. (2017) により発表された「Attention Is All You Need」は、再帰や畳み込みを完全に排除し、注意機構のみに基づく新しいシンプルなネットワークアーキテクチャを提案しました。機械翻訳タスクでは28.4 BLEUを達成し、既存の最良結果を2 BLEU以上改善し、同時により並列化しやすく、大幅に少ない訓練時間で完了しました。
Transformer の詳細構造
Self-Attentionの仕組み
Self-Attentionは、各トークンが他のすべてのトークンを参照しながら、文脈に応じた表現を構築します。Query、Key、Valueの3つの行列を用いて計算されます。
Self-Attentionの数学的表現:
スケーリング係数 は、内積の大きさが次元に応じて変わることを補正します。
Multi-Head Attention
複数の注意ヘッドを並列に実行することで、異なるサブスペース上で相互作用をキャプチャします。
- 単一ヘッド: 1つの線形変換
- マルチヘッド: 複数の線形変換を並列実行して結合
これにより、各ヘッドが異なる種類の関係性(文法的、意味的など)を学習できます。
Positional Encoding
トークンの順序情報を組み込むため、絶対位置または相対位置にもとづいたPositional Encodingを追加します。
正弦波ベースの位置符号化:
この設計により、相対位置に関する線形な関係が学習しやすくなります。
層の積み重ね構造
Transformerは、Encoder層と Decoder層をそれぞれ複数スタックします。
- Encoder: 入力全体をコンテキスト化
- Decoder: 出力を自動回帰的に生成、Encoderの出力を参照
各層は以下を含みます:
- Multi-Head Self-Attention + Residual接続 + Layer Norm
- Feed-Forward Network (FFN) + Residual接続 + Layer Norm
Residual接続と Layer Normalization は、深いモデルの学習を安定化させます。
LLMの基本構造
LLMは、巨大なテキストコーパスで次トークン予測を学ぶ大規模Transformerです。
理解の軸は次の通りです。
- トークン化
- 埋め込み
- Attention
- コンテキスト長
- 事前学習
- 推論時のdecoding
LLMを「知識を持った箱」と見るよりも、「系列上の条件付き確率モデル」として見る方が、限界や失敗も理解しやすくなります。
LLMアーキテクチャの進化
BERT時代 (2018)
BERT(「BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding」、Devlin et al. 2018)は、事前学習タスクとして Masked Language Modeling (MLM) と Next Sentence Prediction (NSP) を導入しました。
双方向性により、文脈の両側から情報を取得でき、下流タスク(分類、固有表現認識など)で高い性能を実現しました。
Decoder-Only モデルへの転換
GPTシリーズの成功により、Decoder-Onlyアーキテクチャが主流に。
- 次トークン予測のみで事前学習
- 自動回帰生成に最適化
- スケーリング法則がシンプル
現代の実装特性
多くの最新LLMは次の工夫を含みます:
- RoPE(Rotary Position Embedding): 相対位置符号化の改善版
- Flash Attention: 計算効率を大幅改善
- Group Query Attention(GQA): KVキャッシュのメモリ削減
これらは、より長いコンテキストと効率的な推論を実現しています。
LLMの学習と適応
LLMを使う流れは、大きく
- 事前学習
- 指示追従の調整
- 追加学習 / ファインチューニング
- 推論時の外部知識利用
に分かれます。
ここで重要なのは、モデル本体だけでなく、
- SFT (Supervised Fine-Tuning)
- PEFT / LoRA (Parameter-Efficient Fine-Tuning)
- RAG (Retrieval-Augmented Generation)
- 推論時プロンプト設計
といった外側の工夫も含めて性能が決まることです。
Transformer アーキテクチャの詳細
Self-Attention の計算
Self-Attention は Query、Key、Value ベクトルを用いたシーケンス内の関連性計算。
import numpy as np
import torch
import torch.nn as nn
def scaled_dot_product_attention(Q, K, V, mask=None):
"""
Scaled Dot-Product Attention
Args:
Q: Query [batch_size, seq_len, d_k]
K: Key [batch_size, seq_len, d_k]
V: Value [batch_size, seq_len, d_v]
mask: Optional mask [seq_len, seq_len]
"""
d_k = Q.shape[-1]
# 1. Compute attention scores
scores = torch.matmul(Q, K.transpose(-2, -1)) / np.sqrt(d_k)
# Shape: [batch_size, seq_len, seq_len]
# 2. Apply mask (for causal/future masking)
if mask is not None:
scores = scores.masked_fill(mask == 0, -1e9)
# 3. Apply softmax
attention_weights = torch.softmax(scores, dim=-1)
# 4. Multiply by values
output = torch.matmul(attention_weights, V)
# Shape: [batch_size, seq_len, d_v]
return output, attention_weights
複雑度分析:
- Time: O(n^2 * d)(n=シーケンス長、d=隠れ次元)
- Space: O(n^2)(attention 行列)
長いシーケンス(4096+ トークン)では計算量が支配的。
Multi-Head Attention
複数の"ヘッド"を並列に実行し、異なる部分空間で関連性を学習。
class MultiHeadAttention(nn.Module):
def __init__(self, d_model, n_heads):
super().__init__()
assert d_model % n_heads == 0
self.d_model = d_model
self.n_heads = n_heads
self.d_k = d_model // n_heads # 各ヘッドの次元
self.W_q = nn.Linear(d_model, d_model)
self.W_k = nn.Linear(d_model, d_model)
self.W_v = nn.Linear(d_model, d_model)
self.W_o = nn.Linear(d_model, d_model)
def forward(self, Q, K, V, mask=None):
batch_size = Q.shape[0]
# Linear transformations
Q = self.W_q(Q).reshape(batch_size, -1, self.n_heads, self.d_k).transpose(1, 2)
K = self.W_k(K).reshape(batch_size, -1, self.n_heads, self.d_k).transpose(1, 2)
V = self.W_v(V).reshape(batch_size, -1, self.n_heads, self.d_k).transpose(1, 2)
# Shape: [batch_size, n_heads, seq_len, d_k]
# Scaled dot-product attention
attn_output, attn_weights = scaled_dot_product_attention(Q, K, V, mask)
# Concatenate heads
attn_output = attn_output.transpose(1, 2).reshape(batch_size, -1, self.d_model)
# Final linear layer
output = self.W_o(attn_output)
return output, attn_weights
Feed-Forward Network
class FeedForward(nn.Module):
def __init__(self, d_model, d_ff, dropout=0.1):
super().__init__()
self.net = nn.Sequential(
nn.Linear(d_model, d_ff),
nn.ReLU(),
nn.Dropout(dropout),
nn.Linear(d_ff, d_model),
nn.Dropout(dropout)
)
def forward(self, x):
return self.net(x)
Positional Encoding
Transformer は位置情報を別途エンコードする(RNN と異なり)。
class PositionalEncoding(nn.Module):
def __init__(self, d_model, max_seq_len=5000):
super().__init__()
pe = torch.zeros(max_seq_len, d_model)
position = torch.arange(0, max_seq_len).unsqueeze(1) # [max_seq_len, 1]
# 正弦・余弦関数の周期を異なる周波数で
div_term = torch.exp(torch.arange(0, d_model, 2) * -(np.log(10000) / d_model))
pe[:, 0::2] = torch.sin(position * div_term) # 偶数インデックス
pe[:, 1::2] = torch.cos(position * div_term) # 奇数インデックス
self.register_buffer('pe', pe.unsqueeze(0)) # [1, max_seq_len, d_model]
def forward(self, x):
# x shape: [batch_size, seq_len, d_model]
return x + self.pe[:, :x.size(1), :]
大言語モデル(LLM)の設計
Decoder-only アーキテクチャ(GPT系)
GPT-3、GPT-4、Llama などは decoder-only 構成。
class TransformerDecoderBlock(nn.Module):
def __init__(self, d_model, n_heads, d_ff, dropout=0.1):
super().__init__()
self.self_attn = MultiHeadAttention(d_model, n_heads)
self.norm1 = nn.LayerNorm(d_model)
self.ffn = FeedForward(d_model, d_ff, dropout)
self.norm2 = nn.LayerNorm(d_model)
self.dropout = nn.Dropout(dropout)
def forward(self, x, causal_mask):
# Self-attention + residual
attn_out, _ = self.self_attn(x, x, x, mask=causal_mask)
x = x + self.dropout(attn_out)
x = self.norm1(x)
# FFN + residual
ffn_out = self.ffn(x)
x = x + self.dropout(ffn_out)
x = self.norm2(x)
return x
class LLMDecoder(nn.Module):
def __init__(self, vocab_size, d_model, n_layers, n_heads, d_ff, max_seq_len=2048):
super().__init__()
self.embedding = nn.Embedding(vocab_size, d_model)
self.pos_encoding = PositionalEncoding(d_model, max_seq_len)
self.decoder_layers = nn.ModuleList([
TransformerDecoderBlock(d_model, n_heads, d_ff)
for _ in range(n_layers)
])
self.norm = nn.LayerNorm(d_model)
self.output_projection = nn.Linear(d_model, vocab_size)
def forward(self, token_ids, causal_mask):
# Token embedding + positional encoding
x = self.embedding(token_ids)
x = self.pos_encoding(x)
# Apply decoder layers
for layer in self.decoder_layers:
x = layer(x, causal_mask)
# Final layer norm
x = self.norm(x)
# Project to vocabulary
logits = self.output_projection(x)
# Shape: [batch_size, seq_len, vocab_size]
return logits
Context Window Management
LLM のコンテキスト長(通常 2048~ 128k トークン)は計算・メモリのボトルネック。
# KV キャッシュ戦略:推論時に計算済み K,V を再利用
class KVCache:
def __init__(self, max_seq_len, n_heads, d_k):
self.max_seq_len = max_seq_len
self.n_heads = n_heads
self.d_k = d_k
self.k_cache = {} # layer_id -> [batch, n_heads, seq_len, d_k]
self.v_cache = {}
def get_or_create(self, layer_id, batch_size):
if layer_id not in self.k_cache:
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
self.k_cache[layer_id] = torch.zeros(batch_size, self.n_heads, self.max_seq_len, self.d_k, device=device)
self.v_cache[layer_id] = torch.zeros(batch_size, self.n_heads, self.max_seq_len, self.d_k, device=device)
return self.k_cache[layer_id], self.v_cache[layer_id]
def update(self, layer_id, k_new, v_new, position):
k_cache, v_cache = self.get_or_create(layer_id, k_new.shape[0])
k_cache[:, :, position:position+k_new.shape[2], :] = k_new
v_cache[:, :, position:position+v_new.shape[2], :] = v_new
Token 生成戦略
def generate(model, prompt_tokens, max_new_tokens, temperature=0.7, top_p=0.9):
"""
Temperature + Top-p sampling を用いた自動回帰生成
"""
generated = prompt_tokens.copy()
for _ in range(max_new_tokens):
# モデル実行
logits = model(generated[-context_window:])
logits = logits[:, -1, :] # 最後のトークンの logits
# Temperature scaling
logits = logits / temperature
# Top-p サンプリング
probs = torch.softmax(logits, dim=-1)
sorted_probs, sorted_indices = torch.sort(probs, descending=True)
cumsum_probs = torch.cumsum(sorted_probs, dim=-1)
# 累積確率が top_p を超えるトークンを除外
sorted_indices_to_remove = cumsum_probs > top_p
sorted_indices_to_remove[..., 0] = False # top token は必ず残す
indices_to_remove = sorted_indices[sorted_indices_to_remove]
logits[indices_to_remove] = -float('inf')
# サンプリング
next_token = torch.multinomial(torch.softmax(logits, dim=-1), num_samples=1)
generated.append(next_token.item())
return generated
効率化テクニック
Quantization(量子化)
16-bit float → 8-bit int への変換で 4倍メモリ削減。精度低下は最小限。
from bitsandbytes.nn import Linear8bitLt
# LoRA + 8bit 量子化
def quantize_and_lora(base_model):
# 重みを int8 に量子化
quantized_model = base_model
for name, module in quantized_model.named_modules():
if isinstance(module, nn.Linear):
quantized_model._modules[name] = Linear8bitLt(
module.in_features,
module.out_features,
has_fp16_weights=False,
threshold=6.0
)
return quantized_model
Low-Rank Adaptation (LoRA)
大規模モデルの全体 fine-tuning の代わりに、低ランク行列を追加。
class LoRALinear(nn.Module):
def __init__(self, in_features, out_features, r=8, alpha=16, dropout=0.1):
super().__init__()
self.weight = nn.Parameter(torch.randn(out_features, in_features) / np.sqrt(in_features))
self.bias = nn.Parameter(torch.zeros(out_features))
# LoRA: W = W_0 + (A @ B) * alpha / r
self.A = nn.Parameter(torch.randn(in_features, r) / np.sqrt(in_features))
self.B = nn.Parameter(torch.zeros(r, out_features))
self.dropout = nn.Dropout(dropout)
self.r = r
self.alpha = alpha
def forward(self, x):
# 元の重み + LoRA 更新
output = nn.functional.linear(x, self.weight, self.bias)
lora_update = self.dropout(x) @ self.A @ self.B * (self.alpha / self.r)
output = output + lora_update
return output
# 使用例
# 元の Linear 層を LoRA に置換
for name, module in model.named_modules():
if isinstance(module, nn.Linear) and 'attn' in name:
# アテンション層のみ LoRA 化(他より重要)
parent = model
for p in name.split('.')[:-1]:
parent = getattr(parent, p)
setattr(parent, name.split('.')[-1], LoRALinear(module.in_features, module.out_features))
Flash Attention
メモリバウンドな操作を削減し、計算効率を向上。
# torch >= 2.0 では組み込み
import torch.nn.functional as F
def flash_attention_forward(Q, K, V):
"""
Flash Attention の効果(メモリ IO 削減)
標準的な Attention: SRAM -> HBM(高バンド幅メモリ)への往復が多い
Flash Attention: ブロック単位で処理し IO を最小化
"""
# PyTorch 2.0+
return F.scaled_dot_product_attention(Q, K, V, is_causal=True)
性能改善例(H100 GPU):
- 標準実装: 100-200 ms(4k トークン)
- Flash Attention v2: 10-20 ms(ほぼ 10 倍)
評価メトリクス
Perplexity(困惑度)
訓練済みモデルの言語モデリング能力を測定。
def calculate_perplexity(model, test_dataset):
"""
PP = exp( -1/N * sum(log P(token_i)) )
低いほど良い(2~ 3 が SOTA, 20+ が悪い)
"""
total_loss = 0
total_tokens = 0
model.eval()
with torch.no_grad():
for batch in test_dataset:
logits = model(batch['input_ids'])
loss = F.cross_entropy(
logits.view(-1, vocab_size),
batch['labels'].view(-1),
reduction='sum'
)
total_loss += loss.item()
total_tokens += batch['labels'].numel()
perplexity = np.exp(total_loss / total_tokens)
return perplexity
BLEU, ROUGE(生成タスク)
BLEU: n-gram の正確さ(機械翻訳) ROUGE: Recall ベースの一致度(要約)
from torchtext.data.metrics import bleu_score
from rouge_score import rouge_scorer
# BLEU スコア
reference = [["a", "dog", "is", "running"]]
hypothesis = ["a", "dog", "running"]
bleu = bleu_score([hypothesis], reference) # 0.0~ 1.0
# ROUGE スコア
scorer = rouge_scorer.RougeScorer(['rouge1', 'rougeL'])
ref = "The quick brown fox"
hyp = "A quick brown fox"
scores = scorer.score(ref, hyp)
print(scores['rouge1'].fmeasure) # F値
LLMの評価と安全性
LLMは「それっぽく話す」ため、評価が難しいモデルです。見るべき観点は複数あります。
- タスク性能
- 事実性
- 一貫性
- 幻覚
- レイテンシ
- コスト
- 安全性
安全性では、
- 有害出力
- 情報漏えい
- プロンプトインジェクション
- モデルの過信
を考える必要があります。
GPU章とのつながり
この章はモデルの見方を扱い、GPU 章は実行基盤の見方を扱います。
- この章: なぜTransformerやLLMが成り立つか
- GPU章: それをどう高速に推論・提供するか
特に、
- Attention
- KV cache
- バッチング
- 量子化
は両章をつなぐキーワードです。
Attentionの直感
Transformerの中心にあるself-attentionは、各tokenが他のtokenを参照しながら表現を更新する仕組みです。文の中で何が何に関係しているかを、固定の距離ではなく内容に応じて学習します。
RNNでは系列を順番に処理しますが、Transformerは多くの位置を並列に扱いやすい構造です。この性質が、大規模データとGPUによる学習に合いました。
「The Illustrated Transformer」(Jay Alammarによる詳細な図解)は、Transformerの各部分を段階的に視覚化し、Query、Key、Value、Positional Encodingといった概念を直感的に説明しています。Self-Attentionの行列計算、Multi-Head Attentionの役割、各層の残差接続とLayerNormを図と共に理解できます。
学習と推論の違い
LLMでは、学習と推論でボトルネックが変わります。
| 段階 | 主な処理 | ボトルネック |
|---|---|---|
| 事前学習 | 大量tokenで重みを更新する | 計算量、通信、データ供給 |
| instruction tuning | 指示応答データで調整する | データ品質、過適応 |
| 推論prefill | prompt全体を処理する | context length、attention計算 |
| 推論decode | 1tokenずつ生成する | memory bandwidth、KV cache |
GPU章で扱うKV cacheやbatchingは、特に推論時のdecodeを効率化するために重要です。
Fine-tuning、RAG、promptingの使い分け
LLMを業務へ合わせる方法は複数あります。
| 方法 | 向いていること | 注意点 |
|---|---|---|
| prompting | 出力形式や作業手順の調整 | 知識更新には弱い |
| RAG | 外部文書にもとづく回答 | 検索品質に依存する |
| fine-tuning | 文体、分類、特定タスクの安定化 | データ品質と評価が重要 |
| tool use | 計算、検索、操作 | 権限と安全設計が必要 |
まずRAGやpromptingで足りるかを確認し、モデル自体の振る舞いを継続的に変えたい場合にfine-tuningを検討します。
評価の分解
LLM評価では、1つのスコアで全体を判断しない方が安全です。
- 正確性
- 根拠への忠実性
- 指示追従
- 安全性
- 一貫性
- レイテンシ
- コスト
- 回帰の有無
特に「人間には自然に見えるが、根拠がない」回答を検出するには、検索結果、引用、期待回答を分けて評価します。
LLM スケーリングと推論最適化
Chinchilla スケーリング則
最適なトークン数: N_opt = 20 * N_params。70B パラメータ → 1.4T トークン。Loss(N,D) ≈ E/N^α + B/D^β で α≈0.07, β≈0.16。パラメータ 2 倍で Loss 7%低下、トークン 2 倍で Loss 16%低下。
推論最適化
バッチサイズ 1 は遅延 100ms・スループット 10tokens/sec。バッチサイズ 128 は遅延 5s・スループット 256tokens/sec。Dynamic batching で効率化。KV Cache 削減:seq_len=2048, batch=32 で 1GB。対策として Paged attention(vLLM)や FP8 量子化(精度損失 ~1%)。
Few-shot プロンプティング
Zero-shot、One-shot、Few-shot with chain-of-thought。In-context learning により、LLM は示例から学習して新規タスクに対応。
事前学習と微調整
LoRA(Low-Rank Adaptation)
全パラメータ 7B を更新する代わり、低ランク分解 Delta_W ≈ A @ B^T で対応。パラメータ削減:d×d = 7B → 2×d×r = 0.001%。
Prefix tuning
学習可能な埋め込みをプロンプト前缀に付与。パラメータが非常に少ない(prefix_len=20, d_model=4096 → 80k)。
nsformer and inference resources](https://github.c
Attention メカニズム の数学的詳細
Attention は information retrieval の観点で見ると、Query を使用して Key との類似度を計算し、その重み付けで Value を集約。
スケール付きドット積: scores = Q * K^T / sqrt(d_k)。sqrt(d_k) で勾配爆発を防止(特に d_k が大きい場合)。
Multi-Head Attention の利点: 異なる部分空間で注意パターンを学習。例:1 つのヘッドは長距離依存を捉え、別のヘッドは局所パターンに焦点。
Positional Encoding の設計選択
Sinusoidal PE: 周期関数で相対位置を符号化。任意長文に対応(外挿性)。
Learned PE: 絶対位置に対して埋め込みを学習。柔軟だが、学習データより長い文に弱い。
Rotary Position Embedding(RoPE): 複素数回転で相対位置を表現。GPT-Neo で採用。高い外挿性。
Transformer の計算複雑度と最適化
時間複雑度: O(n^2 * d)(n = sequence length, d = embedding dim)。n=2048, d=4096 で QK^T 計算が dominant。
メモリ複雑度: O(n^2)(attention matrix 全体を保持)。Sparse Attention や Linear Attention で O(n) に削減。
層正規化と活性化関数
LayerNorm vs BatchNorm: Transformer では LayerNorm が主流(sample size 1 でも機能)。
ReLU の問題: Dead ReLU(出力が常に 0)。GELU や SwiGLU で改善。
勾配爆発・消失問題
Long-term dependency がある場合、逆伝播で勾配が exponentially 増加/減少。
Residual connections(skip connection)で勾配フロー改善。LayerNorm でスケール制御。勾配クリッピング(max norm)で爆発を抑制。
Beam Search とテキスト生成
Greedy decoding: 毎ステップで最高確度のトークン選択。高速だが質低下。
Beam search: 複数の候補を保持(beam width = 5 等)。スコアでリランク。ビーム幅大で品質向上、遅延増加。
Temperature sampling: softmax 前に温度 T を適用。T > 1 で多様性、T < 1 で確定性。
Transfer Learning と事前学習モデル
事前学習モデルを特定タスクに微調整(fine-tune)。ImageNet で学習した ResNet を医療画像分類に転用。計算コスト・学習時間大幅削減。
BERT、GPT など NLP 事前学習モデルの汎用性。テキスト分類、抽出、生成タスクで高精度。
Multitask Learning: 複数タスクを同時学習。shared representation で汎化性向上。
確率的勾配降下法(SGD)と最適化アルゴリズム
Momentum: 勾配方向の速度を保持。鞍点からの脱出高速化。
Adam: 勾配の一次・二次モーメント推定。自動的な学習率調整。ほとんどの深層学習で採用。
Learning rate schedule: 固定値より動的調整(warmup → decay)。収束安定性向上。
正則化と過学習対策
L1/L2 正則化(weight decay): 重みの大きさを制限。L1 で sparse 解導出。
Dropout: ランダムにニューロンを無効化。co-adaptation 防止。推論時は全ニューロン使用(スケーリング調整)。
Early Stopping: 検証損失が改善しなくなった時点で学習終了。過学習防止。
Batch Normalization: 各層入力の分布を正規化。勾配安定、学習率上昇可能。
不均衡データセット への対応
Class imbalance: 例えば医療診断で病例 1% のみ。単純精度では意味ない。
F1 スコア、ROC AUC で評価。困惑行列(TP、FP、TN、FN)で詳細把握。
Over-sampling(少数クラス複製)と Under-sampling(多数クラス削除)。Synthetic data generation(SMOTE)。
Cost-sensitive learning: 少数クラスの誤分類にペナルティ加重。
詳細な実装例集
ResNet(残差ネットワーク)の構造
Skip connection が信号パスをバイパス。深いネットワークでの勾配消失問題を緩和。
input -> Conv -> BatchNorm -> ReLU -> Conv -> + -> ReLU -> output
^
|
(skip connection from input)
ResNet-50: 50 層。ImageNet で 76% top-1 精度。競争的なタスクで定番。
U-Net(セマンティックセグメンテーション)
エンコーダ-デコーダアーキテクチャ。Low-level 特徴を skip connection で decoder に直接注入。
医療画像(CT、MRI)のセグメンテーションで高精度。少データでも効果的(Data Augmentation + skip connections)。
Attention Is All You Need(元の Transformer 論文)
2017 Vaswani et al. Multi-head self-attention のみで SOTA 達成。RNN/CNN 不要。
Sequence-to-sequence(翻訳など)の新パラダイムシフト。並列化可能で GPU フレンドリー。
Vision Transformer(ViT)
画像を patch に分割して embedding。Transformer を画像認識に適用。
ImageNet で CNN と同等以上の精度(ただし大規模事前学習必要)。
Diffusion Models(拡散モデル)
ノイズ を段階的に追加して逆過程を学習。画像生成(Stable Diffusion、DALL-E 3)で最新 SOTA。
ノイズ除去の反復で高品質生成。確率的生成で多様な出力。
om/NVIDIA/FasterTransformer) - Transformerの推論最適化
まとめ
深層学習は、表現そのものを学ぶ多層モデルです。Transformerと大規模事前学習により、その延長線上にLLMが現れました。ニューラルネットの基本、逆伝播、正則化、表現学習、Transformer、LLMの評価と安全性をつなげて見ると、現在のAIシステムがどこで強く、どこで壊れやすいかが見えやすくなります。
Self-Attentionのメカニズム、Multi-Head Attentionによる多角的な関係学習、Positional Encodingによる順序情報の統合といった個々の要素が、なぜTransformerを強力にしたのか、また実装上の工夫(Residual接続、Layer Norm)が深層化を可能にしたのかを理解することで、LLMの動作原理と限界が明確になります。
参考文献
論文
- Vaswani, A., Shazeer, N., Parmar, N., Uszkoreit, J., Jones, L., Gomez, A. N., Kaiser, L., & Polosukhin, I. (2017). Attention Is All You Need. arXiv:1706.03762.
- Devlin, J., Chang, M. W., Lee, K., & Toutanova, K. (2018). BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding. arXiv:1810.04805.
講義・記事
- Stanford CS25: Transformers United - Transformerの最新動向と応用を扱うセミナー
- Stanford CS 224N: Natural Language Processing with Deep Learning - NLP と深層学習の体系的な講義
- The Illustrated Transformer - Self-Attention、Multi-Head Attention、Positional Encodingを図解で説明
書籍
- Deep Learning book - Ian Goodfellow らによる包括的な教科書
解説・補助
- PyTorch Tutorials - Transformerの実装例とベストプラクティス
- [NVIDIA: FasterTra## Transformer アーキテクチャの詳細構造
Self-Attention メカニズムの計算詳細
Self-attention は Query、Key、Value の 3 つの線形投影から構成される。
計算式(スケール付きドット積注意): Attention(Q,K,V) = softmax(Q*K^T/sqrt(d_k))*V
具体例(日本語文の注意スコア計算)では、トークン “私” は “猫” に最も注意を払う。Multi-Head Attention では 8 ヘッドで異なる部分空間を学習。
Positional Encoding と位置情報
Transformer は RNN の連続処理がないため、位置情報を明示的に付与。Sinusoidal Positional Encoding と相対位置エンコーディング(改善版)が利用される。
フィード・フォワード層(FFN)
Attention の後に 2 層の密集層。Standard FFN では d_ff = 2048(d_model = 512 の 4 倍)。Gated Linear Unit(GLU)変種は GPT-3 で採用。計算量:Self-attention は O(n^2d)、FFN は O(nd_model^2)で、長文処理時は Attention が bottleneck。