# 機能設計書 18-バッチ正規化（Batch Normalization）

## 概要

本ドキュメントは、TensorFlowにおけるバッチ正規化（Batch Normalization）機能に関する設計書である。C++カーネル実装（batch_norm_op.cc）とOp定義（nn_ops.cc）の仕様を詳述する。

### 本機能の処理概要

バッチ正規化機能は、ミニバッチ内の各特徴チャネルの平均と分散を使用して入力テンソルを正規化する。これにより内部共変量シフトを低減し、学習の安定化と高速化を実現する。

**業務上の目的・背景**：深層ニューラルネットワークの学習において、各層の入力分布が学習中に変化する（内部共変量シフト）問題がある。バッチ正規化はこの問題を緩和し、より高い学習率の使用を可能にし、初期化への依存度を低減する。現代のほぼ全てのCNNアーキテクチャで使用される。

**機能の利用シーン**：CNN各層の畳み込み後の正規化（ResNet、DenseNet等）、全結合層後の正規化、GAN（生成的敵対的ネットワーク）のGenerator/Discriminator。

**主要な処理内容**：
1. BatchNormWithGlobalNormalization Op - 初期のグローバル正規化（非推奨）
2. FusedBatchNorm V1/V2/V3 Op - 融合型バッチ正規化（推奨）
3. 訓練時: ミニバッチ平均/分散の計算、正規化、スケール・シフト
4. 推論時: 移動平均/移動分散を使用した正規化
5. 勾配計算: 入力・スケール・オフセットに対する逆伝播

**関連システム・外部連携**：cuDNN BatchNormalization、Eigen（CPU実装）。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能はモデル内部で使用される計算処理であり、画面に直接関連しない |

## 機能種別

計算処理（テンソル正規化）

## 入力仕様

### 入力パラメータ（BatchNormOp カーネル）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| input (t) | Tensor (4D) | Yes | 入力テンソル | dims() == 4 |
| mean (m) | Tensor (1D) | Yes | チャネル平均 | dims() == 1、最終次元と一致 |
| variance (v) | Tensor (1D) | Yes | チャネル分散 | dims() == 1、最終次元と一致 |
| beta | Tensor (1D) | Yes | オフセットパラメータ | dims() == 1、最終次元と一致 |
| gamma | Tensor (1D) | Yes | スケールパラメータ | dims() == 1、最終次元と一致 |
| variance_epsilon | float | Yes（属性） | 分散のゼロ除算防止用イプシロン | - |
| scale_after_normalization | bool | Yes（属性） | 正規化後にスケーリングを適用するか | - |

### 入力パラメータ（FusedBatchNorm Op）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| x | Tensor | Yes | 入力テンソル | 4D/5Dテンソル |
| scale | Tensor | Yes | スケールパラメータ | 1Dベクトル |
| offset | Tensor | Yes | オフセットパラメータ | 1Dベクトル |
| mean | Tensor | Yes | 移動平均（推論時） | 1Dベクトル |
| variance | Tensor | Yes | 移動分散（推論時） | 1Dベクトル |
| epsilon | float | No（デフォルト0.0001） | ゼロ除算防止用イプシロン | - |
| exponential_avg_factor | float | No（デフォルト1.0） | 指数移動平均係数 | - |
| data_format | string | No | データ配置 | NHWC/NCHW |
| is_training | bool | No（デフォルトtrue） | 訓練/推論モード | - |

### 入力データソース

前層からのテンソル出力、学習パラメータ（gamma/beta）、移動統計量。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| y (result) | Tensor | 正規化された出力テンソル |
| batch_mean | Tensor | バッチ平均（FusedBatchNormのみ） |
| batch_variance | Tensor | バッチ分散（FusedBatchNormのみ） |
| reserve_space_1 | Tensor | 勾配計算用の保持領域 |
| reserve_space_2 | Tensor | 勾配計算用の保持領域 |

### 出力先

次層への入力テンソル。

## 処理フロー

### 処理シーケンス

```
1. 入力テンソルの検証（4D/5D形状チェック）
2. [訓練時] ミニバッチ統計量の計算
   └─ batch_mean = mean(x, axis=[0,1,2])
   └─ batch_variance = variance(x, axis=[0,1,2])
3. 正規化
   └─ x_normalized = (x - mean) / sqrt(variance + epsilon)
4. スケーリング・シフト
   └─ y = gamma * x_normalized + beta
5. [訓練時] 移動統計量の更新
   └─ moving_mean = moving_mean * (1 - momentum) + batch_mean * momentum
```

### フローチャート

