# 機能設計書 27-SGD（確率的勾配降下法）

## 概要

本ドキュメントは、TensorFlow/KerasにおけるSGD（Stochastic Gradient Descent）オプティマイザの機能設計を記述する。学習率スケジューリング、モーメンタム、Nesterovモーメンタムをサポートする勾配降下法オプティマイザを提供する。

### 本機能の処理概要

**業務上の目的・背景**：SGDは最も基本的で広く使用される最適化アルゴリズムである。シンプルな更新則ながら、モーメンタムやNesterov加速により収束速度を向上できる。大規模なモデルの学習において、適切な学習率スケジュールと組み合わせることで、Adam等の適応的手法と同等以上の汎化性能を達成できることが知られている。

**機能の利用シーン**：画像分類（ResNet等の学習でSGD+Momentumが標準）、一般的なニューラルネットワークの学習、学習率スケジュールを細かく制御したい場合に使用される。

**主要な処理内容**：
1. 勾配に基づくパラメータ更新（基本SGD）
2. モーメンタム付きSGD（velocity蓄積による加速）
3. Nesterovモーメンタム（先読み勾配による更新）
4. スパース勾配対応（IndexedSlices）
5. 学習率スケジュール対応（LearningRateScheduleオブジェクト）

**関連システム・外部連携**：損失関数（No.40）の勾配を受け取り、自動微分（No.37）のGradientTapeと連携する。学習率スケジューリング（No.35）と組み合わせて使用可能。

**権限による制御**：特になし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 画面機能マッピングに該当なし |

## 機能種別

計算処理（パラメータ最適化）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| learning_rate | float/Schedule/callable | No | 学習率 | デフォルト: 0.01 |
| momentum | float | No | モーメンタム係数 | 0.0-1.0、デフォルト: 0.0 |
| nesterov | bool | No | Nesterovモーメンタムを使用するか | デフォルト: False |
| clipnorm | float | No | 勾配ノルムクリッピング | 正値 |
| clipvalue | float | No | 勾配値クリッピング | 正値 |

### 入力データソース

GradientTapeまたはmodel.fit()から計算された勾配テンソル。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| updated_variables | Variable | 更新されたモデルパラメータ |
| iteration | int64 | 更新ステップ数 |

### 出力先

モデルのtrainable_variablesが直接更新される。

## 処理フロー

### 処理シーケンス

```
1. minimize(loss, var_list) / apply_gradients(grads_and_vars)
   └─ 勾配の計算（minimizeの場合）
2. _create_slots(var_list)
   └─ momentum > 0の場合、各変数にmomentumスロットを作成
3. _prepare_local(var_device, var_dtype, apply_state)
   └─ momentum係数のテンソル変換
4. _resource_apply_dense(grad, var)
   └─ momentum使用時: ResourceApplyKerasMomentum
   └─ momentum未使用時: ResourceApplyGradientDescent
5. iterationのインクリメント
```

### フローチャート

```mermaid
flowchart TD
    A[勾配計算] --> B{momentum > 0?}
    B -->|No| C[w = w - lr * grad]
    B -->|Yes| D{nesterov?}
    D -->|No| E[v = momentum * v - lr * grad, w = w + v]
    D -->|Yes| F[v = momentum * v - lr * grad, w = w + momentum * v - lr * grad]
    C --> G[iteration++]
    E --> G
    F --> G
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-27-01 | モーメンタム範囲 | momentumは0-1の範囲内 | __init__時 |
| BR-27-02 | スロット作成条件 | momentum > 0の場合のみmomentumスロット作成 | _create_slots時 |
| BR-27-03 | 集約勾配 | _HAS_AGGREGATE_GRAD=Trueで勾配集約をサポート | 分散学習時 |

### 計算ロジック

- **基本SGD**: `w = w - learning_rate * g`
- **モーメンタム付き**: `v = momentum * v - learning_rate * g; w = w + v`
- **Nesterov**: `v = momentum * v - learning_rate * g; w = w + momentum * v - learning_rate * g`

## データベース操作仕様

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ValueError | 初期化エラー | momentumが0-1の範囲外 | 有効な範囲の値を指定 |

### リトライ仕様

該当なし。

## トランザクション仕様

該当なし。use_locking=Trueでスレッドセーフな更新が可能。

## パフォーマンス要件

- ResourceApplyKerasMomentum / ResourceApplyGradientDescent はC++カーネルで実装
- スパース勾配はResourceSparseApplyKerasMomentumで効率的に処理
- _HAS_AGGREGATE_GRAD=Trueにより分散学習での勾配集約が最適化

## セキュリティ考慮事項

特になし。

## 備考

- Nesterovモーメンタムの参照: Sutskever et al., 2013
- 後方互換のためlr引数も受け付ける（learning_rateの別名）

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: ベースクラスの構造

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | optimizer_v2.py | `tensorflow/python/keras/optimizer_v2/optimizer_v2.py` | OptimizerV2基底クラスのminimize/apply_gradients/add_slotメソッド |

**読解のコツ**: `_set_hyper`でハイパーパラメータを登録し、`_get_hyper`で取得する。`add_slot`で各変数に付随する状態変数（momentumなど）を作成する。

#### Step 2: SGDクラスの実装

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | gradient_descent.py | `tensorflow/python/keras/optimizer_v2/gradient_descent.py` | SGDクラス全体（25-150行目） |

**主要処理フロー**:
1. **98-116行目**: `__init__` - learning_rate, momentum, nesterovの設定。momentumが0超でself._momentum=True
2. **118-121行目**: `_create_slots` - momentum有効時のみmomentumスロット作成
3. **123-126行目**: `_prepare_local` - momentum係数のテンソル化
4. **128-148行目**: `_resource_apply_dense` - 実際のパラメータ更新
   - **133-142行目**: momentum有効時 → `ResourceApplyKerasMomentum`（use_nesterov付き）
   - **143-148行目**: momentum無効時 → `ResourceApplyGradientDescent`

### プログラム呼び出し階層図

```
optimizer.minimize(loss, var_list)
    │
    ├─ GradientTape.gradient(loss, var_list)
    │
    └─ optimizer.apply_gradients(grads_and_vars)
           │
           ├─ _create_slots(var_list)
           │      └─ add_slot(var, "momentum")  [momentum > 0時のみ]
           │
           ├─ _prepare_local(var_device, var_dtype, apply_state)
           │
           └─ _resource_apply_dense(grad, var) / _resource_apply_sparse(...)
                  ├─ gen_training_ops.ResourceApplyKerasMomentum  [momentum > 0]
                  └─ gen_training_ops.ResourceApplyGradientDescent [momentum = 0]
```

### データフロー図

```
[入力]                      [処理]                          [出力]

勾配 g            ───▶  SGD._resource_apply_dense    ───▶  更新後パラメータ w
現在のパラメータ w ───▶    ├─ momentum slot v                 更新後momentum v
learning_rate lr   ───▶    └─ gen_training_ops kernel
momentum coeff     ───▶
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| gradient_descent.py | `tensorflow/python/keras/optimizer_v2/gradient_descent.py` | ソース | SGDオプティマイザ実装 |
| optimizer_v2.py | `tensorflow/python/keras/optimizer_v2/optimizer_v2.py` | ソース | OptimizerV2基底クラス |
| gen_training_ops.py | (自動生成) | ソース | ResourceApplyKerasMomentum等のバインディング |
| training_ops.cc | `tensorflow/core/ops/training_ops.cc` | ソース | 学習用OpのC++定義 |
