기울기가 깊은 신경망을 통과해 흐르면 층마다 활성화 분포가 달라져(Internal Covariate Shift, 2015년에 처음 제시된 설명). 정규화 층은 각 층의 입력이 안정적인 평균과 분산을 갖도록 만들어 기울기를 수치적으로 양호한 상태로 유지해. 덕분에 더 깊은 모델을 더 높은 학습률로 더 안정적으로 학습할 수 있어.
BatchNorm
배치 차원을 기준으로 정규화해. 각 특징에서 배치 평균을 빼고 배치 표준편차로 나눈 뒤, 특징마다 학습 가능한 스케일과 시프트를 더해. CNN, 특히 ResNet 계열에서 사용해. 작은 배치 크기(배치=1, 배치=8)에서는 통계량을 신뢰하기 어렵고, 학습과 평가에서 동작도 달라져. 평가에서는 누적 통계를 사용하는데, 이 차이가 버그를 일으키는 것으로 유명해.
LayerNorm
각 예시 안의 특징 차원을 기준으로 정규화해. 예시마다 평균을 빼고 표준편차로 나눠. 배치 차원을 다루기 까다로운 variable-length 시퀀스에 잘 맞아서 Transformer에서 사용해. 학습과 평가를 구분하지 않고 어느 쪽에서든 똑같이 동작해.
팁: 무엇을 쓸지 결정하기 어렵다면 큰 배치와 고정 형태를 쓰는 비전 CNN에는 BatchNorm을, 작거나 variable 배치 형태를 쓰는 Transformer에는 LayerNorm을 골라. LayerNorm을 단순화한 RMSNorm은 LLaMA를 비롯한 현재 LLM에서 사용하는 현대적인 변형이야.
어디에 둘까
흔한 패턴은 두 가지야. Pre-norm은 층 앞에서 정규화해: x = x + sublayer(LayerNorm(x)). 매우 깊은 Transformer를 더 안정적으로 학습할 수 있어. Post-norm은 층 뒤에서 정규화해: x = LayerNorm(x + sublayer(x)). Original Transformer가 사용한 방식이야. 현대 Transformer는 기본적으로 pre-norm을 사용해.
원칙: 정규화는 2026년에 깊은 신경망을 학습 가능하게 만드는 요소야. 아키텍처에 맞지 않는 종류를 골라도(Transformer에 BN, 작은 CNN에 LN) 대개 작동하지만, 정확도나 안정성을 10-20% 잃을 수 있어. 정규화 종류를 아키텍처에 맞춰.
Code
코드로 비교하는 BatchNorm과 LayerNorm·python
import torch, torch.nn as nn
# CNN with BatchNorm
cnn = nn.Sequential(
nn.Conv2d(3, 64, 3, padding=1),
nn.BatchNorm2d(64), # normalize across batch+spatial, per channel
nn.ReLU(),
nn.Conv2d(64, 128, 3, padding=1),
nn.BatchNorm2d(128),
nn.ReLU(),
)
# Transformer block with LayerNorm
class TransformerBlock(nn.Module):
def __init__(self, d_model, n_heads):
super().__init__()
self.norm1 = nn.LayerNorm(d_model)
self.attn = nn.MultiheadAttention(d_model, n_heads, batch_first=True)
self.norm2 = nn.LayerNorm(d_model)
self.ffn = nn.Sequential(
nn.Linear(d_model, 4 * d_model), nn.GELU(),
nn.Linear(4 * d_model, d_model),
)
def forward(self, x):
# Pre-norm pattern
x = x + self.attn(self.norm1(x), self.norm1(x), self.norm1(x), need_weights=False)[0]
x = x + self.ffn(self.norm2(x))
return x