# 機能設計書 29-Adagradオプティマイザ

## 概要

本ドキュメントは、TensorFlow/KerasにおけるAdagradオプティマイザの機能設計を記述する。パラメータごとの学習率適応を行うAdagradアルゴリズムを提供する。

### 本機能の処理概要

**業務上の目的・背景**：Adagradは、各パラメータの過去の勾配の二乗の累積に基づいて学習率を自動調整するオプティマイザである。更新頻度の低いパラメータには大きな学習率を、頻繁に更新されるパラメータには小さな学習率を適用する。これにより、スパースな特徴量を持つデータ（自然言語処理、推薦システムなど）での学習が効率化される。

**機能の利用シーン**：スパースな特徴量を持つデータセット（テキスト分類、クリック率予測、推薦システム）での学習に特に適している。埋め込み層の学習で効果的。学習率の手動調整が困難な場合にも有用。

**主要な処理内容**：
1. 勾配の二乗の累積（accumulator）の更新
2. パラメータごとの適応的学習率の計算
3. パラメータ更新
4. スパース勾配の効率的な処理
5. 初期アキュムレータ値の設定

**関連システム・外部連携**：損失関数（No.40）、自動微分（No.37）と連携。

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

## 関連画面

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

## 機能種別

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

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| learning_rate | float/Schedule | No | 初期学習率 | デフォルト: 0.001 |
| initial_accumulator_value | float | No | アキュムレータの初期値 | >= 0.0、デフォルト: 0.1 |
| epsilon | float | No | 数値安定性のための小定数 | デフォルト: 1e-7 |

### 入力データソース

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

## 出力仕様

### 出力データ

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

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. _create_slots(var_list)
   └─ 各変数にaccumulatorスロット作成（initial_accumulator_valueで初期化）
2. _prepare_local(var_device, var_dtype, apply_state)
   └─ epsilon, neg_lr_tのテンソル変換
3. _resource_apply_dense(grad, var)
   └─ ResourceApplyAdagradV2呼び出し
4. _resource_apply_sparse(grad, var, indices)
   └─ ResourceSparseApplyAdagradV2呼び出し
```

### フローチャート

```mermaid
flowchart TD
    A[勾配 g] --> B[accumulator += g^2]
    B --> C[adjusted_lr = lr / (sqrt(accumulator) + epsilon)]
    C --> D[w = w - adjusted_lr * g]
    D --> E[iteration++]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-29-01 | 初期アキュムレータ | initial_accumulator_valueは非負 | __init__時 |
| BR-29-02 | アキュムレータ初期化 | constant_initializerで指定値に初期化 | _create_slots時 |
| BR-29-03 | V1互換 | from_configでinitial_accumulator_value未設定時は0.1 | デシリアライズ時 |
| BR-29-04 | 学習率推奨 | Adagradは他のオプティマイザより高い初期学習率が推奨 | チューニング時 |

### 計算ロジック

$$accum_t = accum_{t-1} + g_t^2$$
$$\theta_t = \theta_{t-1} - \frac{lr}{\sqrt{accum_t} + \epsilon} \cdot g_t$$

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ValueError | 初期化エラー | initial_accumulator_valueが負 | 非負の値を指定 |

### リトライ仕様

該当なし。

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

該当なし。

## パフォーマンス要件

- ResourceApplyAdagradV2はC++融合カーネルで実装
- スパース勾配はResourceSparseApplyAdagradV2で効率処理
- _HAS_AGGREGATE_GRAD=Trueで勾配集約を最適化

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

特になし。

## 備考

- 論文: Duchi et al., 2011
- アキュムレータは単調増加するため、学習が進むと実効学習率が非常に小さくなる欠点がある
- 論文の正確な形式を再現するにはlearning_rate=1.0を使用
- set_weightsのV1後方互換: iterationを含まない重みリストに対応

---

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

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

### 推奨読解順序

#### Step 1: 初期化とスロット作成

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | adagrad.py | `tensorflow/python/keras/optimizer_v2/adagrad.py` | __init__（65-80行目）: initial_accumulator_valueの検証とハイパーパラメータ設定 |
| 1-2 | adagrad.py | `tensorflow/python/keras/optimizer_v2/adagrad.py` | _create_slots（82-87行目）: constant_initializerでaccumulatorスロット作成 |

**読解のコツ**: `init_ops.constant_initializer(self._initial_accumulator_value, dtype=dtype)`（85-86行目）で各変数のdtypeに応じた初期化子を作成。これによりアキュムレータの初期値が設定される。

#### Step 2: 密勾配の適用

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | adagrad.py | `tensorflow/python/keras/optimizer_v2/adagrad.py` | _prepare_local（89-99行目）: epsilon, neg_lr_tの準備 |
| 2-2 | adagrad.py | `tensorflow/python/keras/optimizer_v2/adagrad.py` | _resource_apply_dense（133-145行目）: ResourceApplyAdagradV2呼び出し |

**主要処理フロー**:
- **138行目**: accumulatorスロットの取得
- **139-145行目**: ResourceApplyAdagradV2にvar, accum, lr, epsilon, gradを渡して更新

#### Step 3: スパース勾配の適用

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | adagrad.py | `tensorflow/python/keras/optimizer_v2/adagrad.py` | _resource_apply_sparse（147-150行目以降） |

#### Step 4: V1後方互換

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | adagrad.py | `tensorflow/python/keras/optimizer_v2/adagrad.py` | set_weights（101-108行目）: iterationなしの重みリスト対応 |
| 4-2 | adagrad.py | `tensorflow/python/keras/optimizer_v2/adagrad.py` | from_config（110-131行目）: initial_accumulator_valueのデフォルト補完 |

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

```
optimizer.apply_gradients(grads_and_vars)
    │
    ├─ _create_slots(var_list)
    │      └─ add_slot(var, 'accumulator', constant_init(0.1))
    │
    ├─ _prepare_local()
    │      └─ epsilon, neg_lr_tの準備
    │
    └─ _resource_apply_dense / _resource_apply_sparse
           ├─ gen_training_ops.ResourceApplyAdagradV2      [dense]
           └─ gen_training_ops.ResourceSparseApplyAdagradV2 [sparse]
```

### データフロー図

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

勾配 g              ───▶  Adagrad._resource_apply      ───▶  更新後 w
パラメータ w         ───▶    ├─ accum += g^2                   更新後 accum
accumulator         ───▶    └─ w -= lr/(sqrt(accum)+eps)*g
learning_rate       ───▶
```

### 関連ファイル一覧

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