# 機能設計書 36-訓練操作（Training Operations）

## 概要

本ドキュメントは、TensorFlowにおける訓練操作（Training Operations）の機能設計を記載する。訓練操作はモデルパラメータの更新を行う低レベルC++ Opsの集合体であり、`tensorflow/core/ops/training_ops.cc` で定義される。

### 本機能の処理概要

**業務上の目的・背景**：各種オプティマイザ（SGD、Adam、Adagrad、Adadelta、FTRL等）がモデルパラメータを更新するためのアトミックな計算操作を提供する。これらの操作はC++で実装されており、Python側のオプティマイザから呼び出される低レベルカーネルとして機能する。

**機能の利用シーン**：Keras OptimizerV2の `_resource_apply_dense` および `_resource_apply_sparse` メソッドから `gen_training_ops` モジュール経由で呼び出される。直接ユーザが使用することは通常ない。

**主要な処理内容**：
1. 各オプティマイザアルゴリズムに対応するApply系Opの定義（Shape推論関数含む）
2. Dense版（全要素更新）とSparse版（インデックス指定の部分更新）の両方を提供
3. Ref変数版とResource変数版の両方を提供（Resource版が推奨）
4. `use_locking` 属性による排他制御のサポート

**関連システム・外部連携**：Python側の `gen_training_ops` モジュール（自動生成）を介してKeras OptimizerV2から呼び出される。CUDA/ROCm等のGPUカーネルでも実装されており、デバイス透過的に利用可能。

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

## 関連画面

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

## 機能種別

計算処理（低レベルOp定義）

## 入力仕様

### 主要Opの入力パラメータ

#### ApplyGradientDescent / ResourceApplyGradientDescent

| パラメータ名 | 型 | 必須 | 説明 |
|-------------|-----|-----|------|
| var | Ref(T) / resource | Yes | 更新対象の変数 |
| alpha | T | Yes | 学習率（スカラー） |
| delta | T | Yes | 勾配テンソル |

#### ApplyAdadelta / ResourceApplyAdadelta

| パラメータ名 | 型 | 必須 | 説明 |
|-------------|-----|-----|------|
| var | Ref(T) / resource | Yes | 更新対象の変数 |
| accum | Ref(T) / resource | Yes | 勾配蓄積変数 |
| accum_update | Ref(T) / resource | Yes | 更新量蓄積変数 |
| lr | T | Yes | 学習率（スカラー） |
| rho | T | Yes | 減衰率（スカラー） |
| epsilon | T | Yes | 安定性用の微小値（スカラー） |
| grad | T | Yes | 勾配テンソル |

#### ApplyAdagrad / ResourceApplyAdagrad

| パラメータ名 | 型 | 必須 | 説明 |
|-------------|-----|-----|------|
| var | Ref(T) / resource | Yes | 更新対象の変数 |
| accum | Ref(T) / resource | Yes | 蓄積変数 |
| lr | T | Yes | 学習率（スカラー） |
| grad | T | Yes | 勾配テンソル |

### 共通属性

| 属性名 | 型 | デフォルト | 説明 |
|--------|-----|----------|------|
| T | type | - | 数値型（numbertype） |
| use_locking | bool | false | 排他制御の有効/無効 |
| Tindices | type | - | Sparse版でのインデックス型（int32/int64） |

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| out | Ref(T) | 更新済みの変数（Ref変数版のみ） |
| なし | - | Resource変数版は出力なし（インプレース更新） |

### 出力先

変数へのインプレース更新。

## 処理フロー

### 処理シーケンス

```
1. Op登録（REGISTER_OP）でOp定義とShape推論関数を紐付け
2. C++カーネル実装が各デバイス（CPU, GPU）で変数更新を実行
3. Shape推論関数が入力の形状整合性を検証
4. use_lockingがTrueの場合、変数のmutexをロックして更新
```

### フローチャート

