Función PyTorch torch.nn.GroupNorm
Manual de referencia de PyTorch torch.nn
torch.nn.GroupNormEs el módulo de normalización por grupos en PyTorch.
Divide los canales en grupos para la normalización, no depende del tamaño del lote (batch size), adecuado para lotes pequeños o secuencias de longitud variable.
Definición de la función
torch.nn.GroupNorm(num_groups, num_channels, eps=1e-05, affine=True)
Parámetros:
num_groups: Número de gruposnum_channels: Número de canales, debe ser divisible por num_groups
Ejemplo de uso
Ejemplo 1: Uso básico
Ejemplo
import torch
import torch.nn as nn
# GroupNorm: 4 grupos, 32 canales
gn = nn.GroupNorm(num_groups=4, num_channels=32)
# Entrada: (batch, channels, height, width)
x = torch.randn(8, 32, 16, 16)
output = gn(x)
print("Forma de entrada:", x.shape)
print("Forma de salida:", output.shape)
import torch.nn as nn
# GroupNorm: 4 grupos, 32 canales
gn = nn.GroupNorm(num_groups=4, num_channels=32)
# Entrada: (batch, channels, height, width)
x = torch.randn(8, 32, 16, 16)
output = gn(x)
print("Forma de entrada:", x.shape)
print("Forma de salida:", output.shape)
Ejemplo 2: Caso especial - InstanceNorm
Ejemplo
import torch
import torch.nn as nn
# InstanceNorm es un caso especial donde num_groups=num_channels
inorm = nn.InstanceNorm2d(32)
# Equivalente a 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 es un caso especial donde num_groups=num_channels
inorm = nn.InstanceNorm2d(32)
# Equivalente a 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())
Ejemplo 3: GroupNorm en ResNet
Ejemplo
import torch
import torch.nn as nn
# La estructura ResNet usa 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("Entrada:", x.shape, "-> Salida:", output.shape)
import torch.nn as nn
# La estructura ResNet usa 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("Entrada:", x.shape, "-> Salida:", output.shape)
Ejemplo 4: Efecto de diferentes num_groups
Ejemplo
import torch
import torch.nn as nn
# 32 canales, con diferentes números de grupos
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}, media de salida: {out.mean().item():.4f}")
import torch.nn as nn
# 32 canales, con diferentes números de grupos
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}, media de salida: {out.mean().item():.4f}")
Casos de uso
- Batch pequeño: sigue siendo válido cuando batch=1
- Video/3D: BatchNorm es inestable
- MobileNet: GroupNorm reemplaza a BatchNorm
Nota: num_channels debe ser divisible por num_groups.
Otras extensiones