# 通知設計書 8-RemoteMonitor

## 概要

本ドキュメントは、TensorFlow Kerasの`RemoteMonitor`コールバックに関する通知設計書である。`RemoteMonitor`はトレーニングイベントをリモートサーバへHTTP POST送信する。

### 本通知の処理概要

`RemoteMonitor`は、各エポック終了時にトレーニングメトリクスをJSON形式でリモートサーバにHTTP POST送信するコールバックである。外部モニタリングシステムとの連携を可能にする。

**業務上の目的・背景**：チーム開発やMLOps環境では、トレーニング進捗を中央のモニタリングサーバで一元管理したい場合がある。`RemoteMonitor`はトレーニングメトリクスを外部サーバにリアルタイム送信することで、リモートからのトレーニング監視やダッシュボード表示を可能にする。

**通知の送信タイミング**：各エポック終了時（`on_epoch_end`）にメトリクスデータをHTTP POSTで送信する。

**通知の受信者**：`root`引数で指定されたリモートHTTPサーバ。デフォルトは`http://localhost:9000`。

**通知内容の概要**：エポック番号と各メトリクスの値をJSON形式で送信する。numpy型はPythonネイティブ型に変換される。

**期待されるアクション**：リモートサーバがメトリクスデータを受信・保存し、ダッシュボード等で可視化する。

## 通知種別

HTTP POST通知（リモートサーバへのJSON送信）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（requests.post） |
| 優先度 | 中 |
| リトライ | 無し（送信失敗時は警告出力のみ） |

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

`root + path`で決定されるURL。デフォルトは`http://localhost:9000/publish/epoch/end/`。

## 通知テンプレート

### メール通知の場合

該当なし

### 本文テンプレート

```json
{
    "epoch": 5,
    "loss": 0.45,
    "accuracy": 0.82,
    "val_loss": 0.50,
    "val_accuracy": 0.78
}
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| root | サーバルートURL | コンストラクタ引数（デフォルト: 'http://localhost:9000'） | Yes |
| path | 送信先パス | コンストラクタ引数（デフォルト: '/publish/epoch/end/'） | Yes |
| field | フォーム送信時のフィールド名 | コンストラクタ引数（デフォルト: 'data'） | No |
| headers | カスタムHTTPヘッダ | コンストラクタ引数 | No |
| send_as_json | JSON送信フラグ | コンストラクタ引数（デフォルト: False） | No |
| epoch | エポック番号 | on_epoch_endの引数 | Yes |
| logs | メトリクス辞書 | on_epoch_endの引数 | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| エポック終了 | on_epoch_end | 常に発火 | メトリクスをHTTP POSTで送信 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| requestsライブラリ未インストール | ImportError発生 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[on_epoch_end] --> B{requestsインストール済み?}
    B -->|No| C[ImportError発生]
    B -->|Yes| D[送信データ構築]
    D --> E[numpy型変換: v.item]
    E --> F{send_as_json?}
    F -->|Yes| G[requests.post: json=send]
    F -->|No| H[requests.post: data=field:json.dumps]
    G --> I{送信成功?}
    H --> I
    I -->|Yes| J[正常終了]
    I -->|No| K[警告出力: could not reach server]
```

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

### 参照テーブル一覧

該当なし

### 更新テーブル一覧

該当なし（外部HTTPサーバへの送信）

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| ImportError | requestsライブラリ未インストール | on_epoch_endでImportErrorをraise |
| RequestException | HTTP送信失敗（タイムアウト、接続拒否等） | 警告ログ出力、トレーニングは継続 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0回（リトライなし） |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | 該当なし |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | エポック数に依存 |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし

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

- デフォルトではHTTP（暗号化なし）で通信するため、メトリクスデータが平文で送信される
- `root`にHTTPSを指定することで暗号化通信が可能
- `headers`引数で認証トークン等を設定可能
- リモートサーバの認証・認可はユーザの責任

## 備考

- `requests`ライブラリが必要（TensorFlowの標準依存には含まれない場合がある）
- `send_as_json=False`（デフォルト）の場合、JSONはフォームフィールドとして送信される
- `send_as_json=True`の場合、Content-Typeが`application/json`になる
- numpy.ndarray/numpy.genericは`.item()`でPythonスカラーに変換される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | callbacks.py | `tensorflow/python/keras/callbacks.py` | `RemoteMonitor.__init__`（行1866-1878）。root, path, field, headers, send_as_json |

**読解のコツ**: `RemoteMonitor`は非常にシンプルで、`__init__`でパラメータを保存し、`on_epoch_end`で送信するのみ。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | callbacks.py | `tensorflow/python/keras/callbacks.py` | `on_epoch_end`（行1880-1903）。HTTP POST送信の全処理 |

**主要処理フロー**:
1. **行1881-1882**: requestsライブラリの存在チェック
2. **行1884-1893**: 送信データ構築、numpy型変換
3. **行1895-1900**: `send_as_json`に応じたPOST送信方法分岐
4. **行1901-1903**: RequestException時の警告出力

#### Step 3: requestsライブラリのインポートを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | callbacks.py | `tensorflow/python/keras/callbacks.py` | ファイル先頭（行67-70）。try-exceptでrequestsをオプショナルインポート |

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

```
model.fit()
    |
    +-- CallbackList.on_epoch_end()
            +-- RemoteMonitor.on_epoch_end(epoch, logs)
                    +-- [requestsチェック]
                    +-- 送信データ構築
                    |       +-- numpy型 -> Python型変換 (v.item())
                    +-- requests.post(root + path, ...)
                    |       +-- [send_as_json=True]  json=send, headers=headers
                    |       +-- [send_as_json=False] data={field: json.dumps(send)}, headers=headers
                    +-- [RequestException] logging.warning(...)
```

### データフロー図

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

epoch, logs            ---> RemoteMonitor.on_epoch_end() ---> HTTP POST
  {loss: 0.45,              1. 送信データ構築                   POST http://localhost:9000
   accuracy: 0.82}          2. numpy型変換                      /publish/epoch/end/
                            3. JSON化                           Body: {"epoch": 5,
                            4. HTTP POST送信                            "loss": 0.45, ...}
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| callbacks.py | `tensorflow/python/keras/callbacks.py` | ソース | RemoteMonitorクラス定義 |
| requests (外部ライブラリ) | - | 外部依存 | HTTP通信 |
