# 機能設計書 131-Kerasモデル構築API

## 概要

本ドキュメントは、TensorFlowのKerasにおけるモデル構築API（Sequential、Functional、Subclassing）の機能設計について記載する。

### 本機能の処理概要

Kerasモデル構築APIは、ニューラルネットワークモデルを定義するための3つの構築パターンを提供する高水準APIである。

**業務上の目的・背景**：ディープラーニングモデルの構築は複雑な計算グラフの定義を必要とするが、Kerasモデル構築APIは直感的なインターフェースを提供することで、研究者や開発者が迅速にモデルを設計・実装できるようにする。低レベルのTensorFlowグラフ操作を意識することなく、レイヤーの積み重ねや接続でモデルを定義できることが最大の利点である。

**機能の利用シーン**：画像分類、自然言語処理、音声認識などのあらゆるディープラーニングタスクにおいて、モデルアーキテクチャを定義する際に使用される。単純な層の積み重ね（Sequential）、複雑な分岐・結合を持つモデル（Functional）、カスタムロジックを含むモデル（Subclassing）など、用途に応じた構築パターンを選択できる。

**主要な処理内容**：
1. Sequential APIによるレイヤーの線形スタック構築（`model.add()`による逐次的なレイヤー追加）
2. Functional APIによるDAG（有向非巡回グラフ）形式のモデル構築（`Input`テンソルと関数呼び出しスタイルによるレイヤー接続）
3. Model Subclassingによるカスタムモデル定義（`__init__`でレイヤー定義、`call`でフォワードパス実装）
4. モデルのコンパイル（オプティマイザ・損失関数・評価指標の設定）
5. モデルの訓練（`fit`）、評価（`evaluate`）、推論（`predict`）の実行
6. モデルのクローン（`clone_model`）による構造の複製

**関連システム・外部連携**：損失関数（No.40）、オプティマイザ（No.27-34）、評価指標（No.41）、コールバック（No.132）、モデル保存（No.134）と密接に連携する。

**権限による制御**：特になし。全てのユーザが利用可能。

## 関連画面

本機能は画面機能マッピングにおいて直接的な関連画面は定義されていない。Kerasモデル構築APIはプログラミングAPI として利用される。

## 機能種別

計算処理 / モデル定義

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| inputs | Tensor / list[Tensor] | Yes（Functional） | モデルの入力テンソル（`keras.Input()`で生成） | KerasTensorであること |
| outputs | Tensor / list[Tensor] | Yes（Functional） | モデルの出力テンソル | 入力と接続されたテンソルであること |
| layers | list[Layer] | No（Sequential） | レイヤーのリスト（コンストラクタ引数） | 各要素がLayerインスタンスであること |
| name | str | No | モデル名 | 文字列型 |
| trainable | bool | No | モデルの重みを訓練可能にするか | ブール値 |

### 入力データソース

Pythonコードによるプログラム的な定義。`keras.Input()`で生成されるKerasTensorオブジェクトと、各種Kerasレイヤーインスタンス。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| model | keras.Model | 構築されたKerasモデルインスタンス |
| model.summary() | str | モデルのアーキテクチャサマリー |
| model.layers | list[Layer] | モデルに含まれるレイヤーのリスト |
| model.weights | list[Variable] | モデルの全重みパラメータ |

### 出力先

メモリ上のPythonオブジェクト。必要に応じてモデル保存機能（No.134）により永続化。

## 処理フロー

### 処理シーケンス

```
1. モデルインスタンスの生成
   └─ Sequential: 空モデル or レイヤーリストから生成
   └─ Functional: inputs, outputsを指定して生成
   └─ Subclassing: __init__でレイヤー定義

2. レイヤーの追加・接続
   └─ Sequential: model.add()で逐次追加
   └─ Functional: layer(input_tensor)でDAG構築
   └─ Subclassing: call()内で処理定義

3. モデルのビルド
   └─ 入力形状の推論・重みの生成
   └─ 遅延ビルドパターン: 最初のfit/predict呼び出し時にビルド

4. モデルのコンパイル
   └─ model.compile(optimizer, loss, metrics)

5. 訓練・評価・推論
   └─ model.fit() / model.evaluate() / model.predict()
```

### フローチャート

