# 機能設計書 17-活性化関数（Activation Functions）

## 概要

本ドキュメントは、TensorFlowにおける活性化関数（ReLU、Sigmoid、Softmax等）に関する設計書である。`tf.keras.activations`モジュールの関数群および`tf.keras.layers`のレイヤー型活性化関数の仕様を詳述する。

### 本機能の処理概要

活性化関数機能は、ニューラルネットワークに非線形性を導入するための数学関数群を提供する。各ニューロンの出力に適用され、ネットワークが複雑な関数を近似できるようにする。

**業務上の目的・背景**：線形変換のみではどれだけ層を重ねても線形関数しか表現できない。活性化関数により非線形性を導入することで、ニューラルネットワークは任意の連続関数を近似可能（万能近似定理）となる。活性化関数の選択はモデルの学習効率・精度・安定性に大きく影響する。

**機能の利用シーン**：隠れ層の活性化（ReLU系が標準）、分類出力層（Softmax/Sigmoid）、回帰出力層（Linear）、注意機構でのスコア正規化（Softmax）、生成モデルの出力層（Tanh/Sigmoid）。

**主要な処理内容**：
1. 関数型活性化: softmax, relu, sigmoid, tanh, elu, selu, softplus, softsign, swish, gelu, exponential, hard_sigmoid, linear
2. レイヤー型活性化: LeakyReLU, PReLU, ELU, ThresholdedReLU, Softmax（レイヤー版）
3. 活性化関数のシリアライズ/デシリアライズ
4. 活性化関数の動的ルックアップ（文字列名 -> 関数）

**関連システム・外部連携**：tf.nn（低レベル活性化関数実装）、Keras レイヤーシステム。

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

## 関連画面

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

## 機能種別

計算処理（数学関数）

## 入力仕様

### 入力パラメータ（関数型）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| x | tf.Tensor | Yes | 入力テンソル | - |
| axis | int | No（softmax、デフォルト-1） | 正規化軸 | 有効な軸インデックス |
| alpha | float | No（elu/relu） | 負領域の傾き | - |
| max_value | float | No（relu） | 上限クリップ値 | - |
| threshold | float | No（relu） | しきい値 | - |
| approximate | bool | No（gelu） | 近似有効化 | - |

### 入力パラメータ（レイヤー型）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| alpha | float | No（LeakyReLU、デフォルト0.3） | 負領域の傾き | None不可 |
| alpha_initializer | initializer | No（PReLU） | 学習可能alphaの初期化 | 有効なinitializer |
| theta | float | No（ThresholdedReLU、デフォルト1.0） | しきい値 | - |

### 入力データソース

前層からのテンソル出力。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| output | tf.Tensor | 活性化関数を適用した結果テンソル（入力と同形状） |

### 出力先

次層への入力テンソル。

## 処理フロー

### 処理シーケンス

```
1. 活性化関数の呼び出し
   └─ 関数型: activations.relu(x, alpha, max_value, threshold) 等
   └─ レイヤー型: layer.call(inputs)
2. 数学演算の実行
   └─ backend.relu / nn.softmax / math_ops.exp 等に委譲
3. 結果テンソルの返却
   └─ softmax/sigmoidの場合: _keras_logits属性をキャッシュ
```

### フローチャート

