# 機能設計書 32-Adamaxオプティマイザ

## 概要

本ドキュメントは、TensorFlow/Kerasにおける Adamax オプティマイザの機能設計を記載する。AdamaxはAdamオプティマイザのL-infinityノルムベースの変種であり、`tf.keras.optimizers.Adamax` として提供される。

### 本機能の処理概要

**業務上の目的・背景**：Adamオプティマイザを一般化したL-pノルムに基づく変種の中で、L-infinityノルムを用いたAdamaxは安定した動作を示す。特にエンベディングを含むモデルにおいて、Adamよりも優れた性能を発揮する場合がある。

**機能の利用シーン**：ニューラルネットワーク訓練において、Adamの代替として利用される。特にエンベディング層が多いモデルや、Adamの二次モーメント推定が不安定なケースで有効。

**主要な処理内容**：
1. 各パラメータに対して第1モーメント（m）と指数加重無限大ノルム（v）のスロットを作成
2. 密な勾配に対して `ResourceApplyAdaMax` C++カーネルで変数更新を実行
3. スパースな勾配に対してはPythonレベルで部分的なスロット更新とパラメータ更新を実行
4. beta_1のべき乗によるバイアス補正付き学習率を計算

**関連システム・外部連携**：OptimizerV2基底クラスを継承し、C++ `gen_training_ops` カーネルに密な更新処理を委譲する。

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

## 関連画面

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

## 機能種別

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

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| learning_rate | float / LearningRateSchedule | No | 学習率。デフォルト0.001 | 正の数値 |
| beta_1 | float | No | 第1モーメントの指数減衰率。デフォルト0.9 | 0.0〜1.0 |
| beta_2 | float | No | 無限大ノルムの指数減衰率。デフォルト0.999 | 0.0〜1.0 |
| epsilon | float | No | 数値安定性のための微小値。デフォルト1e-7 | 正の数値 |
| name | str | No | オプティマイザ名。デフォルト"Adamax" | - |

### 入力データソース

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

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 更新済み変数 | ResourceVariable | Adamaxアルゴリズムに従い更新されたモデルパラメータ |
| m | Tensor | 第1モーメント推定（各変数ごと） |
| v | Tensor | 指数加重無限大ノルム（各変数ごと） |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. __init__: ハイパーパラメータ設定
   └─ learning_rate, beta_1, beta_2, epsilonを登録
2. _create_slots: mとvのスロット変数を各パラメータに作成
3. _prepare_local: beta_1_power, neg_scaled_lrなど係数を事前計算
4. _resource_apply_dense: ResourceApplyAdaMaxカーネル呼び出し
5. _resource_apply_sparse: Python上でスライスベースの部分更新
   └─ m_t_slice = beta_1 * m_slice + (1-beta_1) * grad
   └─ v_t_slice = max(beta_2 * v_slice, abs(grad))
   └─ var_slice = -lr/(1-beta_1^t) * m_t_slice / (v_t_slice + eps)
```

### フローチャート

```mermaid
flowchart TD
    A[apply_gradients呼び出し] --> B[_create_slots: m, vスロット作成]
    B --> C[_prepare_local: beta_1_power等の計算]
    C --> D{勾配の種別}
    D -->|Dense| E[_resource_apply_dense]
    D -->|Sparse| F[_resource_apply_sparse]
    E --> G[ResourceApplyAdaMax C++ Kernel]
    F --> H[gather/scatter によるスライス更新]
    G --> I[変数更新完了]
    H --> I
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-32-1 | Adamax更新則 | m_t = beta_1 * m + (1-beta_1) * g; v_t = max(beta_2 * v, abs(g)); w -= (lr/(1-beta_1^t)) * m_t / (v_t + eps) | 全パラメータ更新時 |
| BR-32-2 | スパース更新 | スパース勾配の場合、該当するスライスのみm, vを更新 | IndexedSlices勾配の場合 |

### 計算ロジック

Adamax更新式（Kingma et al., 2014 Section 7.1）:
```
t += 1
m_t = beta_1 * m_{t-1} + (1 - beta_1) * g_t
v_t = max(beta_2 * v_{t-1}, |g_t|)
current_lr = learning_rate / (1 - beta_1^t)
w_t = w_{t-1} - current_lr * m_t / (v_t + epsilon)
```

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

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

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| TypeError | 型エラー | learning_rateに不正な型が指定された | float値またはLearningRateScheduleインスタンスを指定 |

### リトライ仕様

リトライは不要。

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

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

## パフォーマンス要件

- 密な勾配はC++カーネルで高速処理
- スパース勾配はPythonレベルで処理されるため、密な場合より低速
- `_HAS_AGGREGATE_GRAD = True` により効率的な勾配集約

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

特になし。

## 備考

- 参照論文: Kingma et al., 2014 (http://arxiv.org/abs/1412.6980)

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | optimizer_v2.py | `tensorflow/python/keras/optimizer_v2/optimizer_v2.py` | add_slot, _set_hyper, apply_gradientsの仕組み |

**読解のコツ**: `_prepare_local` はデバイスとデータ型の組み合わせごとに事前計算された係数を `apply_state` 辞書に格納する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | adamax.py | `tensorflow/python/keras/optimizer_v2/adamax.py` | Adamaxクラスの全体構造 |

**主要処理フロー**:
1. **88-100行目**: `__init__`でハイパーパラメータを設定
2. **102-107行目**: `_create_slots`でm, vスロットを作成
3. **109-130行目**: `_prepare_local`でneg_scaled_lr, beta_1_power等を計算
4. **132-149行目**: `_resource_apply_dense`でResourceApplyAdaMaxカーネル呼び出し
5. **151-176行目**: `_resource_apply_sparse`でスライスベースの更新処理

#### Step 3: スパース更新の詳細

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | adamax.py | `tensorflow/python/keras/optimizer_v2/adamax.py` | _resource_apply_sparse（151-176行目） |

**主要処理フロー**:
- **157-162行目**: m_t_sliceの計算とscatter_update
- **165-170行目**: v_t_sliceの計算（max操作）とscatter_update
- **172-176行目**: var_sliceの計算とscatter_add

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

```
tf.keras.optimizers.Adamax (adamax.py)
    |
    +-- OptimizerV2.minimize() / apply_gradients()
    |       |
    |       +-- Adamax._create_slots() -> m, v
    |       +-- Adamax._prepare_local() -> neg_scaled_lr, beta_1_power
    |       +-- Adamax._resource_apply_dense()
    |       |       +-- gen_training_ops.ResourceApplyAdaMax (C++)
    |       +-- Adamax._resource_apply_sparse()
    |               +-- array_ops.gather / _resource_scatter_update / _resource_scatter_add
    |               +-- control_flow_ops.group
    |
    +-- Adamax.get_config() -> dict
```

### データフロー図

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

勾配テンソル -------> Adamax._resource_apply_dense -------> 更新済み変数
                          |                                  更新済みm
                          v                                  更新済みv
                     ResourceApplyAdaMax (C++)
                          |
var, m, v, beta_1_power, lr, beta_1, beta_2, epsilon -> |
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| adamax.py | `tensorflow/python/keras/optimizer_v2/adamax.py` | ソース | Adamaxオプティマイザの主実装 |
| optimizer_v2.py | `tensorflow/python/keras/optimizer_v2/optimizer_v2.py` | ソース | OptimizerV2基底クラス |
| training_ops.cc | `tensorflow/core/ops/training_ops.cc` | ソース | ResourceApplyAdaMax Op定義 |
| backend_config.py | `tensorflow/python/keras/backend_config.py` | ソース | epsilonデフォルト値 |
