# 機能設計書 33-Nadamオプティマイザ

## 概要

本ドキュメントは、TensorFlow/Kerasにおける Nadam（Nesterov-accelerated Adaptive Moment estimation）オプティマイザの機能設計を記載する。NadamはAdamにNesterovモーメンタムを組み合わせたオプティマイザであり、`tf.keras.optimizers.Nadam` として提供される。

### 本機能の処理概要

**業務上の目的・背景**：AdamがRMSpropにモーメンタムを加えたものであるのと同様に、NadamはAdamにNesterovモーメンタムを加えたものである。Nesterovモーメンタムにより、勾配降下の先読み効果が得られ、収束速度の向上が期待できる。

**機能の利用シーン**：Adamよりも収束速度を改善したい場合に利用される。RNN系のモデルや、Nesterovモーメンタムの恩恵を受けやすいアーキテクチャでの訓練に適している。

**主要な処理内容**：
1. 各パラメータに対して第1モーメント（m）と第2モーメント（v）のスロット、およびモーメンタムキャッシュ変数を作成
2. モーメンタムスケジュールを用いたバイアス補正付きの更新を実行
3. 密な勾配・スパースな勾配それぞれに対して、Python上でNesterov型更新式を適用
4. LearningRateScheduleは未サポート（使用時にValueError発生）

**関連システム・外部連携**：OptimizerV2基底クラスを継承。全ての更新処理はPythonレベルで`state_ops.assign` を使用。

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

## 関連画面

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

## 機能種別

計算処理（最適化アルゴリズム）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| learning_rate | float | No | 学習率。デフォルト0.001 | 正の数値。LearningRateScheduleは不可 |
| beta_1 | float | No | 第1モーメントの指数減衰率。デフォルト0.9 | 0.0〜1.0 |
| beta_2 | float | No | 第2モーメントの指数減衰率。デフォルト0.999 | 0.0〜1.0 |
| epsilon | float | No | 数値安定性のための微小値。デフォルト1e-7 | 正の数値 |
| name | str | No | オプティマイザ名。デフォルト"Nadam" | - |
| schedule_decay | float | No | Keras互換のスケジュール減衰。デフォルト0.004 | - |

### 入力データソース

- モデルの勾配テンソル
- モデルの訓練可能な変数

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 更新済み変数 | ResourceVariable | Nadamアルゴリズムに従い更新されたモデルパラメータ |
| m | Tensor | 第1モーメント推定 |
| v | Tensor | 第2モーメント推定 |
| momentum_cache | Variable | モーメンタムスケジュールキャッシュ |

### 出力先

モデルの訓練可能な変数へインプレース更新。

## 処理フロー

### 処理シーケンス

```
1. __init__: ハイパーパラメータ設定
   └─ LearningRateScheduleチェック（使用時はValueError）
   └─ schedule_decayをdecayとして設定
   └─ _m_cache = None で初期化
2. _create_slots: m, vスロットおよびmomentum_cache変数を作成
3. _prepare: モーメンタムキャッシュの読み取り
4. _prepare_local: m_t, m_t_1, m_schedule_new等の係数計算
5. _resource_apply_dense: Nesterov型の密な勾配更新
   └─ g_prime, m_t, m_t_prime, v_t, v_t_prime, m_t_barの順に計算
6. _resource_apply_sparse: スパース勾配に対する部分更新
```

### フローチャート

