Activation関数比較:ReLU / LeakyReLU / ELU / GELU の違いとは?

2025年6月29日日曜日

Activation関数 Google Colab Keras 活性化関数

X f B! P L
Activation関数比較 アイキャッチ画像

はじめに:活性化関数の重要性

ニューラルネットワークにおいて「活性化関数(Activation Function)」は、各ニューロンの出力に非線形性を加える重要な役割を持ちます。適切な関数を選ぶことで、学習のスピードや精度が大きく変わります。

本記事では代表的な4つの活性化関数 ReLU・LeakyReLU・ELU・GELU を比較し、それぞれの特徴と違いを解説します。

比較する活性化関数

  • ReLU(Rectified Linear Unit、「レルー」と読む):最も一般的な活性化関数。シンプルで高速。
  • LeakyReLU(Leaky Rectified Linear Unit):ReLUの欠点(死んだReLU)を緩和。
  • ELU(Exponential Linear Unit):学習初期の安定性に強い。
  • GELU(Gaussian Error Linear Unit):最近注目の関数。BERTなどで使用。

実験概要

4つの活性化関数を用いて、それぞれ同じ構造のCNNモデルをMNISTデータセットで訓練し、精度・学習速度を比較します。

環境とライブラリ

import tensorflow as tf
from tensorflow.keras import layers, models
import numpy as np
import matplotlib.pyplot as plt

# GELUは tf.nn.gelu で使用可能

データ準備(MNIST)

