# 機能設計書 34-FTRLオプティマイザ

## 概要

本ドキュメントは、TensorFlow/Kerasにおける FTRL（Follow-The-Regularized-Leader）オプティマイザの機能設計を記載する。FTRLはGoogleで開発されたCTR（クリック率）予測向けの最適化アルゴリズムであり、`tf.keras.optimizers.Ftrl` として提供される。

### 本機能の処理概要

**業務上の目的・背景**：FTRLは大規模かつスパースな特徴空間を持つ浅いモデル（線形モデルなど）のために設計された。オンライン学習でL1/L2正則化を効率的に適用でき、重みのスパース化を促進する。広告CTR予測やレコメンデーションシステムなどの産業応用で広く使われている。

**機能の利用シーン**：大規模なスパース特徴量を扱う線形モデルやワイド部分の訓練。特にWide & DeepモデルのWide部分でL1正則化によるスパースな重みが必要な場合に最適。

**主要な処理内容**：
1. 各パラメータに対してaccumulator（蓄積変数）とlinear（線形変数）のスロットを作成
2. L1正則化、L2正則化、L2シュリンケージ正則化をサポート
3. シュリンケージなしの場合は `ResourceApplyFtrl`、ありの場合は `ResourceApplyFtrlV2` カーネルを使い分ける
4. 学習率のべき乗制御（learning_rate_power）によるアダプティブな学習率調整

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

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

## 関連画面

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

## 機能種別

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

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| learning_rate | float / LearningRateSchedule | No | 学習率。デフォルト0.001 | 正の数値 |
| learning_rate_power | float | No | 学習率減衰のべき乗。デフォルト-0.5 | 0以下 |
| initial_accumulator_value | float | No | 蓄積変数の初期値。デフォルト0.1 | 0以上 |
| l1_regularization_strength | float | No | L1正則化強度。デフォルト0.0 | 0以上 |
| l2_regularization_strength | float | No | L2正則化強度。デフォルト0.0 | 0以上 |
| l2_shrinkage_regularization_strength | float | No | L2シュリンケージ正則化強度。デフォルト0.0 | 0以上 |
| beta | float | No | ベータパラメータ。デフォルト0.0 | - |
| name | str | No | オプティマイザ名。デフォルト"Ftrl" | - |

### 入力データソース

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

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 更新済み変数 | ResourceVariable | FTRLアルゴリズムに従い更新されたモデルパラメータ |
| accumulator | Tensor | 勾配の二乗和の蓄積 |
| linear | Tensor | 線形項の蓄積 |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. __init__: パラメータバリデーションとハイパーパラメータ設定
   └─ initial_accumulator_value >= 0, learning_rate_power <= 0,
      l1 >= 0, l2 >= 0, l2_shrinkage >= 0 を検証
2. _create_slots: accumulatorとlinearスロットを作成
   └─ accumulatorはinitial_accumulator_valueで初期化
3. _prepare_local: learning_rate_power等の係数をテンソル化
4. _resource_apply_dense:
   └─ adjusted_l2 = l2 + beta / (2 * lr) を計算
   └─ l2_shrinkage == 0: ResourceApplyFtrl
   └─ l2_shrinkage > 0: ResourceApplyFtrlV2
5. _resource_apply_sparse:
   └─ 同上のロジックでSparse版カーネルを使用
```

### フローチャート

```mermaid
flowchart TD
    A[apply_gradients呼び出し] --> B[_create_slots: accumulator, linear]
    B --> C[_prepare_local: 係数テンソル化]
    C --> D{勾配の種別}
    D -->|Dense| E[_resource_apply_dense]
    D -->|Sparse| F[_resource_apply_sparse]
    E --> G{l2_shrinkage > 0?}
    F --> H{l2_shrinkage > 0?}
    G -->|No| I[ResourceApplyFtrl]
    G -->|Yes| J[ResourceApplyFtrlV2]
    H -->|No| K[ResourceSparseApplyFtrl]
    H -->|Yes| L[ResourceSparseApplyFtrlV2]
    I --> M[変数更新完了]
    J --> M
    K --> M
    L --> M
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-34-1 | FTRL更新則 | n_t = n_{t-1} + g^2; sigma = (sqrt(n_t) - sqrt(n_{t-1})) / lr; z_t = z_{t-1} + g - sigma * w; w = 0 if |z| < lambda_1 else (sgn(z)*lambda_1 - z) / ((beta + sqrt(n)) / alpha + lambda_2) | 全パラメータ更新時 |
| BR-34-2 | L2調整 | adjusted_l2 = l2 + beta / (2 * lr) としてbetaをl2に組み込む | 全パラメータ更新時 |
| BR-34-3 | FtrlV2使い分け | l2_shrinkage > 0の場合のみFtrlV2カーネルを使用 | シュリンケージ正則化が有効時 |
| BR-34-4 | パラメータ制約 | initial_accumulator_value >= 0, learning_rate_power <= 0, l1 >= 0, l2 >= 0, l2_shrinkage >= 0 | 初期化時 |

