# 通知設計書 13-LambdaCallback

## 概要

本ドキュメントは、TensorFlow Kerasの`LambdaCallback`コールバックの通知設計について記載する。このコールバックは、ユーザ定義のラムダ関数（無名関数）をトレーニングイベントの各フックポイントに対して実行する汎用的な通知機構である。

### 本通知の処理概要

`LambdaCallback`は、`on_epoch_begin`、`on_epoch_end`、`on_batch_begin`、`on_batch_end`、`on_train_begin`、`on_train_end`の各トレーニングイベントに対してユーザが任意のラムダ関数を登録し、イベント発生時にそれらを実行する。カスタムコールバッククラスを定義せずに、簡易的な通知ロジックを実装できる。

**業務上の目的・背景**：既存のコールバッククラスではカバーしきれないカスタム通知やアクションを、新たなクラス定義なしに簡潔に実装する手段を提供する。例えば、バッチ番号の出力、JSON形式でのログ記録、外部プロセスとの連携など、多様なユースケースに対応できる。

**通知の送信タイミング**：ユーザがコンストラクタで指定した各フックポイント（エポック開始/終了、バッチ開始/終了、トレーニング開始/終了）でラムダ関数が実行される。

**通知の受信者**：ユーザが定義したラムダ関数の出力先に依存する。コンソール出力、ファイル出力、外部API呼び出し、変数への格納など、任意の宛先が設定可能。

**通知内容の概要**：ユーザが定義したラムダ関数の内容に完全に依存する。フックに渡される引数（epoch/batch番号、logsメトリクス辞書）を基に任意の通知を生成できる。

**期待されるアクション**：ユーザ定義のラムダ関数に依存する。トレーニング進捗の監視、カスタムログの記録、外部システムへの通知、プロセスの制御など多岐にわたる。

## 通知種別

ユーザ定義（ラムダ関数の実装に依存：コンソール出力 / ファイル出力 / API呼び出し / その他任意）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（コールバック内でラムダ関数を直接呼び出し） |
| 優先度 | ユーザ定義に依存 |
| リトライ | 無し（ラムダ関数内で独自に実装可能） |

### 送信先決定ロジック

- ユーザがコンストラクタで渡すラムダ関数内で宛先が決定される
- LambdaCallback自体は送信先を制御しない

## 通知テンプレート

### ユーザ定義通知の場合

| 項目 | 内容 |
|-----|------|
| フォーマット | ユーザ定義 |
| 出力先 | ユーザ定義 |

### 本文テンプレート

ドキュメントに記載されている使用例：

```python
# バッチ番号の出力
batch_print_callback = LambdaCallback(
    on_batch_begin=lambda batch, logs: print(batch))

# エポックlossのJSON出力
json_logging_callback = LambdaCallback(
    on_epoch_end=lambda epoch, logs: json_log.write(
        json.dumps({'epoch': epoch, 'loss': logs['loss']}) + '\n'),
    on_train_end=lambda logs: json_log.close())

# プロセスの終了処理
cleanup_callback = LambdaCallback(
    on_train_end=lambda logs: [
        p.terminate() for p in processes if p.is_alive()])
```

### 添付ファイル

該当なし（ユーザ定義に依存）

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| epoch | エポック番号 | Kerasトレーニングループ | Yes（on_epoch_begin/endの場合） |
| batch | バッチ番号 | Kerasトレーニングループ | Yes（on_batch_begin/endの場合） |
| logs | メトリクス辞書 | Kerasトレーニングループ | Yes（全フック） |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| コールバック | `on_epoch_begin` | ラムダ関数が登録されている場合 | エポック開始時にlambda(epoch, logs)を実行 |
| コールバック | `on_epoch_end` | ラムダ関数が登録されている場合 | エポック終了時にlambda(epoch, logs)を実行 |
| コールバック | `on_batch_begin` | ラムダ関数が登録されている場合 | バッチ開始時にlambda(batch, logs)を実行 |
| コールバック | `on_batch_end` | ラムダ関数が登録されている場合 | バッチ終了時にlambda(batch, logs)を実行 |
| コールバック | `on_train_begin` | ラムダ関数が登録されている場合 | トレーニング開始時にlambda(logs)を実行 |
| コールバック | `on_train_end` | ラムダ関数が登録されている場合 | トレーニング終了時にlambda(logs)を実行 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| ラムダ関数がNone | 各フックにNoneが指定された場合、no-opラムダ（`lambda ...: None`）が設定されるため、何も出力されない |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[トレーニングイベント発火] --> B{該当フックにラムダ登録済み?}
    B -->|Yes（ユーザ定義）| C[ラムダ関数実行]
    B -->|No（デフォルトno-op）| D[lambda returns None]
    C --> E[ラムダ関数の出力に依存]
    D --> F[終了]
    E --> F