(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
x_train = x_train.astype("float32") / 255.0
x_test = x_test.astype("float32") / 255.0
x_train = np.expand_dims(x_train, -1)
x_test = np.expand_dims(x_test, -1)

モデル構築関数

def build_model(activation_fn):
    model = models.Sequential([
        layers.Input(shape=(28, 28, 1)),
        layers.Conv2D(32, (3, 3)),
        activation_fn,
        layers.MaxPooling2D((2, 2)),
        layers.Flatten(),
        layers.Dense(64),
        activation_fn,
        layers.Dense(10, activation='softmax')
    ])
    model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
    return model

それぞれのモデル

models_dict = {
    'ReLU': build_model(layers.Activation('relu')),
    'LeakyReLU': build_model(layers.LeakyReLU(negative_slope=0.1)),
    'ELU': build_model(layers.ELU(alpha=1.0)),
    'GELU': build_model(layers.Activation(tf.nn.gelu))
}

訓練と精度の記録

history_dict = {}

for name, model in models_dict.items():
    print(f"Training with {name}")
    history = model.fit(x_train, y_train, epochs=5, batch_size=128,
                        validation_split=0.1, verbose=1)
    history_dict[name] = history

実行結果

Training with ReLU
Epoch 1/5
422/422 ━━━━━━━━━━━━━━━━━━━━ 7s 9ms/step - accuracy: 0.8406 - loss: 0.5529 - val_accuracy: 0.9693 - val_loss: 0.1072
Epoch 2/5
422/422 ━━━━━━━━━━━━━━━━━━━━ 2s 4ms/step - accuracy: 0.9713 - loss: 0.0998 - val_accuracy: 0.9815 - val_loss: 0.0692
Epoch 3/5
422/422 ━━━━━━━━━━━━━━━━━━━━ 2s 4ms/step - accuracy: 0.9819 - loss: 0.0631 - val_accuracy: 0.9857 - val_loss: 0.0553
Epoch 4/5
422/422 ━━━━━━━━━━━━━━━━━━━━ 1s 3ms/step - accuracy: 0.9873 - loss: 0.0452 - val_accuracy: 0.9837 - val_loss: 0.0617
Epoch 5/5
422/422 ━━━━━━━━━━━━━━━━━━━━ 1s 3ms/step - accuracy: 0.9891 - loss: 0.0373 - val_accuracy: 0.9878 - val_loss: 0.0506
Training with LeakyReLU
Epoch 1/5
422/422 ━━━━━━━━━━━━━━━━━━━━ 4s 7ms/step - accuracy: 0.8536 - loss: 0.5220 - val_accuracy: 0.9730 - val_loss: 0.0992
Epoch 2/5
422/422 ━━━━━━━━━━━━━━━━━━━━ 2s 4ms/step - accuracy: 0.9719 - loss: 0.0961 - val_accuracy: 0.9820 - val_loss: 0.0665
Epoch 3/5
422/422 ━━━━━━━━━━━━━━━━━━━━ 2s 4ms/step - accuracy: 0.9823 - loss: 0.0607 - val_accuracy: 0.9838 - val_loss: 0.0608
Epoch 4/5
422/422 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - accuracy: 0.9864 - loss: 0.0464 - val_accuracy: 0.9837 - val_loss: 0.0568
Epoch 5/5
422/422 ━━━━━━━━━━━━━━━━━━━━ 1s 3ms/step - accuracy: 0.9893 - loss: 0.0353 - val_accuracy: 0.9865 - val_loss: 0.0546
Training with ELU
Epoch 1/5
422/422 ━━━━━━━━━━━━━━━━━━━━ 5s 8ms/step - accuracy: 0.8654 - loss: 0.4912 - val_accuracy: 0.9700 - val_loss: 0.1047
Epoch 2/5
422/422 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - accuracy: 0.9677 - loss: 0.1089 - val_accuracy: 0.9800 - val_loss: 0.0689
Epoch 3/5
422/422 ━━━━━━━━━━━━━━━━━━━━ 1s 3ms/step - accuracy: 0.9801 - loss: 0.0657 - val_accuracy: 0.9805 - val_loss: 0.0689
Epoch 4/5
422/422 ━━━━━━━━━━━━━━━━━━━━ 1s 3ms/step - accuracy: 0.9874 - loss: 0.0440 - val_accuracy: 0.9833 - val_loss: 0.0598
Epoch 5/5
422/422 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - accuracy: 0.9898 - loss: 0.0341 - val_accuracy: 0.9847 - val_loss: 0.0564
Training with GELU
Epoch 1/5
422/422 ━━━━━━━━━━━━━━━━━━━━ 5s 8ms/step - accuracy: 0.8462 - loss: 0.5652 - val_accuracy: 0.9703 - val_loss: 0.1155
Epoch 2/5
422/422 ━━━━━━━━━━━━━━━━━━━━ 2s 4ms/step - accuracy: 0.9631 - loss: 0.1264 - val_accuracy: 0.9825 - val_loss: 0.0694
Epoch 3/5
422/422 ━━━━━━━━━━━━━━━━━━━━ 1s 3ms/step - accuracy: 0.9800 - loss: 0.0713 - val_accuracy: 0.9825 - val_loss: 0.0670
Epoch 4/5
422/422 ━━━━━━━━━━━━━━━━━━━━ 3s 3ms/step - accuracy: 0.9855 - loss: 0.0488 - val_accuracy: 0.9847 - val_loss: 0.0526
Epoch 5/5
422/422 ━━━━━━━━━━━━━━━━━━━━ 1s 3ms/step - accuracy: 0.9891 - loss: 0.0375 - val_accuracy: 0.9872 - val_loss: 0.0498

結果の可視化(バリデーション精度)

for name, history in history_dict.items():
    plt.plot(history.history['val_accuracy'], label=name)

plt.title('Validation Accuracy per Epoch')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.legend()
plt.grid()
plt.show()

精度グラフ

精度グラフ

考察

各活性化関数の訓練結果を比較すると、最終的な精度(accuracy)はどの関数も非常に高く、0.989前後に到達しており、明確な差は見られませんでした。ただし、学習の進み方や汎化性能(val_accuracy)には微妙な違いがありました。

活性化関数 最終Accuracy 最終Loss Val Accuracy Val Loss
ReLU 0.9891 0.0373 0.9878 0.0506
LeakyReLU 0.9893 0.0353 0.9865 0.0546
ELU 0.9898 0.0341 0.9847 0.0564
GELU 0.9891 0.0375 0.9872 0.0498
  • ReLU:シンプルかつ高速で、依然として高性能なベースライン。
  • LeakyReLU:ReLUよりやや滑らかで、若干の性能向上が見られる場面も。
  • ELU:収束が速くLossも最小だが、汎化性能では少し劣る。
  • GELU:最新のモデルで使われる関数。精度・損失ともに安定。

まとめ

活性化関数はモデルの学習挙動に影響を与える重要な要素です。今回の比較では、大きな性能差は見られなかったものの、ELUやGELUはより滑らかで安定した学習挙動を示しました。

一方で、ReLUは依然として堅実でシンプルな選択肢であることが分かりました。タスクやデータに応じて適切な関数を選択することが、より良いモデル構築につながります。

参考リンク

このブログを検索

自己紹介

はじめまして、機械学習を独学中のSHOU TAKEと申します。本ブログでは、Python・Keras・Google Colabを活用した画像分類やニューラルネットワークの実験記事を中心に発信しています。初学者の方にも分かりやすく、学んだことをそのまま実験形式でまとめるスタイルです。これまで取り組んだテーマには、学習率やOptimizerの比較、Batch Sizeの検証、事前学習の活用などがあります。ご質問やご感想は、お問い合わせフォームからお気軽にどうぞ。

お問い合わせフォーム

名前

メール *

メッセージ *

プライバシーポリシー

QooQ