```mermaid
flowchart TD
    A[モデル構築パターン選択] --> B{パターン}
    B -->|Sequential| C[Sequential Model生成]
    B -->|Functional| D[Input定義 → Layer接続 → Model生成]
    B -->|Subclassing| E[Model継承クラス定義]
    C --> F[model.add でレイヤー追加]
    D --> G[inputs/outputs指定でModel生成]
    E --> H[__init__/call メソッド実装]
    F --> I[model.compile]
    G --> I
    H --> I
    I --> J[model.fit / evaluate / predict]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-131-01 | Sequentialの単一出力制約 | Sequentialモデルの各レイヤーは単一の出力テンソルを持つ必要がある | Sequentialモデル使用時 |
| BR-131-02 | Functional入力制約 | Functional APIのInputはkeras.Input()で生成したKerasTensorである必要がある | Functionalモデル使用時 |
| BR-131-03 | 遅延ビルド | 入力形状未指定の場合、最初のデータ入力時に自動的にビルドされる | 入力形状未指定時 |
| BR-131-04 | クラス注入 | ModelクラスはFunctionalパラメータ検出時にFunctionalクラスを基底クラスに注入する | inputs/outputs引数がある場合 |

### 計算ロジック

Sequentialモデルは`functional.Functional`を継承し、内部的にFunctional APIの仕組みを利用してグラフを構築する。`inject_functional_model_class`関数により、Modelクラスの基底クラス階層にFunctionalを動的に挿入する仕組みが実装されている（training.py 108-125行目）。

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

本機能にデータベース操作はない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ValueError | 入力検証エラー | Sequentialモデルで複数出力レイヤーを追加した場合 | Functional APIに切り替える |
| ValueError | 入力検証エラー | Functionalモデルでinputs/outputsが未接続の場合 | レイヤーの接続関係を確認する |
| RuntimeError | 状態エラー | ビルド前にweightsにアクセスした場合 | build()を先に呼び出す |

### リトライ仕様

該当なし。

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

該当なし。

## パフォーマンス要件

モデル構築自体は軽量な操作であり、特段のパフォーマンス要件はない。ただしモデルの最初のビルド時（重みの初期化）には入力形状に応じたメモリ割り当てが発生する。

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

- `model_from_yaml`および`model_from_json`でのモデル復元時は、信頼できないソースからの設定を使用しないこと（任意コード実行のリスク）
- `custom_objects`パラメータを使用する際は、信頼できるカスタムオブジェクトのみを指定すること

## 備考

- Kerasは元々独立したライブラリとして開発され、TensorFlow 2.0以降でTensorFlowに統合された
- `tf.keras.Model`は`base_layer.Layer`を継承しており、モデル自体もレイヤーとして扱うことができる（モデルのネスト）
- Sequential APIはFunctional APIの特殊なケースとして実装されている（sequential.py 46行目）

---

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

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

### 推奨読解順序

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

モデル構築の基盤となるクラス階層を把握することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | base_layer.py | `tensorflow/python/keras/engine/base_layer.py` | Layerクラスの基底。全レイヤー・モデルの共通インターフェース |
| 1-2 | node.py | `tensorflow/python/keras/engine/node.py` | レイヤー間の接続情報を保持するNodeクラス |
| 1-3 | keras_tensor.py | `tensorflow/python/keras/engine/keras_tensor.py` | Functional APIで使用されるKerasTensorの定義 |

**読解のコツ**: KerasのクラスはPythonの多重継承を活用している。`Model`は`Layer`のサブクラスであり、モデルもレイヤーとして振る舞える点が設計の鍵。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | models.py | `tensorflow/python/keras/models.py` | API公開エントリーポイント。Model/Sequential/Functionalのエイリアス定義 |
| 2-2 | input_layer.py | `tensorflow/python/keras/engine/input_layer.py` | `keras.Input()`関数の定義。Functional APIの起点 |

**主要処理フロー**:
1. **40行目**: `Model = training.Model` - Modelクラスをtrainingモジュールからエイリアス
2. **41行目**: `Sequential = sequential.Sequential` - Sequentialクラスのエイリアス
3. **42行目**: `Functional = functional.Functional` - Functionalクラスのエイリアス

#### Step 3: Modelクラス（訓練機能統合）を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | training.py | `tensorflow/python/keras/engine/training.py` | Modelクラスの本体。compile/fit/evaluate/predict等の主要メソッド |

**主要処理フロー**:
- **134行目**: `class Model(base_layer.Layer, version_utils.ModelVersionSelector)` - Modelクラスの定義と多重継承
- **108-125行目**: `inject_functional_model_class` - Functional APIパターン検出時のクラス注入ロジック
- **128-131行目**: `is_functional_model_init_params` - inputs/outputs引数の検出

#### Step 4: Functionalモデルを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | functional.py | `tensorflow/python/keras/engine/functional.py` | Functional APIの実装。DAGグラフの構築とトポロジカルソート |

**主要処理フロー**:
- **48行目**: `class Functional(training_lib.Model)` - FunctionalはModelを継承
- inputs/outputsを受け取り、レイヤー間のノード接続からDAGを構築
- `_map_graph_network`で入力から出力へのパスを解析

#### Step 5: Sequentialモデルを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | sequential.py | `tensorflow/python/keras/engine/sequential.py` | Sequential APIの実装。Functionalを継承した線形スタック |

**主要処理フロー**:
- **46行目**: `class Sequential(functional.Functional)` - SequentialはFunctionalを継承
- `add()`メソッドでレイヤーを逐次追加
- 入力形状が指定されている場合は即座にビルド、未指定の場合は遅延ビルド

#### Step 6: モデルクローンを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 6-1 | models.py | `tensorflow/python/keras/models.py` | `clone_model`関数とその補助関数 |

**主要処理フロー**:
- **55-56行目**: `_clone_layer` - レイヤーのクローン（configベース）
- **72-100行目**: `_make_new_nodes` - ノード構造を再構築してモデルを複製

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

```
tf.keras.Model (models.py:40)
    |
    +-- training.Model (training.py:134)
    |       |
    |       +-- base_layer.Layer (base_layer.py)
    |       |       +-- __call__() -> call()
    |       |       +-- build()
    |       |       +-- get_config()
    |       |
    |       +-- compile() -> compile_utils.LossesContainer / MetricsContainer
    |       +-- fit() -> data_adapter -> train_step()
    |       +-- evaluate() -> test_step()
    |       +-- predict() -> predict_step()
    |
    +-- functional.Functional (functional.py:48)
    |       |
    |       +-- __init__(inputs, outputs) -> _map_graph_network()
    |       +-- _validate_graph_inputs_and_outputs()
    |
    +-- sequential.Sequential (sequential.py:46)
            |
            +-- add(layer) -> _build_graph_network_for_inferred_shape()
            +-- pop() -> レイヤー除去
