Fonction torch.nn.LayerNorm de PyTorch
Manuel de référence torch.nn de PyTorch
torch.nn.LayerNormest le module de normalisation de couche dans PyTorch.
Contrairement à la normalisation par lots, la normalisation de couche normalise selon la dimension des caractéristiques d'un seul échantillon et ne dépend pas de la taille du lot.
Définition de fonction
torch.nn.LayerNorm(normalized_shape, eps=1e-05, elementwise_affine=True)
Description des paramètres :
normalized_shape(int ou list): Les dimensions à normaliser.eps(float): Epsilon pour la stabilité numérique. La valeur par défaut est 1e-5.elementwise_affine(bool): Indique s'il faut utiliser une mise à l'échelle et un décalage apprenables. La valeur par défaut est True.
Principe mathématique
Formule de la normalisation de couche :
y = (x - E[x]) / sqrt(Var[x] + eps) * gamma + beta
Différence avec la normalisation par lots : la normalisation de couche calcule la moyenne et la variance sur la dernière dimension des caractéristiques.
Exemples d'utilisation
Exemple 1 : Utilisation de base
Effectuer une normalisation de couche sur les caractéristiques :
Exemple
import torch.nn as nn
# Normalisation de couche : normaliser la dernière dimension
ln = nn.LayerNorm(normalized_shape=10)
# Entrée : batch=4, dimension de caractéristique=10
x = torch.randn(4, 10)
# Propagation avant
output = ln(x)
print("Forme d'entrée :", x.shape)
print("Forme de sortie :", output.shape)
print("Première ligne de l'entrée d'origine :", x[0].tolist())
print("Première ligne après normalisation :", output[0].tolist())
Exemple 2 : Entrée multidimensionnelle
Gestion des entrées 3D ou 4D :
Exemple
import torch.nn as nn
# Normaliser sur la dimension de séquence : (batch, seq, features)
ln_seq = nn.LayerNorm(normalized_shape=64)
# entrée 3D
x_3d = torch.randn(2, 10, 64)
output_3d = ln_seq(x_3d)
print("Entrée 3D :", x_3d.shape, "-> sortie :", output_3d.shape)
# entrée 4D (par ex., images) : (batch, height, width, channels)
# LayerNorm normalise la dernière dimension de canal
ln_channel = nn.LayerNorm(normalized_shape=128)
x_4d = torch.randn(2, 8, 8, 128)
output_4d = ln_channel(x_4d)
print("Entrée 4D :", x_4d.shape, "-> sortie :", output_4d.shape)
Exemple 3 : Utilisation dans un Transformer
Utilisation typique de LayerNorm :
Exemple
import torch.nn as nn
class TransformerBlock(nn.Module):
def __init__(self, d_model, nhead):
super(TransformerBlock, self).__init__()
self.self_attn = nn.MultiheadAttention(d_model, nhead, batch_first=True)
self.norm1 = nn.LayerNorm(d_model)
self.norm2 = nn.LayerNorm(d_model)
self.ffn = nn.Sequential(
nn.Linear(d_model, d_model * 4),
nn.GELU(),
nn.Linear(d_model * 4, d_model)
)
def forward(self, x):
# Auto-attention avec résidu
attn_out, _ = self.self_attn(x, x, x)
x = self.norm1(x + attn_out)
# FFN avec résidu
ffn_out = self.ffn(x)
x = self.norm2(x + ffn_out)
return x
# Test
block = TransformerBlock(d_model=512, nhead=8)
x = torch.randn(4, 100, 512) # (batch, seq, d_model)
output = block(x)
print("Forme d'entrée :", x.shape)
print("Forme de sortie :", output.shape)
Exemple 4 : Sans paramètres apprenables
Normalisation pure sans échelle ni décalage :
Exemple
import torch.nn as nn
# Sans paramètres apprenables
ln = nn.LayerNorm(16, elementwise_affine=False)
x = torch.randn(4, 16)
output = ln(x)
# Pas de poids ni de biais
print("A un poids :", hasattr(ln, 'weight'))
print("A un biais :", hasattr(ln, 'bias'))
print("Forme de sortie :", output.shape)
Comparaison des méthodes de normalisation
| Méthode | Dimension de normalisation | Dépendance au lot | Scénarios applicables |
|---|---|---|---|
BatchNorm |
Dimension de batch | Oui | CNN, batch stable |
LayerNorm |
Dimension des caractéristiques | non | Transformer, RNN |
InstanceNorm |
Canal + spatial | non | Transfert de style |
GroupNorm |
Regroupement de canaux | non | Scénarios de petits lots |
Questions fréquentes
Q1 : Quelle est la différence entre LayerNorm et BatchNorm ?
LayerNorm ne dépend pas de la taille du lot, ce qui le rend adapté aux modèles de séquence et aux scénarios où la taille du lot varie considérablement.
Q2 : Comment choisir normalized_shape ?
On choisit généralement la dimension des caractéristiques, comme 768 ou 1024 dans BERT.
Q3 : Pourquoi le Transformer utilise-t-il LayerNorm ?
La longueur de la séquence d'entrée du Transformer est variable, et LayerNorm est plus stable.
Cas d'utilisation
nn.LayerNormLes principaux scénarios d'application incluent :
- Architecture Transformer: BERT, GPT, etc.
- Réseaux de neurones récurrents: LSTM、GRU
- Traitement de séquences de longueur variable: la taille du lot n'est pas fixe
Astuce : LayerNorm est un composant standard de Transformer, placé après la connexion résiduelle (Post-LN) ou avant celle-ci (Pre-LN).
Autres extensions