PyTorch torch.nn.GroupNorm 関数
torch.nn.GroupNormPyTorch のグループ正規化モジュールです。
チャネルをグループに分けて正規化し、バッチサイズに依存しないため、小さいバッチや可変長シーケンスに適しています。
関数定義
torch.nn.GroupNorm(num_groups, num_channels, eps=1e-05, affine=True)
パラメータ:
num_groups: グループ数num_channels: チャネル数。num_groups で割り切れる必要があります
使用例
例 1: 基本的な使い方
サンプル
import torch
import torch.nn as nn
# GroupNorm: 4グループ、32チャンネル
gn = nn.GroupNorm(num_groups=4, num_channels=32)
# 入力: (batch, channels, height, width)
x = torch.randn(8, 32, 16, 16)
output = gn(x)
print("入力形状:", x.shape)
print("出力形状:", output.shape)
import torch.nn as nn
# GroupNorm: 4グループ、32チャンネル
gn = nn.GroupNorm(num_groups=4, num_channels=32)
# 入力: (batch, channels, height, width)
x = torch.randn(8, 32, 16, 16)
output = gn(x)
print("入力形状:", x.shape)
print("出力形状:", output.shape)
例 2: 特殊なケース - InstanceNorm
サンプル
import torch
import torch.nn as nn
# InstanceNorm は num_groups=num_channels の特殊なケースです
inorm = nn.InstanceNorm2d(32)
# GroupNorm, num_groups=32, num_channels=32 と等価です
gn_equiv = nn.GroupNorm(32, 32)
x = torch.randn(4, 32, 16, 16)
print("InstanceNorm2d:", inorm(x).mean().item())
print("GroupNorm:", gn_equiv(x).mean().item())
import torch.nn as nn
# InstanceNorm は num_groups=num_channels の特殊なケースです
inorm = nn.InstanceNorm2d(32)
# GroupNorm, num_groups=32, num_channels=32 と等価です
gn_equiv = nn.GroupNorm(32, 32)
x = torch.randn(4, 32, 16, 16)
print("InstanceNorm2d:", inorm(x).mean().item())
print("GroupNorm:", gn_equiv(x).mean().item())
例 3: ResNet での GroupNorm
サンプル
import torch
import torch.nn as nn
# ResNet 構造は GroupNorm を使用
class ConvBlock(nn.Module):
def __init__(self, in_ch, out_ch, num_groups=8):
super(ConvBlock, self).__init__()
self.conv = nn.Conv2d(in_ch, out_ch, 3, padding=1)
self.gn = nn.GroupNorm(num_groups, out_ch)
self.relu = nn.ReLU()
def forward(self, x):
return self.relu(self.gn(self.conv(x)))
block = ConvBlock(64, 128)
x = torch.randn(2, 64, 32, 32)
output = block(x)
print("入力:", x.shape, "-> 出力:", output.shape)
import torch.nn as nn
# ResNet 構造は GroupNorm を使用
class ConvBlock(nn.Module):
def __init__(self, in_ch, out_ch, num_groups=8):
super(ConvBlock, self).__init__()
self.conv = nn.Conv2d(in_ch, out_ch, 3, padding=1)
self.gn = nn.GroupNorm(num_groups, out_ch)
self.relu = nn.ReLU()
def forward(self, x):
return self.relu(self.gn(self.conv(x)))
block = ConvBlock(64, 128)
x = torch.randn(2, 64, 32, 32)
output = block(x)
print("入力:", x.shape, "-> 出力:", output.shape)
例 4: 異なる num_groups の影響
サンプル
import torch
import torch.nn as nn
# 32チャンネルを異なるグループ数で
for num_groups in [1, 2, 4, 8, 32]:
gn = nn.GroupNorm(num_groups, 32)
x = torch.randn(4, 32, 8, 8)
out = gn(x)
print(f"groups={num_groups}, 出力平均: {out.mean().item():.4f}")
import torch.nn as nn
# 32チャンネルを異なるグループ数で
for num_groups in [1, 2, 4, 8, 32]:
gn = nn.GroupNorm(num_groups, 32)
x = torch.randn(4, 32, 8, 8)
out = gn(x)
print(f"groups={num_groups}, 出力平均: {out.mean().item():.4f}")
使用シーン
- 小さいバッチ: batch=1 でも有効
- 動画/3D: BatchNorm が不安定
- MobileNet: GroupNorm が BatchNorm を置き換える
注意:num_channels は num_groups で割り切れる必要があります。
その他の拡張機能
PyTorch torch.nn リファレンスマニュアル