본문 바로가기
C.W.K.
Stream
Lesson 07 of 08 · published

정규화 (BatchNorm, LayerNorm, GroupNorm)과 풀링

~12 min · batchnorm, layernorm, groupnorm, pool

Level 0텐서 탐구자
0 XP0/62 lessons0/13 achievements
0/120 XP to next level120 XP to go0% complete

정규화는 깊은 신경망의 학습을 안정시켜

정규화 계층은 활성화의 중심과 크기를 다시 맞춰 학습을 안정시켜. 흔한 변형은 세 가지지만 서로 마음대로 바꿔 쓸 수는 없어. 데이터와 작업의 모양에 맞춰 골라야 해:

  • BatchNorm2d: 각 채널을 배치 전체에 걸쳐 정규화해. CNN의 표준 선택이야. 통계를 안정적으로 추정하려면 보통 16개 이상의 충분한 배치가 필요해. train()에서는 배치 통계를 쓰고 eval()에서는 버퍼에 저장한 누적 평균과 분산을 사용해.
  • LayerNorm: 특징 차원에 걸쳐 샘플별로 정규화해. Transformer의 표준 선택이며 배치 크기에 영향을 받지 않고 추론 동작도 안정적이야.
  • GroupNorm: 채널을 여러 그룹으로 나누고 각 그룹 안에서 정규화해. 배치 크기가 1이어도 잘 작동해. GPU당 배치가 2개인 경우도 흔한 COCO 객체 탐지나 일부 비전 Transformer에서 사용해.

왜 BatchNorm을 아무 데나 쓰면 안 될까?

BatchNorm에서는 한 샘플의 정규화가 같은 배치의 다른 샘플에 의존하므로 샘플 사이에 정보가 섞여. RNN의 각 단계, 다중 작업, 배치 간 결합을 원하지 않는 대조 학습에서는 문제가 될 수 있어. 작은 배치와 샘플 하나씩 처리하는 추론에도 취약해. LayerNorm은 이런 문제를 피할 수 있어서 Transformer의 표준으로 자리 잡았어.

풀링

MaxPool2d는 각 창의 최댓값을, AvgPool2d는 평균을 골라. AdaptiveAvgPool2d(out_size)는 요청한 출력 크기에 맞춰 창 크기를 알아서 정해 주는 편리한 도구야. CNN 백본 끝에 AdaptiveAvgPool2d(1)을 두면 입력 이미지 크기와 관계없이 하나의 특징 벡터를 만들 수 있어.

Code

BatchNorm2d: CNN 용·python
import torch
import torch.nn as nn

bn = nn.BatchNorm2d(64)             # normalizes per-channel across batch
x = torch.randn(32, 64, 16, 16)     # batch=32

bn.train()
out_train = bn(x)                    # uses batch stats
print(bn.running_mean.shape)         # torch.Size([64]) — buffer

bn.eval()
out_eval = bn(x)                     # uses running stats
LayerNorm: Transformer 용·python
import torch
import torch.nn as nn

# Normalize the LAST dim (features), per-sample
ln = nn.LayerNorm(512)
x = torch.randn(32, 16, 512)         # batch=32, seq=16, features=512
out = ln(x)
print(out.mean(dim=-1).abs().max())  # ~0  (zero mean per-sample-per-position)
print(out.std(dim=-1).mean())        # ~1
GroupNorm: 작은 배치에서도 샘플 사이 결합이 없어·python
import torch
import torch.nn as nn

# 64 channels split into 8 groups of 8 channels each
gn = nn.GroupNorm(num_groups=8, num_channels=64)
x = torch.randn(2, 64, 16, 16)       # batch=2 — too small for BatchNorm
out = gn(x)
print(out.shape)                      # torch.Size([2, 64, 16, 16])
풀링: 그리고 AdaptiveAvgPool 요령·python
import torch
import torch.nn as nn

x = torch.randn(8, 64, 32, 32)

mp = nn.MaxPool2d(2)                  # halves spatial
print(mp(x).shape)                     # torch.Size([8, 64, 16, 16])

ap = nn.AvgPool2d(4)
print(ap(x).shape)                     # torch.Size([8, 64, 8, 8])

# AdaptiveAvgPool — outputs a fixed spatial size regardless of input
gap = nn.AdaptiveAvgPool2d(1)
print(gap(x).shape)                    # torch.Size([8, 64, 1, 1])

# Same module on a different input size still produces 1x1
y = torch.randn(8, 64, 224, 224)
print(gap(y).shape)                    # torch.Size([8, 64, 1, 1])

External links

Exercise

같은 2계층 MLP를 두 개 만들어 봐. 하나에는 계층 사이에 LayerNorm을 넣고 다른 하나에는 넣지 마. 무작위 데이터로 둘 다 100단계 학습하고 손실 곡선을 그려. LayerNorm을 넣은 모델이 더 빠르고 부드럽게 수렴하는지 확인하면서, 모든 Transformer 블록에 적어도 하나의 LayerNorm이 들어가는 이유를 생각해 봐.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.