← Day 5
Phase 0 · Week 1 · Day 6
Day 7 →
Day 6 — 최적화, 초기화, 손실 지형
엔진으로 진짜 학습을 한다 — 그런데 "loss가 줄었다"에서 멈추지 않는다.
초기화 이론(분산 보존, Xavier/He)으로 왜 시작점이 학습을 좌우하는지,
SGD·모멘텀·Adam을 직접 구현해 각 옵티마이저가 손실 지형을 어떻게 항해하는지,
결정경계와 loss landscape를 시각화해 비볼록 최적화의 실제 모습을 본다.
two-moons 같은 비선형 문제로 MLP의 표현력을 눈으로 확인한다.
🎯 오늘의 목표
- 분산 보존 논증으로 Xavier/He 초기화를 유도한다
- SGD/모멘텀/Adam을 직접 구현하고 갱신식을 안다
- 초기화×학습률의 상호작용을 실험으로 해부한다
- two-moons를 MLP로 학습하고 결정경계를 시각화한다
- 1D/2D 손실 단면으로 비볼록 지형을 관찰한다
- 학습 진단(grad norm, 활성값 분포)을 습관화한다
📖 개념 (수업)
1. 초기화 이론 — 분산 보존
랜덤 초기화의 스케일이 왜 중요한가? 신호가 층을 통과하며 분산이 폭발하거나 소실되면, 깊은 망은
처음부터 학습 불능이다. 선형층 $y = Wx$($W\in\mathbb{R}^{d_\text{out}\times d_\text{in}}$, 원소 i.i.d. 평균0 분산$\sigma_W^2$)에서,
입력이 분산 $\sigma_x^2$로 독립이라 가정하면 출력 원소의 분산은
$$\mathrm{Var}(y_i) = d_\text{in}\,\sigma_W^2\,\sigma_x^2$$
forward에서 분산을 보존하려면 $\sigma_W^2 = 1/d_\text{in}$. backward에서 gradient 분산을 보존하려면 $\sigma_W^2 = 1/d_\text{out}$.
둘을 절충한 게 Xavier/Glorot: $\sigma_W^2 = 2/(d_\text{in}+d_\text{out})$. ReLU는 음수 절반을 죽여 분산을 반토막내므로
보정 계수 2를 곱한 He 초기화 $\sigma_W^2 = 2/d_\text{in}$를 쓴다. 이게 "왜 kaiming_normal_인가"의 답이다.
심화 이 분산 논증의 현대적 일반화가 신호전파 이론(Poole et al. 2016)과
NTK(Jacot et al. 2018)다. 초기화 스케일이 "혼돈/질서 상전이"의 경계(edge of chaos)에 있을 때
깊은 신호가 가장 잘 전파된다. 트랜스포머의 residual·LN도 이 분산 가계부를 맞추는 장치로 읽을 수 있다.
2. 경사하강과 그 친척들
비볼록 $\hat R(\theta)$를 1차 방법으로 내려간다. 세 갱신식을 정확히:
| 옵티마이저 | 갱신식 | 직관 |
| SGD | $\theta \leftarrow \theta - \eta\, g$ | 가장 가파른 방향 한 걸음 |
| Momentum | $v \leftarrow \mu v + g;\ \ \theta \leftarrow \theta - \eta v$ | 관성으로 협곡 진동 억제·가속 |
| Adam | $m\leftarrow\beta_1 m+(1{-}\beta_1)g;\ v\leftarrow\beta_2 v+(1{-}\beta_2)g^2;$ $\hat m=\tfrac{m}{1-\beta_1^t};\ \hat v=\tfrac{v}{1-\beta_2^t};\ \theta\leftarrow\theta-\eta\tfrac{\hat m}{\sqrt{\hat v}+\epsilon}$ | 좌표별 적응 스텝(2차 모멘트로 정규화) |
Adam의 $\hat v$로 나누는 항이 핵심: gradient가 큰 좌표는 스텝을 줄이고 작은 좌표는 키워, 조건수가 나쁜 지형에서도 잘 간다.
바이어스 보정 $\hat m, \hat v$는 초기 $m,v=0$ 편향을 상쇄한다. 트랜스포머 학습은 거의 항상 AdamW
(weight decay를 gradient가 아닌 파라미터에 직접 — Loshchilov & Hutter 2019)다. Phase 1에서 그대로 쓴다.
3. 옵티마이저를 추상화 — PyTorch처럼
Neuron/Layer/MLP는 Day 1 구조 그대로(이제 ReLU/He 초기화 적용). 새로 만들 것은 옵티마이저 객체다.
파라미터 리스트를 받아 step()과 zero_grad()를 제공한다 — PyTorch optim의 미니 버전.
class SGD:
def __init__(self, params, lr, momentum=0.0):
self.params, self.lr, self.mu = params, lr, momentum
self.v = [0.0 for _ in params]
def step(self):
# TODO: v ← mu*v + p.grad ; p.data -= lr * v
...
def zero_grad(self):
for p in self.params: p.grad = 0.0
class Adam:
# TODO: m, v 버퍼 + 바이어스 보정 + 좌표별 갱신 (위 표)
...
4. 손실 지형 — 비볼록의 실제 모습
학습을 "loss 숫자"가 아니라 지형 위의 궤적으로 본다. 고차원 $\theta$를 직접 못 보니 단면을 뜬다:
- 1D 단면: 학습 전후 파라미터 $\theta_0,\theta^\star$를 잇는 직선 $\theta(\alpha)=(1-\alpha)\theta_0+\alpha\theta^\star$ 위에서 loss를 플롯.
- 2D 단면: 두 랜덤 방향 $d_1,d_2$(필터별 정규화, Li et al. 2018)로 $\theta^\star + a d_1 + b d_2$의 loss 등고선.
여기서 안장점·평탄골·날카로운/평평한 최소값을 눈으로 본다. "평평한 최소값이 더 잘 일반화한다"는 가설(Hochreiter–Schmidhuber, Keskar et al.)도
이 시각화로 직관화된다. Phase 3에서 큰 모델의 일반화를 논할 때 다시 등장.
5. 진단 습관 — 학습이 안 될 때 보는 것
최고수준이라면 "loss가 안 줄어요"에서 멈추지 않는다. 항상 보는 계기판:
- grad norm $\|g\|$: 폭발(→clip/낮은 lr)인지 소실(→초기화/구조)인지
- 활성값 분포: 층별 평균·분산이 보존되는지(죽은 ReLU, 포화 tanh 탐지)
- 업데이트/파라미터 비율 $\eta\|g\|/\|\theta\| \approx 10^{-3}$ 가 건강한 범위(Karpathy 경험칙)
- train vs val: 갈라지면 overfit, 둘 다 높으면 underfit/버그
✍️ 직접 해보기 (강도 ↑)
과제 1 — 초기화 분산 실험.
깊이 20 ReLU MLP에서 초기화 스케일을 $\sigma_W^2 \in \{1/d, 2/d, 1\}$로 바꿔 층별 활성값 분산을
측정·플롯해라. He($2/d$)에서 분산이 보존되고, $1$에서 폭발, $1/d$에서 ReLU 때문에 서서히 소실됨을 보여라.
forward 분산 식 $\mathrm{Var}(y)=d\sigma_W^2\sigma_x^2$ 와 정량 일치 확인.
과제 2 — 옵티마이저 3종 구현 + 비교.
SGD/Momentum/Adam을 구현하고, Rosenbrock 또는 조건수 나쁜 2차함수에서 수렴 궤적을 등고선 위에 그려라.
Adam이 협곡에서 SGD보다 빠른 이유를 좌표별 스텝으로 설명.
과제 3 — two-moons 분류.
sklearn.datasets.make_moons로 비선형 데이터 생성, micrograd MLP(예: 2-16-16-1, tanh/ReLU)로 학습.
결정경계를 등고선으로 시각화하고, 은닉 너비/깊이를 바꿀 때 경계 복잡도가 어떻게 변하는지 관찰(Day 1 선형영역과 연결).
과제 4 — 손실 단면 시각화.
학습된 모델의 1D 보간 단면과 2D 필터정규화 단면(Li et al. 2018)을 그려라. 평평/날카로운 최소값을 식별하고,
배치 크기를 키웠을 때 단면이 더 날카로워지는지(Keskar 가설) 실험으로 점검.
과제 5 — zero_grad 함정 + lr×init.
zero_grad를 빼면 학습이 어떻게 망가지는지 grad norm 폭발로 확인. 그리고 (초기화, 학습률) 격자를 훑어
학습 성공/발산 상도(phase diagram)를 그려라 — 좋은 초기화가 허용 lr 범위를 넓힘을 보여라.
도전 학습률 탐색기. lr을 지수적으로 증가시키며 한 배치씩 돌려 loss를 기록하는
LR range test(Smith 2017)를 구현하고, "loss가 최소 기울기로 감소하는 lr"을 자동 추정해 과제 3에 적용하라.
✅ 스스로 확인
- He/Xavier를 분산 보존으로 유도하고 실험으로 확인했다
- SGD/Momentum/Adam 갱신식을 유도 없이 쓰고 구현했다
- two-moons 결정경계가 비선형으로 휘는 걸 시각화했다
- 손실 단면에서 비볼록 구조를 관찰했다
- grad norm·업데이트 비율 등 진단 계기판을 읽을 수 있다
📝 오늘의 기록
docs/00_day06.md:
- 초기화 분산 실험 플롯 + 식과의 정량 일치
- 옵티마이저 3종 수렴 궤적 비교 + two-moons 결정경계
- lr×init 상도(phase diagram)와 해석
이제 학습 루프 전체를 처음부터 통제한다. forward·loss·backward·step의 네 단계는
GPT 학습에서도 토씨 하나 안 바뀐다. 다만 차이는 규모와 디테일(AdamW, LR 스케줄, mixed precision) —
Phase 1 Week 6에서 그대로 확장한다. 오늘 만든 진단 습관이 그때 디버깅의 무기가 된다.
다음 (Day 7): 한 주를 통합한다. micrograd ↔ PyTorch autograd 내부(grad_fn/tape) 대응을 정밀히 짚고,
스칼라 AD의 한계(벡터화 부재)를 정량화해 Week 2(텐서)의 동기를 못박는다.
그리고 "reverse-mode AD를 처음부터" 기술 글을 완성한다 — 포트폴리오의 첫 글.
← Day 5
Day 6 끝
Day 7 — 통합 & 글쓰기 →