```mermaid
flowchart TD
    A[入力テンソル x] --> B{is_training?}
    B -->|Yes| C[バッチ平均/分散計算]
    B -->|No| D[移動平均/分散使用]
    C --> E[正規化: x_norm = (x-mean)/sqrt(var+eps)]
    D --> E
    E --> F[スケール・シフト: y = gamma*x_norm + beta]
    F --> G[出力]
    C --> H[移動統計量更新]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 4D入力制約 | BatchNormOpは4D入力のみサポート | batch_norm_op.cc |
| BR-02 | 1Dパラメータ制約 | mean/variance/beta/gammaは1Dベクトル | 全BatchNorm Op |
| BR-03 | 非推奨API | BatchNormWithGlobalNormalizationはTF9で非推奨 | Deprecated(9) |
| BR-04 | FusedBatchNorm推奨 | tf.nn.batch_normalization()の使用が推奨 | 全バージョン |
| BR-05 | 訓練/推論切替 | is_trainingフラグで統計量の計算方法が変わる | FusedBatchNorm |

### 計算ロジック

- 正規化: `y = gamma * (x - mean) / sqrt(variance + epsilon) + beta`
- scale_after_normalization=Trueの場合のみgammaを適用
- Eigenテンソル演算による実装（batch_norm_op.cc 71-74行目）

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| InvalidArgument | 非4D入力 | 入力テンソルが4次元でない | 4Dテンソルを入力する |
| InvalidArgument | 非1Dパラメータ | mean/var/beta/gammaが1次元でない | 1Dベクトルを入力する |
| InvalidArgument | 次元不一致 | パラメータの次元が入力の最終次元と不一致 | 次元数を合わせる |

### リトライ仕様

該当なし。

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

該当なし。

## パフォーマンス要件

- FusedBatchNormはmean/variance計算と正規化を融合し、メモリアクセス効率化
- cuDNN上では高度に最適化された実装を使用
- reserve_spaceにより勾配計算時の再計算を回避

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

特になし。

## 備考

- FusedBatchNormのV1/V2/V3の違い: V2はU型（float32スケール）を追加、V3はreserve_space_3を追加
- exponential_avg_factorは移動平均の更新速度を制御
- バッチサイズが小さい場合はGroupNormalizationやLayerNormalizationの使用を推奨

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | batch_norm_op.h | `tensorflow/core/kernels/batch_norm_op.h` | BatchNorm functorの定義 |

**読解のコツ**: TensorFlowのC++カーネルはEigen Tensorライブラリを使用する。`functor::BatchNorm`はデバイス（CPU/GPU）をテンプレートパラメータとして持つ。

#### Step 2: Op定義を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | nn_ops.cc | `tensorflow/core/ops/nn_ops.cc` | BatchNorm関連のREGISTER_OP定義 |

**主要処理フロー**:
1. **107-133行目**: BatchNormWithGlobalNormalization Op - 入力5テンソル、出力1テンソル、非推奨
2. **135-173行目**: BatchNormWithGlobalNormalizationGrad Op - 逆伝播、出力5テンソル
3. **177-193行目**: FusedBatchNorm V1 - T={float}制約
4. **195-200行目〜**: FusedBatchNorm V2 - T/U分離型パラメータ

#### Step 3: カーネル実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | batch_norm_op.cc | `tensorflow/core/kernels/batch_norm_op.cc` | BatchNormOp/BatchNormGradOp カーネル実装 |

**主要処理フロー**:
- **33-80行目**: BatchNormOp - 入力検証（4D/1D制約）、出力テンソル確保、functor呼び出し
- **35-42行目**: コンストラクタ - variance_epsilon/scale_after_normalization属性取得
- **44-74行目**: Compute - 入力テンソル取得、形状検証、BatchNorm functor実行
- **82-99行目**: BatchNormGradOp - コンストラクタと勾配計算のCompute

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

```
tf.nn.batch_normalization(x, mean, variance, offset, scale, variance_epsilon)
    |
    +-- [C++] FusedBatchNorm Op (推奨パス)
    |       +-- shape_inference::FusedBatchNormShape
    |       +-- FusedBatchNorm kernel (cuDNN on GPU / Eigen on CPU)
    |
    +-- [C++ Legacy] BatchNormWithGlobalNormalization Op
            +-- BatchNormOp::Compute(context)
            |       +-- 入力検証 (4D input, 1D params)
            |       +-- context->allocate_output
            |       +-- functor::BatchNorm<Device,T>()(...)
            |
            +-- BatchNormGradOp::Compute(context)
                    +-- functor::BatchNormGrad<Device,T>()(...)
```

### データフロー図

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

x (batch,H,W,C)    ---> 正規化計算                 ---> y (batch,H,W,C)
mean (C,)           ---> (x-mean)/sqrt(var+eps)          batch_mean (C,)
variance (C,)       ---> gamma * x_norm + beta           batch_variance (C,)
beta (C,)           --->                                 reserve_space_1
gamma (C,)          --->                                 reserve_space_2

[逆伝播]
backprop (batch,H,W,C) --> BatchNormGrad --> dx, dm, dv, db, dg
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| batch_norm_op.cc | `tensorflow/core/kernels/batch_norm_op.cc` | C++ソース | BatchNormカーネル実装 |
| batch_norm_op.h | `tensorflow/core/kernels/batch_norm_op.h` | C++ヘッダ | BatchNorm functor宣言 |
| nn_ops.cc | `tensorflow/core/ops/nn_ops.cc` | C++ソース | BatchNorm Op登録 |
| fused_batch_norm_op.cc | `tensorflow/core/kernels/fused_batch_norm_op.cc` | C++ソース | FusedBatchNormカーネル |
| nn.py | `tensorflow/python/ops/nn.py` | ソース | tf.nn.batch_normalization Python API |
| normalization.py | `tensorflow/python/keras/layers/normalization.py` | ソース | Keras BatchNormalization レイヤー |
