PyTorch torch.nn.ReLU 関数

PyTorch torch.nn リファレンスマニュアル


torch.nn.ReLUPyTorch で最もよく使われる活性化関数の1つであり、入力テンソルに対して要素ごとに修正線形ユニット(Rectified Linear Unit)演算を実行します。

ReLU は、計算が簡単で収束が速く、勾配消失問題を効果的に軽減できるため、深層学習で最も成功した活性化関数の1つです。

関数定義

torch.nn.ReLU(inplace=False)

パラメータの説明:

  • inplaceinplace (bool): に設定するとTrue、その場で入力テンソルが直接変更され、メモリが節約されます。デフォルトはFalse。

数学的原理

nn.ReLU実行される計算式は次のとおりです:

f(x) = max(0, x)

つまり、入力の各要素について、値が0より大きい場合はそのままにし、値が0以下の場合は0を出力します。

この単純な非線形変換により、ネットワークは勾配の流れを保ちながら複雑なパターンを学習できます。


使用例

例1: 基本的な使い方

ReLU 活性化層を作成し、入力を活性化します:

例

import torch
import torch.nn as nn

# ReLU 活性化層を作成
relu = nn.ReLU()

# 負の値を含む入力テンソルを作成
input_tensor = torch.tensor([[-1.0, 2.0, -3.0], [4.0, -5.0, 6.0]])

# 順伝播
output = relu(input_tensor)

print("入力:n", input_tensor)
print("出力:n", output)

出力結果は次のとおりです:

输入:
 tensor([[-1.,  2., -3.],
        [ 4., -5.,  6.]])
输出:
 tensor([[0., 2., 0.],
        [4., 0., 6.]])

すべての負の値が0に設定され、正の値はそのままであることがわかります。

例2: インプレース操作

inplace パラメータを使用するとメモリを節約できます:

例

import torch
import torch.nn as nn

# インプレース操作を有効にした ReLU を作成
relu_inplace = nn.ReLU(inplace=True)

# 入力テンソルを作成
input_tensor = torch.randn(2, 4)
original_id = id(input_tensor)

# インプレースで変更
output = relu_inplace(input_tensor)

# 元のテンソルが変更されたか確認
print("元のテンソルが変更されたか:", id(output) == original_id)
print("入力/出力:n", input_tensor)

出力結果は次のとおりです:

是否修改了原张量: True
输入/输出:
 tensor([[0.0000, 0.0000, 1.2345, 0.0000],
        [0.5432, 0.0000, 0.0000, 2.3456]])

注意: インプレース操作はメモリを節約できますが、場合によっては勾配計算に影響を与える可能性があります。トレーニングの初期や中間の活性化値を保持する必要がある場合は、デフォルトのinplace=False。

例3: ニューラルネットワークでの使用

畳み込みニューラルネットワークでは、ReLU は通常、畳み込み層の後に続きます:

例

import torch
import torch.nn as nn

# 簡単な畳み込みニューラルネットワークを定義
class SimpleCNN(nn.Module):
    def __init__(self):
        super(SimpleCNN, self).__init__()
        # 畳み込み層: 入力3チャンネル、出力32チャンネル、カーネル3x3
        self.conv1 = nn.Conv2d(3, 32, kernel_size=3, padding=1)
        # ReLU 活性化
        self.relu1 = nn.ReLU()
        # 2番目の畳み込み層
        self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
        self.relu2 = nn.ReLU()
        # プーリング層
        self.pool = nn.MaxPool2d(2, 2)

    def forward(self, x):
        x = self.conv1(x)
        x = self.relu1(x)
        x = self.pool(x)

        x = self.conv2(x)
        x = self.relu2(x)
        x = self.pool(x)

        return x

# モデルを作成
model = SimpleCNN()

# モデル構造を出力
print("モデル構造:")
print(model)

# 順伝播をテスト
# 3x32x32 のカラー画像をシミュレート
input_image = torch.randn(1, 3, 32, 32)
output = model(input_image)

print("n入力形状:", input_image.shape)
print("出力形状:", output.shape)

出力結果は次のとおりです:

模型结构:
SimpleCNN(
  (conv1): Conv2d(3, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
  (relu1): ReLU()
  (conv2): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
  (relu2): ReLU()
  (pool): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)

输入形状: torch.Size([1, 3, 32, 32])
输出形状: torch.Size([1, 64, 8, 8])

例4: nn.functional.relu を使用

PyTorch には関数型インターフェースも用意されていますtorch.nn.functional.relu:

例

import torch
import torch.nn.functional as F

# 関数型インターフェースを使用
input_tensor = torch.randn(1, 5, 5)

# 方法1: 関数型インターフェースを使用
output1 = F.relu(input_tensor)

# 方法2: inplace バージョンの関数を使用
F.relu_(input_tensor)

print("出力:n", output1)

両者の違い:

  • nn.ReLUモジュールクラスであり、モデル定義で使用でき、パラメータを保持します。
  • F.relu関数型インターフェースであり、forwardメソッドや学習可能なパラメータがない場合によく使用されます。
  • F.relu_インプレースバージョンのアンダースコア関数です。

他の活性化関数との比較

活性化関数 式 特徴 適用シーン
nn.ReLU max(0, x) 計算が簡単、スパース活性化 一般的な深層学習(デフォルトの選択)
nn.LeakyReLU x > 0 ? x : 0.01x 負の軸にわずかな勾配がある 「死滅ニューロン」を防ぐ
nn.GELU x * Φ(x) スムーズな近似、Transformer のデフォルト Transformer、BERT など
nn.Sigmoid 1/(1+e^(-x)) 出力0-1、勾配飽和 出力層、二値分類
nn.Tanh (e^x - e^(-x))/(e^x + e^(-x)) 出力 -1 から 1、ゼロ中心化 RNN、LSTM

よくある質問

Q1: ReLU はなぜ「死滅ニューロン」問題を引き起こすのですか?

入力が継続的に負の場合、ReLU の出力は常に0になり、勾配も0になるため、これらのニューロンは学習できなくなります。

解決方法:

  • 使用nn.LeakyReLU 或 nn.ELU代替
  • より小さな初期学習率を使用する
  • バッチ正規化を採用する

Q2: ReLU は出力層に適していますか?

通常は適していません。出力層ではより一般的に使用されるのはSigmoid(分類)または恒等関数(回帰)です。なぜなら ReLU の出力は非有界だからです。


使用シーン

nn.ReLU深層学習で最もよく使われる活性化関数であり、主な適用シーンは次のとおりです:

  • 畳み込みニューラルネットワーク: 畳み込み層または全結合層の後に非線形性を導入します。
  • 多層パーセプトロン: 隠れ層の活性化関数として使用されます。
  • TransformerFFN(Feed-Forward Network)内で活性化関数として使用されます(現在はGELUがより多く使用されていますが)。
  • 生成対抗ネットワーク: 生成器の活性化関数として使用されます。

ヒント:特別な要件がない限り、ニューラルネットワークを設計する際、ReLU が隠れ層の活性化関数の第一候補です。


PyTorch torch.nn リファレンスマニュアル

その他の拡張