```mermaid
flowchart TD
    A[入力テンソル] --> B{関数型/レイヤー型}
    B -->|関数型| C[tf.keras.activations.xxx]
    B -->|レイヤー型| D[tf.keras.layers.xxx.call]
    C --> E{関数種別}
    D --> F[対応するbackend/nn関数]
    E -->|relu| G[backend.relu]
    E -->|softmax| H[nn.softmax]
    E -->|sigmoid| I[nn.sigmoid]
    E -->|gelu| J[nn.gelu]
    E -->|tanh| K[nn.tanh]
    G --> L[結果テンソル]
    H --> M[_keras_logits キャッシュ]
    I --> M
    J --> L
    K --> L
    M --> L
    F --> L
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | Softmax次元制約 | 1Dテンソルには適用不可（ValueError） | x.shape.rank == 1 |
| BR-02 | Softmaxログキャッシュ | softmax出力に_keras_logits属性をキャッシュ | crossentropyで再利用 |
| BR-03 | Sigmoidログキャッシュ | sigmoid出力に_keras_logits属性をキャッシュ | binary_crossentropyで再利用 |
| BR-04 | タプル軸Softmax | nn.softmaxがタプル軸未対応のため手動計算 | axis がタプルの場合 |
| BR-05 | v2シリアライズ互換 | softmax_v2/log_softmax_v2はsoftmax/log_softmaxにマッピング | シリアライズ時 |
| BR-06 | LeakyReLU alpha | alphaにNoneを渡すとValueError | alpha=None |

### 計算ロジック

- **ReLU**: `max(0, x)` （alpha/max_value/thresholdで拡張可能）
- **Softmax**: `exp(x - max(x)) / sum(exp(x - max(x)))`
- **Sigmoid**: `1 / (1 + exp(-x))`
- **Tanh**: `(exp(x) - exp(-x)) / (exp(x) + exp(-x))`
- **ELU**: `x if x > 0 else alpha * (exp(x) - 1)`
- **SELU**: `scale * elu(x, alpha)` (scale=1.05070098, alpha=1.67326324)
- **Swish**: `x * sigmoid(x)`
- **GELU**: `0.5 * x * (1 + tanh(sqrt(2/pi) * (x + 0.044715 * x^3)))` (近似)
- **Hard Sigmoid**: `clip(0.2*x + 0.5, 0, 1)`

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ValueError | 1D Softmax | 1Dテンソルにsoftmaxを適用 | 2D以上のテンソルを使用 |
| ValueError | 不明活性化関数 | deserializeで未知の名前を指定 | 有効な活性化関数名を使用 |
| TypeError | 不正なidentifier | get()にcallableでもstr/dictでもない値を渡す | 関数または文字列を使用 |
| ValueError | LeakyReLU alpha None | alpha=Noneを指定 | float値を指定 |

### リトライ仕様

該当なし。

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

該当なし。

## パフォーマンス要件

- 活性化関数は要素単位の演算のため、テンソルサイズに線形なコスト
- GPU上ではカーネル融合により畳み込み+活性化が一体化される場合がある
- _keras_logitsキャッシュによりcrossentropy計算の数値安定性向上

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

特になし。

## 備考

- `silu`は`swish`のエイリアス（activations.pyの503行目）
- `leaky_relu`、`log_softmax`、`relu6`はnn関数の直接エイリアス
- カスタム活性化関数はcustom_objectsパラメータで登録可能
- PReLUは学習可能なalpha（重みパラメータ）を持つ

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | activations.py | `tensorflow/python/keras/activations.py` | _TF_ACTIVATIONS_V2マッピング（33-36行目） |

**読解のコツ**: 活性化関数は2種類のインターフェースがある。(1) 関数型（`tf.keras.activations.*`）は単純な数学関数、(2) レイヤー型（`tf.keras.layers.*`）はパラメータや状態を持つ。

#### Step 2: 関数型活性化関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | activations.py | `tensorflow/python/keras/activations.py` | 各活性化関数の実装 |

**主要処理フロー**:
1. **40-92行目**: softmax - nn.softmax委譲、タプル軸の場合は手動計算、_keras_logitsキャッシュ
2. **96-141行目**: elu - backend.elu委譲
3. **144-194行目**: selu - nn.selu委譲
4. **268-305行目**: relu - backend.relu委譲（alpha/max_value/threshold対応）
5. **309-344行目**: gelu - nn.gelu委譲（approximate対応）
6. **347-365行目**: tanh - nn.tanh委譲
7. **369-397行目**: sigmoid - nn.sigmoid委譲、_keras_logitsキャッシュ
8. **420-445行目**: hard_sigmoid - backend.hard_sigmoid委譲
9. **238-265行目**: swish - nn.swish委譲

#### Step 3: レイヤー型活性化関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | advanced_activations.py | `tensorflow/python/keras/layers/advanced_activations.py` | LeakyReLU（33-86行目）、PReLU（89行目〜） |

**主要処理フロー**:
- **67-68行目**: LeakyReLU.__init__ - alphaをfloatxにキャスト
- **76-77行目**: LeakyReLU.call - backend.relu(inputs, alpha=self.alpha)
- **89行目〜**: PReLU - 学習可能なalpha重みを持つ

#### Step 4: シリアライズ/デシリアライズを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | activations.py | `tensorflow/python/keras/activations.py` | serialize（468-495行目）、deserialize（507-545行目）、get（549-589行目） |

**主要処理フロー**:
- **492-494行目**: serialize - v2名前のリマッピング
- **533-539行目**: deserialize - advanced_activationsのglobalsを統合
- **577-581行目**: get - str/dict/callableの判定

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

```
tf.keras.activations.relu(x, alpha, max_value, threshold)
    +-- backend.relu(x, alpha, max_value, threshold)

tf.keras.activations.softmax(x, axis)
    +-- [rank>1, int axis] nn.softmax(x, axis)
    +-- [rank>1, tuple axis] exp(x-max)/sum(exp)  (手動計算)
    +-- [rank<=1] ValueError
    +-- output._keras_logits = x  (キャッシュ)

tf.keras.activations.sigmoid(x)
    +-- nn.sigmoid(x)
    +-- output._keras_logits = x  (キャッシュ)

tf.keras.activations.get(identifier)
    +-- [None] -> linear
    +-- [str/dict] -> deserialize(identifier)
    |       +-- deserialize_keras_object(name, module_objects, ...)
    +-- [callable] -> identifier

tf.keras.layers.LeakyReLU(alpha=0.3)
    +-- call(inputs) -> backend.relu(inputs, alpha=self.alpha)
```

### データフロー図

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

入力テンソル x       ---> 活性化関数 f(x) --------> 出力テンソル f(x)
                           |
                           v
                    [softmax/sigmoid のみ]
                    _keras_logits = x  (キャッシュ)
                           |
                           v
                    crossentropy損失で再利用
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| activations.py | `tensorflow/python/keras/activations.py` | ソース | 関数型活性化関数の主要実装 |
| advanced_activations.py | `tensorflow/python/keras/layers/advanced_activations.py` | ソース | レイヤー型活性化関数 |
| nn.py | `tensorflow/python/ops/nn.py` | ソース | tf.nn低レベル活性化関数 |
| backend.py | `tensorflow/python/keras/backend.py` | ソース | Kerasバックエンド関数 |
| generic_utils.py | `tensorflow/python/keras/utils/generic_utils.py` | ソース | serialize/deserialize_keras_object |
| dispatch.py | `tensorflow/python/util/dispatch.py` | ソース | @add_dispatch_supportデコレータ |