```mermaid
flowchart TD
    A[apply_gradients呼び出し] --> B[_create_slots: m, v, momentum_cache]
    B --> C[_prepare: m_cache読み取り]
    C --> D[_prepare_local: 係数計算]
    D --> E{勾配の種別}
    E -->|Dense| F[_resource_apply_dense]
    E -->|Sparse| G[_resource_apply_sparse]
    F --> H[state_ops.assign による変数更新]
    G --> I[scatter_add による部分更新]
    H --> J[完了]
    I --> J
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-33-1 | LearningRateSchedule非対応 | LearningRateScheduleインスタンスが渡された場合はValueError | 初期化時 |
| BR-33-2 | Nadam更新則 | g' = g/(1-m_schedule); m_t = beta_1*m + (1-beta_1)*g; m_t' = m_t/(1-m_schedule_next); v_t = beta_2*v + (1-beta_2)*g^2; v_t' = v_t/(1-beta_2^t); m_bar = (1-m_t)*g' + m_t_1*m_t'; var -= lr * m_bar / (sqrt(v_t') + eps) | 全パラメータ更新時 |
| BR-33-3 | モーメンタムスケジュール | m_t = beta_1 * (1 - 0.5 * 0.96^(decay*step)) により時間変化 | 各ステップ |

### 計算ロジック

Nadam更新式（Dozat, 2015）:
```
m_schedule_t = m_schedule_{t-1} * mu_t
g'_t = g_t / (1 - m_schedule_t)
m_t = beta_1 * m_{t-1} + (1 - beta_1) * g_t
m'_t = m_t / (1 - m_schedule_{t+1})
v_t = beta_2 * v_{t-1} + (1 - beta_2) * g_t^2
v'_t = v_t / (1 - beta_2^t)
m_bar_t = (1 - mu_t) * g'_t + mu_{t+1} * m'_t
theta_t = theta_{t-1} - lr * m_bar_t / (sqrt(v'_t) + epsilon)
```

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

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | データベース操作なし |

### テーブル別操作詳細

データベース操作は発生しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ValueError | パラメータエラー | LearningRateScheduleが指定された | 固定のfloat値を指定する |

### リトライ仕様

リトライは不要。

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

`use_locking` フラグによる変数更新時の排他制御が可能。

## パフォーマンス要件

- C++カーネルへの委譲は行わず、全てPythonレベルでstate_ops.assignを使用
- `_HAS_AGGREGATE_GRAD = True`

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

特になし。

## 備考

- 参照論文: Dozat, 2015 (http://cs229.stanford.edu/proj2015/054_report.pdf)
- Keras NAdamオプティマイザとの後方互換性のためschedule_decayパラメータをサポート

---

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

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

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | nadam.py | `tensorflow/python/keras/optimizer_v2/nadam.py` | momentum_cacheの役割とスロット変数m, v |

**読解のコツ**: `_m_cache` はモーメンタムスケジュールの累積積を保持する特別な重み変数。`_prepare` メソッドで読み取り、`_prepare_local` で更新される。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | nadam.py | `tensorflow/python/keras/optimizer_v2/nadam.py` | Nadamクラスの初期化と制約事項 |

**主要処理フロー**:
1. **63-84行目**: `__init__`でLearningRateScheduleチェック、schedule_decay互換処理
2. **86-103行目**: `_create_slots`でmomentum_cache、m、vを作成
3. **105-141行目**: `_prepare_local`で複雑なモーメンタムスケジュール係数を計算
4. **143-146行目**: `_prepare`でm_cacheの現在値を読み取り
5. **148-169行目**: `_resource_apply_dense`でNesterov型更新
6. **171-209行目**: `_resource_apply_sparse`でスパース版Nesterov更新

#### Step 3: 密な勾配の更新ロジック

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | nadam.py | `tensorflow/python/keras/optimizer_v2/nadam.py` | _resource_apply_dense（148-169行目） |

**主要処理フロー**:
- **156行目**: g_prime = grad / one_minus_m_schedule_new
- **157-159行目**: m_t計算とassign
- **160行目**: m_t_prime = m_t / one_minus_m_schedule_next
- **161-164行目**: v_t計算とassign
- **165-166行目**: m_t_bar = (1-m_t)*g_prime + m_t_1*m_t_prime
- **167-169行目**: var更新

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

```
tf.keras.optimizers.Nadam (nadam.py)
    |
    +-- OptimizerV2.minimize() / apply_gradients()
    |       |
    |       +-- Nadam._prepare()  -> _m_cache_read
    |       +-- Nadam._create_slots() -> m, v, momentum_cache
    |       +-- Nadam._prepare_local() -> m_t, m_t_1, m_schedule_new, ...
    |       +-- Nadam._resource_apply_dense()
    |       |       +-- state_ops.assign (m, v, var)
    |       +-- Nadam._resource_apply_sparse()
    |               +-- state_ops.assign / _resource_scatter_add
    |               +-- control_flow_ops.group
    |
    +-- Nadam.get_config() -> dict
```

### データフロー図

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

勾配テンソル -------> _prepare_local
                          |
                     モーメンタムスケジュール計算
                          |
                     _resource_apply_dense             更新済み変数
                          |                            更新済みm
                     g_prime -> m_t -> m_t_prime       更新済みv
                     -> v_t -> v_t_prime -> m_t_bar    更新済みmomentum_cache
                     -> var更新
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| nadam.py | `tensorflow/python/keras/optimizer_v2/nadam.py` | ソース | Nadamオプティマイザの主実装 |
| optimizer_v2.py | `tensorflow/python/keras/optimizer_v2/optimizer_v2.py` | ソース | OptimizerV2基底クラス |
| learning_rate_schedule.py | `tensorflow/python/keras/optimizer_v2/learning_rate_schedule.py` | ソース | LearningRateSchedule（互換チェック用） |
| state_ops.py | `tensorflow/python/ops/state_ops.py` | ソース | 変数のassign操作 |
| control_flow_ops.py | `tensorflow/python/ops/control_flow_ops.py` | ソース | 操作グループ化 |