### 計算ロジック

FTRL-Proximal更新式（McMahan et al., 2013）:
```
prev_n = n
n = n + g^2
sigma = (sqrt(n) - sqrt(prev_n)) / lr
z = z + g - sigma * w
if abs(z) < lambda_1:
    w = 0
else:
    w = (sign(z) * lambda_1 - z) / ((beta + sqrt(n)) / alpha + lambda_2)
```

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

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

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ValueError | パラメータエラー | initial_accumulator_value < 0 | 0以上の値を指定 |
| ValueError | パラメータエラー | learning_rate_power > 0 | 0以下の値を指定 |
| ValueError | パラメータエラー | l1_regularization_strength < 0 | 0以上の値を指定 |
| ValueError | パラメータエラー | l2_regularization_strength < 0 | 0以上の値を指定 |
| ValueError | パラメータエラー | l2_shrinkage_regularization_strength < 0 | 0以上の値を指定 |

### リトライ仕様

リトライは不要。

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

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

## パフォーマンス要件

- 全更新処理はC++カーネルに委譲されるため高速
- スパースデータに最適化されたアルゴリズム

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

特になし。

## 備考

- 参照論文: McMahan et al., 2013 (https://research.google.com/pubs/archive/41159.pdf)
- L2 shrinkage正則化はスパース入力で有効なマグニチュードペナルティ

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ftrl.py | `tensorflow/python/keras/optimizer_v2/ftrl.py` | accumulator, linearスロットの役割 |

**読解のコツ**: accumulatorは勾配の二乗の蓄積であり、学習率の適応調整に使用される。linearはFTRL特有のz変数に対応する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ftrl.py | `tensorflow/python/keras/optimizer_v2/ftrl.py` | Ftrlクラスの初期化とバリデーション |

**主要処理フロー**:
1. **100-140行目**: `__init__`で5つのバリデーションチェックとハイパーパラメータ設定
2. **142-149行目**: `_create_slots`でaccumulator（初期値付き）とlinearを作成
3. **151-163行目**: `_prepare_local`で各種正則化係数をテンソル化
4. **165-201行目**: `_resource_apply_dense`でadjusted_l2を計算し、Ftrl/FtrlV2を使い分け
5. **203-241行目**: `_resource_apply_sparse`で同様のロジック

#### Step 3: カーネル使い分けの判定

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ftrl.py | `tensorflow/python/keras/optimizer_v2/ftrl.py` | _resource_apply_dense内の条件分岐（179, 191行目） |

**主要処理フロー**:
- **172-174行目**: adjusted_l2の計算（l2 + beta / (2 * lr)）
- **179行目**: l2_shrinkage <= 0.0 の場合 ResourceApplyFtrl
- **191行目**: それ以外の場合 ResourceApplyFtrlV2（l2_shrinkageパラメータ追加）

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

```
tf.keras.optimizers.Ftrl (ftrl.py)
    |
    +-- OptimizerV2.minimize() / apply_gradients()
    |       |
    |       +-- Ftrl._create_slots() -> accumulator (初期値付き), linear
    |       +-- Ftrl._prepare_local() -> 正則化係数
    |       +-- Ftrl._resource_apply_dense()
    |       |       +-- gen_training_ops.ResourceApplyFtrl (C++)
    |       |       +-- gen_training_ops.ResourceApplyFtrlV2 (C++) [shrinkage時]
    |       +-- Ftrl._resource_apply_sparse()
    |               +-- gen_training_ops.ResourceSparseApplyFtrl (C++)
    |               +-- gen_training_ops.ResourceSparseApplyFtrlV2 (C++) [shrinkage時]
    |
    +-- Ftrl.get_config() -> dict
```

### データフロー図

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

勾配テンソル --------> Ftrl._resource_apply_dense
                           |
                      adjusted_l2計算              更新済み変数
                           |                       更新済みaccumulator
                      ResourceApplyFtrl(V2)        更新済みlinear
                           |
var, accum, linear,        |
lr, l1, l2, l2_shrinkage,  |
lr_power -> [C++ Kernel]   |
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ftrl.py | `tensorflow/python/keras/optimizer_v2/ftrl.py` | ソース | FTRLオプティマイザの主実装 |
| optimizer_v2.py | `tensorflow/python/keras/optimizer_v2/optimizer_v2.py` | ソース | OptimizerV2基底クラス |
| training_ops.cc | `tensorflow/core/ops/training_ops.cc` | ソース | ResourceApplyFtrl / FtrlV2 Op定義 |
| init_ops.py | `tensorflow/python/ops/init_ops.py` | ソース | accumulatorの定数初期化子 |