```mermaid
flowchart TD
    A[Python: gen_training_ops.ResourceApplyXxx] --> B[TF Op Dispatch]
    B --> C{デバイス}
    C -->|CPU| D[CPU Kernel]
    C -->|GPU| E[GPU Kernel]
    D --> F{use_locking?}
    E --> F
    F -->|True| G[mutex lock取得]
    F -->|False| H[ロックなし]
    G --> I[変数更新計算]
    H --> I
    I --> J[完了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-36-1 | Shape推論 | var, accum等の形状が一致することを検証。lr, rho, epsilon等のスカラーはrank=0を検証 | 全Op |
| BR-36-2 | Sparse版インデックス | indices.dim[0] == grad.dim[0] を検証 | Sparse版Op |
| BR-36-3 | Resource版の推奨 | Resource変数版（ResourceApplyXxx）が推奨。Ref変数版は後方互換 | 全Op |
| BR-36-4 | ShapeOrHandleShape | Resource変数の場合、ハンドルデータから形状を推論。形状不明時はUnknownShapeを返す | Resource版Op |

### 登録されている主要Op一覧

| Op名 | アルゴリズム | Sparse版 | Resource版 |
|------|------------|---------|-----------|
| ApplyGradientDescent | SGD | - | ResourceApplyGradientDescent |
| ApplyProximalGradientDescent | Proximal SGD | SparseApplyProximalGradientDescent | ResourceApplyProximalGradientDescent |
| ApplyAdadelta | Adadelta | SparseApplyAdadelta | ResourceApplyAdadelta |
| ApplyAdagrad | Adagrad | SparseApplyAdagrad | ResourceApplyAdagrad |
| ApplyFtrl | FTRL | SparseApplyFtrl | ResourceApplyFtrl |
| ApplyFtrlV2 | FTRL V2 | SparseApplyFtrlV2 | ResourceApplyFtrlV2 |
| ApplyAdam | Adam | - | ResourceApplyAdam |
| ApplyAdaMax | AdaMax | - | ResourceApplyAdaMax |

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

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

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| InvalidArgument | Shape不一致 | var, accum等の形状が一致しない | 同一形状の変数を使用 |
| InvalidArgument | Rank不正 | スカラー入力のrankが0でない | スカラーテンソルを渡す |
| InvalidArgument | gradがスカラー | Sparse版でgradがスカラーの場合 | 1次元以上のテンソルを渡す |

### リトライ仕様

リトライは不要。

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

`use_locking=true` により、変数の更新をアトミックに実行可能。

## パフォーマンス要件

- C++で実装されているため、Pythonオーバーヘッドは最小
- GPU版はCUDAカーネルとして実装され、大規模テンソルでも高速処理
- Sparse版はインデックスされた部分のみを更新するため、スパースデータに効率的

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

特になし。

## 備考

- `training_ops.cc` はOp定義のみであり、実際のカーネル実装は `training_ops.h` および各デバイス固有の実装ファイルに存在する

---

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

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

### 推奨読解順序

#### Step 1: テンプレートとユーティリティ関数

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | training_ops.cc | `tensorflow/core/ops/training_ops.cc` | ShapeOrHandleShape関数テンプレート |

**主要処理フロー**:
1. **25-46行目**: `ShapeOrHandleShape<is_resource>` テンプレートと特殊化。Resource変数の場合はhandle_dataから形状取得、不明時はUnknownShape返却
2. **51-76行目**: `HandleGradAndIndicesInputs<is_sparse, is_resource>` テンプレート。Sparse版のインデックスと勾配の形状検証
3. **78-88行目**: `ApplyGradientDescentShapeFn` 最もシンプルなShape推論関数の例

**読解のコツ**: 各OpのShape推論関数は `<is_sparse, is_resource>` テンプレートパラメータを持つ。`is_sparse=true` の場合は `HandleGradAndIndicesInputs` がインデックスの検証を追加で行う。

#### Step 2: 各アルゴリズムのOp定義

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | training_ops.cc | `tensorflow/core/ops/training_ops.cc` | REGISTER_OPマクロの使用パターン |

**主要処理フロー**:
- **90-105行目**: ApplyGradientDescent / ResourceApplyGradientDescent
- **172-246行目**: ApplyAdadelta系（4つのOp）
- **248-310行目**: ApplyAdagrad系

#### Step 3: Python側の自動生成コード

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | gen_training_ops.py | `tensorflow/python/ops/gen_training_ops.py`（自動生成） | Python側のラッパー関数 |

**読解のコツ**: `gen_training_ops.py` はprotobuf Op定義から自動生成される。各関数はC++ Opへの直接ディスパッチを行う。

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

```
Python: OptimizerV2._resource_apply_dense()
    |
    +-- gen_training_ops.resource_apply_adadelta(...)
        |
        +-- TF C++ Op Dispatch
            |
            +-- ApplyAdadeltaShapeFn() -> Shape推論
            |
            +-- training_ops.h -> ApplyAdadelta Kernel実装
                |
                +-- CPU: training_ops.cc (kernel)
                +-- GPU: training_ops_gpu.cu.cc (kernel)
```

### データフロー図

```
[Python側]                    [C++ Op層]              [カーネル層]

optimizer._resource_apply_*   REGISTER_OP             Kernel実装
        |                     Shape推論               var更新
        v                         |                       |
gen_training_ops.resource_*   ShapeOrHandleShape     CPU/GPU演算
        |                     HandleGradAndIndices         |
        v                         |                       v
    TF Runtime ----------------> Op実行 ----------------> 結果
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| training_ops.cc | `tensorflow/core/ops/training_ops.cc` | ソース | Op定義とShape推論（約800行） |
| gen_training_ops.py | `tensorflow/python/ops/gen_training_ops.py` | 自動生成 | Python側ラッパー |
| optimizer_v2.py | `tensorflow/python/keras/optimizer_v2/optimizer_v2.py` | ソース | 呼び出し元（OptimizerV2基底クラス） |
| adadelta.py | `tensorflow/python/keras/optimizer_v2/adadelta.py` | ソース | Adadeltaオプティマイザ（呼び出し例） |
| adam.py | `tensorflow/python/keras/optimizer_v2/adam.py` | ソース | Adamオプティマイザ（呼び出し例） |