```

### データフロー図

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

keras.Input(shape)  ---> Functional.__init__()      ---> Model instance
                           |
layer instances     ---> Sequential.add()           ---> Model instance
                           |
class定義           ---> Model.__init__() (subclass) ---> Model instance
                           |
                    ---> model.compile()            ---> compiled model
                           |
training data       ---> model.fit()                ---> trained model + History
                           |
test data           ---> model.evaluate()           ---> metrics dict
                           |
input data          ---> model.predict()            ---> predictions
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| models.py | `tensorflow/python/keras/models.py` | ソース | APIエントリーポイント、clone_model |
| training.py | `tensorflow/python/keras/engine/training.py` | ソース | Modelクラス本体（compile/fit/evaluate/predict） |
| functional.py | `tensorflow/python/keras/engine/functional.py` | ソース | Functional APIによるDAGモデル構築 |
| sequential.py | `tensorflow/python/keras/engine/sequential.py` | ソース | Sequential APIによる線形モデル構築 |
| base_layer.py | `tensorflow/python/keras/engine/base_layer.py` | ソース | Layer基底クラス |
| input_layer.py | `tensorflow/python/keras/engine/input_layer.py` | ソース | Input関数・InputLayerクラス |
| node.py | `tensorflow/python/keras/engine/node.py` | ソース | レイヤー間接続のNode |
| keras_tensor.py | `tensorflow/python/keras/engine/keras_tensor.py` | ソース | KerasTensorデータ構造 |
| compile_utils.py | `tensorflow/python/keras/engine/compile_utils.py` | ソース | compile用ユーティリティ |
| data_adapter.py | `tensorflow/python/keras/engine/data_adapter.py` | ソース | 訓練データアダプタ |
| training_utils.py | `tensorflow/python/keras/engine/training_utils.py` | ソース | 訓練ユーティリティ |
| model_config.py | `tensorflow/python/keras/saving/model_config.py` | ソース | model_from_config/json/yaml |
