- Authors

- Name
- Youngju Kim
- @fjvbn20031
목차
최적화 기초
볼록 최적화 (Convex Optimization)
함수 이 **볼록(convex)**이면, 임의의 두 점 와 에 대해 다음이 성립합니다.
볼록 함수의 핵심 성질:
- 모든 지역 최솟값(local minimum)이 전역 최솟값(global minimum)
- 경사 하강법이 수렴이 보장됨
- 딥러닝 손실 함수는 대부분 비볼록(non-convex)이지만, 볼록 분석 기법이 여전히 유용
강볼록(Strongly Convex): 이 존재하여 가 성립하면, 수렴 속도가 선형(linear convergence)으로 빨라집니다.
라그랑주 승수법
등호 제약 최적화 문제를 다룹니다.
라그랑주안(Lagrangian):
최적해에서 , 이 성립합니다.
KKT 조건
부등호 제약까지 포함한 일반적인 최적화:
KKT 조건 (필요 조건):
- 정류성(Stationarity):
- 원시 실현가능성(Primal feasibility): ,
- 쌍대 실현가능성(Dual feasibility):
- 상보 여유(Complementary slackness):
볼록 문제에서 KKT 조건은 충분 조건도 됩니다.
안장점 (Saddle Point)
딥러닝 최적화에서 큰 문제는 지역 최솟값보다 안장점입니다. 안장점에서는 일부 방향으로는 함수값이 증가하고 다른 방향으로는 감소하여 경사가 0이 됩니다. SGD의 확률적 노이즈가 안장점 탈출에 도움이 됩니다.
경사 하강법 계열
SGD와 그 변형
기본 SGD:
SGD with Momentum:
모멘텀 가 보통 사용되며, 이전 기울기 방향을 유지해 oscillation을 줄입니다.
Nesterov Accelerated Gradient (NAG):
현재 위치가 아니라 "앞을 내다본" 위치에서 기울기를 계산합니다.
AdaGrad, RMSProp, Adam
AdaGrad: 파라미터별 학습률 적응
자주 나타나는 특성은 학습률이 줄어들고, 드물게 나타나는 특성은 학습률이 큽니다. 단점: 학습률이 단조 감소하여 학습이 멈출 수 있습니다.
RMSProp: AdaGrad의 누적 문제 해결
Adam (Adaptive Moment Estimation):
Bias correction:
기본 하이퍼파라미터: , ,
import torch
import torch.optim as optim
model = ... # 모델 정의
# Adam optimizer
optimizer_adam = optim.Adam(
model.parameters(),
lr=1e-3,
betas=(0.9, 0.999),
eps=1e-8
)
# AdamW optimizer (weight decay 분리)
optimizer_adamw = optim.AdamW(
model.parameters(),
lr=1e-3,
betas=(0.9, 0.999),
eps=1e-8,
weight_decay=0.01 # L2와 독립적으로 적용
)
AdamW와 Lion
AdamW: Adam에서 weight decay를 L2 패널티가 아닌 파라미터 업데이트에 직접 적용합니다.
일반 Adam의 L2 정규화와 수학적으로 동등하지 않습니다 (자세한 설명은 퀴즈 참고).
Lion (EvoLved Sign Momentum):
Lion은 부호(sign)만 사용하므로 메모리 효율적이며, 업데이트 크기가 균일합니다.
| Optimizer | 메모리 | 수렴 속도 | 적합한 상황 |
|---|---|---|---|
| SGD+Momentum | 낮음 | 느림 | 컴퓨터 비전, 큰 배치 |
| Adam | 중간 | 빠름 | NLP, 범용 |
| AdamW | 중간 | 빠름 | Transformer 학습 |
| Lion | 낮음 | 빠름 | 대규모 모델 |
| L-BFGS | 높음 | 매우 빠름 | 소규모 모델 |
2차 최적화
Newton 방법
2차 미분(Hessian)을 활용합니다.
여기서 는 Hessian 행렬입니다. 이차 수렴(quadratic convergence)하지만, Hessian의 역행렬 계산이 으로 딥러닝에서 비현실적입니다.
L-BFGS (Limited-memory BFGS)
Hessian을 직접 저장하지 않고, 최근 개의 기울기 차이로 근사합니다.
여기서 , 입니다.
import torch
import torch.optim as optim
# L-BFGS는 클로저(closure) 함수 필요
optimizer = optim.LBFGS(
model.parameters(),
lr=1.0,
max_iter=20,
history_size=10,
line_search_fn='strong_wolfe'
)
def closure():
optimizer.zero_grad()
output = model(input_data)
loss = criterion(output, target)
loss.backward()
return loss
optimizer.step(closure)
자연 경사 하강법 (Natural Gradient)
Fisher Information Matrix를 사용하여 파라미터 공간의 곡률을 고려합니다.
Fisher Matrix:
K-FAC(Kronecker-factored Approximate Curvature)은 자연 경사법을 실용적으로 구현합니다.
학습률 스케줄링
Warmup
초기에 학습률을 서서히 증가시켜 학습을 안정화합니다.
Cosine Annealing
from torch.optim.lr_scheduler import CosineAnnealingLR, OneCycleLR, ReduceLROnPlateau
# Cosine Annealing
scheduler = CosineAnnealingLR(optimizer, T_max=100, eta_min=1e-6)
# OneCycleLR: Warmup + Cosine Decay
scheduler = OneCycleLR(
optimizer,
max_lr=1e-3,
total_steps=1000,
pct_start=0.3, # 30% warmup
anneal_strategy='cos'
)
# ReduceLROnPlateau: 검증 손실이 개선되지 않으면 감소
scheduler = ReduceLROnPlateau(
optimizer,
mode='min',
factor=0.5,
patience=10,
min_lr=1e-6
)
Cyclical Learning Rate (CLR)
학습률을 주기적으로 변동시켜 안장점 탈출을 돕습니다.
| 스케줄러 | 특징 | 적합한 상황 |
|---|---|---|
| Cosine Annealing | 부드러운 감소 | Transformer 사전학습 |
| OneCycleLR | Warmup + 빠른 감소 | 파인튜닝, 짧은 학습 |
| ReduceLROnPlateau | 적응형 | 일반 학습, 검증 필요 |
| Cyclical LR | 주기적 변동 | 안장점 회피 |
| Linear Warmup | 초기 안정화 | LLM 학습 |
정규화 기법
L1 / L2 정규화
L2 정규화 (Ridge):
기울기:
L1 정규화 (Lasso):
L1은 희소(sparse) 솔루션을 유도합니다.
Batch Normalization vs Layer Normalization
Batch Normalization (BN):
여기서 , 는 미니배치 내 통계량입니다. 배치 방향으로 정규화합니다.
Layer Normalization (LN):
여기서 통계량은 각 샘플의 피처 차원을 따라 계산됩니다.
| 정규화 | 통계량 계산 방향 | 적합한 상황 |
|---|---|---|
| Batch Norm | 배치 방향 (같은 피처) | CNN, 큰 배치 |
| Layer Norm | 피처 방향 (같은 샘플) | Transformer, RNN |
| Instance Norm | 공간 방향 (같은 채널) | 스타일 전이 |
| Group Norm | 채널 그룹 | 작은 배치 |
Weight Decay vs L2 정규화
SGD에서:
이 경우 weight decay와 L2 정규화는 동일합니다. 하지만 Adam에서는:
- L2 Adam: 기울기에 를 더한 후 적응형 학습률 적용 → 적응 계수로 나누어져 정규화 효과 약화
- AdamW: 파라미터 업데이트 후 를 직접 빼냄 → 모든 파라미터에 균등한 weight decay
# Dropout
import torch.nn as nn
class RegularizedModel(nn.Module):
def __init__(self):
super().__init__()
self.fc1 = nn.Linear(512, 256)
self.bn1 = nn.BatchNorm1d(256)
self.ln1 = nn.LayerNorm(256)
self.dropout = nn.Dropout(p=0.3)
def forward(self, x):
x = self.fc1(x)
x = self.bn1(x) # 또는 self.ln1(x)
x = torch.relu(x)
x = self.dropout(x)
return x
손실 함수 설계
Cross-Entropy Loss
이진 분류:
Focal Loss
클래스 불균형 문제를 해결합니다. 쉬운 샘플의 기여를 줄입니다.
여기서 는 정답 클래스의 예측 확률, 는 focusing parameter입니다. 이면 일반 Cross-Entropy와 동일합니다.
import torch
import torch.nn.functional as F
class FocalLoss(torch.nn.Module):
def __init__(self, alpha=0.25, gamma=2.0):
super().__init__()
self.alpha = alpha
self.gamma = gamma
def forward(self, logits, targets):
bce_loss = F.binary_cross_entropy_with_logits(
logits, targets.float(), reduction='none'
)
p = torch.sigmoid(logits)
p_t = p * targets + (1 - p) * (1 - targets)
focal_weight = (1 - p_t) ** self.gamma
alpha_t = self.alpha * targets + (1 - self.alpha) * (1 - targets)
loss = alpha_t * focal_weight * bce_loss
return loss.mean()
Contrastive Loss와 Triplet Loss
Contrastive Loss (Siamese Network):
여기서 , 이면 유사 쌍, 이면 비유사 쌍입니다.
Triplet Loss:
앵커(a), 포지티브(p), 네거티브(n) 샘플을 사용합니다.
InfoNCE Loss (NT-Xent)
대조 학습(Contrastive Learning)의 핵심 손실 함수입니다.
여기서 는 temperature parameter, 은 코사인 유사도입니다.
import torch
import torch.nn.functional as F
def info_nce_loss(features, temperature=0.07):
"""
features: (2N, D) - 각 이미지의 두 augmentation view
"""
N = features.shape[0] // 2
features = F.normalize(features, dim=1)
# 유사도 행렬 계산
similarity = torch.matmul(features, features.T) / temperature
# 자기 자신 제거 (대각선을 -inf로)
mask = torch.eye(2 * N, dtype=torch.bool, device=features.device)
similarity.masked_fill_(mask, float('-inf'))
# 포지티브 쌍: i와 i+N, i+N과 i
labels = torch.cat([
torch.arange(N, 2 * N),
torch.arange(N)
]).to(features.device)
loss = F.cross_entropy(similarity, labels)
return loss
LLM 학습 최적화
Gradient Clipping
기울기 폭발(exploding gradient)을 방지합니다.
import torch
def train_with_clipping(model, optimizer, loss, max_norm=1.0):
optimizer.zero_grad()
loss.backward()
# 기울기 노름 모니터링
total_norm = 0
for p in model.parameters():
if p.grad is not None:
param_norm = p.grad.data.norm(2)
total_norm += param_norm.item() ** 2
total_norm = total_norm ** 0.5
# 클리핑 적용
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=max_norm)
optimizer.step()
return total_norm
ZeRO Optimizer (Zero Redundancy Optimizer)
모델 학습 시 메모리를 3단계로 최적화합니다.
| ZeRO 단계 | 분산 대상 | 메모리 절감 |
|---|---|---|
| Stage 1 | Optimizer 상태 | ~4x |
| Stage 2 | + 기울기 | ~8x |
| Stage 3 | + 파라미터 | ~64x (N GPU 기준) |
혼합 정밀도(mixed precision) + ZeRO-3로 수십억 파라미터 모델을 단일 노드에서 학습 가능합니다.
8-bit Adam
양자화(quantization)를 통해 optimizer 상태를 FP32 대신 INT8로 저장합니다.
- Optimizer 상태 메모리를 75% 절감 (FP32 대비)
- Block-wise quantization으로 정밀도 손실 최소화
bitsandbytes라이브러리로 구현 가능
# bitsandbytes 8-bit Adam
import bitsandbytes as bnb
optimizer = bnb.optim.Adam8bit(
model.parameters(),
lr=1e-4,
betas=(0.9, 0.999)
)
Adafactor
Adam의 2차 모멘트를 행렬 분해로 근사합니다.
파라미터 크기에 비례한 메모리만 사용 (행 + 열 벡터). T5, PaLM 등 초대형 모델 학습에 사용됩니다.
| Optimizer | 메모리 (파라미터 기준 배수) | LLM 적합도 |
|---|---|---|
| Adam | 8x (params + 2 states) | 보통 |
| AdamW | 8x | 좋음 |
| 8-bit Adam | 6x | 좋음 |
| Adafactor | ~2x | 매우 좋음 |
| Lion | 6x | 좋음 |
퀴즈
Q1. Adam optimizer에서 bias correction이 필요한 이유는 무엇인가요?
정답: 초기 모멘트 추정값의 0 초기화로 인한 편향을 보정하기 위해서입니다.
설명: Adam에서 , 으로 초기화하면, 초기 타임스텝 에서 와 는 실제 기울기의 모멘트를 과소평가합니다. 예를 들어 에서 이고, 이는 실제 기댓값 인데, 이를 로 복원하려면 을 곱해야 합니다. 일 때 에서 로 보정됩니다. 가 충분히 크면 이므로 보정 계수가 1에 수렴하여 효과가 사라집니다.
Q2. Weight Decay와 L2 정규화가 Adam에서 동등하지 않은 이유는?
정답: Adam의 적응형 학습률이 L2 페널티 기울기를 스케일링하기 때문입니다.
설명: SGD에서는 로 두 방식이 수학적으로 동일합니다. 그러나 Adam에서 L2 정규화를 추가하면 기울기가 가 되고, 이것이 적응형 스케일링 계수 로 나누어집니다. 따라서 가중치가 큰 파라미터(큰 )는 L2 페널티도 작아집니다. AdamW는 weight decay를 적응형 스케일링 밖으로 꺼내어 로 처리함으로써, 모든 파라미터에 균등한 정규화를 적용합니다.
Q3. Batch Normalization과 Layer Normalization의 차이와 적합한 상황은?
정답: BN은 배치 차원에서, LN은 피처 차원에서 정규화합니다.
설명: BN은 미니배치 내 같은 피처(뉴런)들의 평균/분산으로 정규화합니다. 따라서 배치 크기에 의존하며, 배치 크기가 작으면 통계량 추정이 불안정해집니다. CNN처럼 공간적 피처가 있고 배치 크기가 충분한 경우에 적합합니다. LN은 각 샘플의 피처 차원을 따라 정규화하므로 배치 크기에 독립적입니다. Transformer처럼 시퀀스 길이가 가변적이거나 RNN처럼 배치 통계를 유지하기 어려운 상황에 적합합니다. 추론 시에도 배치 통계가 필요 없으므로 온라인 추론에 유리합니다.
Q4. Focal Loss가 Cross-Entropy보다 클래스 불균형에 효과적인 수학적 원리는?
정답: 가중치가 쉬운 샘플의 기여를 동적으로 감소시키기 때문입니다.
설명: 일반 CE 손실은 로 쉽게 분류되는 다수 클래스 샘플도 동일하게 기여합니다. Focal Loss의 항을 살펴보면, (쉬운 샘플)일 때 로 가중치가 매우 작아집니다. 반면 (어려운 샘플)일 때 로 거의 그대로 유지됩니다. 를 사용하면 쉬운 샘플의 손실이 100배 감소합니다. 이를 통해 모델이 어려운 소수 클래스 샘플에 집중하여 학습합니다.
Q5. InfoNCE Loss가 대조 학습에서 좋은 표현을 학습하는 원리는?
정답: 같은 이미지의 다른 augmentation 쌍을 유사하게, 다른 이미지는 멀어지도록 학습합니다.
설명: InfoNCE는 상호 정보량(mutual information)의 하한을 최대화합니다. 분자 는 포지티브 쌍(같은 이미지의 두 뷰)의 유사도를 높이고, 분모는 개의 네거티브 쌍을 포함합니다. Temperature 는 분포의 날카로움을 조절합니다. 가 작을수록 경쟁이 치열해져 표현 공간이 더 구별적이 됩니다. 대규모 배치에서 다양한 네거티브 샘플을 제공하면 표현이 더욱 일반화됩니다. SimCLR, MoCo, CLIP 등 주요 대조 학습 모델이 이 손실 함수를 사용합니다.