```

## データベース参照・更新仕様

### 参照テーブル一覧

該当なし（データベースを使用しない。ユーザのラムダ関数内で任意のアクセスは可能）

### 更新テーブル一覧

該当なし（ユーザのラムダ関数内で任意の更新は可能）

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| ラムダ関数内例外 | ユーザ定義ラムダで例外が発生した場合 | 例外はトレーニングループに伝播し、トレーニングが停止する可能性がある |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0（リトライなし。ユーザのラムダ関数内で独自に実装可能） |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | 該当なし |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 制限 | なし（フック発火のたびにラムダ関数が実行される） |

### 配信時間帯

制限なし（トレーニング実行中のフック発火タイミングに依存）

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

- ユーザ定義のラムダ関数に任意のコードが実行可能であるため、信頼できないコードの実行リスクがある
- ラムダ関数内でのネットワーク通信やファイルアクセスはユーザの責任

## 備考

- `**kwargs`を受け取り、`self.__dict__.update(kwargs)`で任意の属性を追加できる（行2851）
- 指定されなかったフックにはno-opラムダ（`lambda ...: None`）がデフォルトで設定される
- `on_predict_begin`等の予測フェーズ用フックは提供されていない

---

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

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

### 推奨読解順序

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

LambdaCallbackが受け取るラムダ関数のシグネチャを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | callbacks.py | `tensorflow/python/keras/callbacks.py` | LambdaCallbackのdocstring（行2790-2840）で各フックの引数シグネチャを確認 |

**読解のコツ**: `on_epoch_begin/end`は`(epoch, logs)`、`on_batch_begin/end`は`(batch, logs)`、`on_train_begin/end`は`(logs)`のシグネチャである。

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

コンストラクタでのラムダ関数の登録処理を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | callbacks.py | `tensorflow/python/keras/callbacks.py` | `LambdaCallback.__init__`（行2842-2875）で各フックへのラムダ関数代入を確認 |

**主要処理フロー**:
1. **行2850**: 親クラスの初期化
2. **行2851**: `**kwargs`による任意属性の追加
3. **行2852-2875**: 各フック（on_epoch_begin/end, on_batch_begin/end, on_train_begin/end）へのラムダ関数設定。Noneの場合はno-opラムダを設定

#### Step 3: 実行フローを理解する

LambdaCallbackはフックメソッドをインスタンス変数として上書きするため、Kerasのトレーニングループから直接呼び出される。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | callbacks.py | `tensorflow/python/keras/callbacks.py` | Callback基底クラス（行591-670）のフックメソッド定義を確認 |

**主要処理フロー**:
- LambdaCallbackは`self.on_epoch_begin = on_epoch_begin`のようにインスタンスメソッドをラムダ関数で直接置換する
- これにより、Kerasのトレーニングループが`callback.on_epoch_begin(epoch, logs)`を呼び出した際に、ユーザ定義のラムダ関数が実行される

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

```
model.fit() [Kerasトレーニングループ]
    │
    ├─ CallbackList.on_train_begin()
    │      └─ LambdaCallback.on_train_begin(logs) [ユーザ定義lambda]
    │
    ├─ [各エポックのループ]
    │      ├─ CallbackList.on_epoch_begin()
    │      │      └─ LambdaCallback.on_epoch_begin(epoch, logs) [ユーザ定義lambda]
    │      │
    │      ├─ [各バッチのループ]
    │      │      ├─ CallbackList.on_batch_begin()
    │      │      │      └─ LambdaCallback.on_batch_begin(batch, logs) [ユーザ定義lambda]
    │      │      └─ CallbackList.on_batch_end()
    │      │             └─ LambdaCallback.on_batch_end(batch, logs) [ユーザ定義lambda]
    │      │
    │      └─ CallbackList.on_epoch_end()
    │             └─ LambdaCallback.on_epoch_end(epoch, logs) [ユーザ定義lambda]
    │
    └─ CallbackList.on_train_end()
           └─ LambdaCallback.on_train_end(logs) [ユーザ定義lambda]
```

### データフロー図

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

epoch/batch (番号)     ───▶ LambdaCallback                ───▶ ユーザ定義の出力先
logs (メトリクス辞書)  ───▶ └─ ユーザ定義ラムダ関数実行       ├─ stdout / ファイル
                                                               ├─ 外部API
                                                               └─ その他任意
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| callbacks.py | `tensorflow/python/keras/callbacks.py` | ソース | LambdaCallbackクラス定義（行2790-2875） |
| callbacks.py | `tensorflow/python/keras/callbacks.py` | ソース | Callback基底クラス（行591-670） |
