이 장에서 이 세 질문에 차례로 답한다. 셋 모두 “이론”이 아니라, 딥러닝을 실제로 돌릴 때 매번 부딪히는 실전의 문제들이다. 그리고 장의 마지막에서는 여기까지 모은 도구 전부 — MLP, 손실, 경사하강, 과적합 관리 — 를 산업 현장에서 가장 흔한 정형 데이터에 처음으로 적용할 준비를 한다.
6.2 학습률 (Learning Rate)
6.2.1 학습률의 역할
학습률 \(\eta\)는 경사하강법에서 가장 중요한 하이퍼파라미터이다.
학습률
효과
너무 작으면
수렴이 매우 느림, 학습 시간 낭비
적절하면
안정적으로 최솟값에 도달
너무 크면
최솟값 주변을 진동하거나 발산
6.2.2 수치 비교
\(\mathcal{L}(\theta) = (\theta - 3)^2\)에서 다양한 학습률로 10스텝 실행:
코드
import pandas as pdetas = [0.01, 0.05, 0.1, 0.3, 0.5, 0.9]rows = []for eta in etas: theta =0.0for _ inrange(10): grad =2* (theta -3) theta = theta - eta * grad loss = (theta -3) **2if loss <0.01: status ='수렴'elif loss <1.0: status ='수렴 중'elif loss >100: status ='발산!'else: status ='느림' rows.append({'학습률 $\\eta$': eta,'10스텝 후 $\\theta$': f'{theta:.4f}','10스텝 후 손실': f'{loss:.4f}'if loss <1e6elsef'{loss:.2e}','상태': status, })pd.DataFrame(rows).to_html(index=False, border=0, escape=False)
표 6.1: 학습률에 따른 수렴 비교 (10 스텝 후)
학습률 \(\\eta\)
10스텝 후 \(\\theta\)
10스텝 후 손실
상태
0.01
0.5488
6.0085
느림
0.05
1.9540
1.0942
느림
0.10
2.6779
0.1038
수렴 중
0.30
2.9997
0.0000
수렴
0.50
3.0000
0.0000
수렴
0.90
2.6779
0.1038
수렴 중
Ch03의 1차원 경사하강법 인터랙티브에서 학습률 슬라이더를 0.9까지 올렸을 때 본 것과 같은 현상이다. 실무에서는 보통 0.1~0.0001 범위에서 시작해, 러닝커브(이 장 후반)를 보며 조정한다.
6.3 배치 크기 (Batch Size)
6.3.1 전체 배치 vs 확률적 경사하강법
실제 딥러닝에서는 수천~수백만 개의 데이터가 있다. 매번 전체 데이터로 그래디언트를 계산하면 비용이 매우 크다.
배치 크기에 따른 경사하강법 분류
방법
배치 크기
특징
Full-batch GD
전체 데이터 (\(n\))
정확한 그래디언트, 느린 갱신
SGD
1개
매우 빠른 갱신, 높은 노이즈
Mini-batch SGD
\(B\)개 (보통 32~256)
속도와 안정성의 균형
6.3.2 수치 예시
10개 데이터에 대해 배치 크기별 1 에폭(epoch) 동안의 파라미터 갱신 횟수:
코드
import pandas as pdn =10batches = [10, 5, 2, 1]rows = []for b in batches: updates = n // b method ="Full-batch GD"if b == n else"SGD"if b ==1elsef"Mini-batch (B={b})" rows.append({'방법': method,'배치 크기': b,'갱신 횟수': f'{n} / {b} = {updates}','그래디언트 정확도': '높음'if b == n else'낮음'if b ==1else'중간','갱신 속도': '느림'if b == n else'빠름'if b ==1else'중간', })pd.DataFrame(rows).to_html(index=False, border=0, escape=False)
표 6.2: 배치 크기에 따른 1 에폭 갱신 횟수 (데이터 10개)
방법
배치 크기
갱신 횟수
그래디언트 정확도
갱신 속도
Full-batch GD
10
10 / 10 = 1
높음
느림
Mini-batch (B=5)
5
10 / 5 = 2
중간
중간
Mini-batch (B=2)
2
10 / 2 = 5
중간
중간
SGD
1
10 / 1 = 10
낮음
빠름
핵심: 배치 크기가 작을수록 갱신이 자주 일어나지만 그래디언트에 노이즈가 많고, 클수록 안정적이지만 느리다. 실무에서는 보통 32~256 크기의 미니배치를 사용한다.
인터랙티브 — 배치 크기에 따른 경사하강법 비교
같은 목표 함수에서 배치 크기에 따라 그래디언트 경로가 어떻게 달라지는지 확인하세요. 작은 배치는 노이즈가 많지만 빠르게 탐색하고, 큰 배치는 안정적이지만 느립니다. (배치 크기에 따른 그래디언트 노이즈는 이 시뮬레이션에서 인공적으로 재현한 것입니다 — 실제로는 배치에 어떤 데이터가 뽑히느냐에 따라 생깁니다.)
viewof batchSize = Inputs.radio(["full","mini","sgd"], {label:"배치 방법",value:"mini",format: k => k ==="full"?"Full-batch (B=10)": k ==="mini"?"Mini-batch (B=3)":"SGD (B=1)"})viewof batchEta = Inputs.range([0.01,0.5], { step:0.01,label:"학습률 η",value:0.1 })viewof batchSeed = Inputs.range([1,100], { step:1,label:"시드 (노이즈 변화)",value:42 })
바깥 미분 \(2(y-\hat{y})\) × 안쪽 미분 \((-1)\) — \(\hat{y}\) 앞에 음수 부호가 있으므로
\(w_2 \to \hat{y}\)
\(\hat{y}=w_2 h + b_2\)
\(\dfrac{\partial\hat{y}}{\partial w_2} = h\)
\(w_2\)에 곱해져 있는 것이 \(h\) (\(b_2\)는 상수라 사라짐)
\(b_2 \to \hat{y}\)
〃
\(1\)
\(b_2\)의 계수는 1
\(h \to \hat{y}\)
〃
\(w_2\)
\(h\)에 곱해져 있는 것이 \(w_2\)
\(z_1 \to h\)
\(h=\sigma(z_1)\)
\(\sigma'(z_1) = h(1-h)\)
아래 공식 참고
\(w_1 \to z_1\)
\(z_1=w_1 x + b_1\)
\(x\)
\(w_1\)의 계수는 \(x\)
\(b_1 \to z_1\)
〃
\(1\)
\(b_1\)의 계수는 1
Sigmoid의 도함수 — 공식으로 기억하자
\[\sigma'(z) = \sigma(z)\,(1 - \sigma(z))\]
유도는 이 수업 범위 밖이다(합성함수 미분 연습문제일 뿐이다). 중요한 것은 실용적 성질이다: 순전파에서 이미 계산해 둔 \(h = \sigma(z_1)\)만 있으면 도함수가 \(h(1-h)\)로 바로 나온다. Ch02의 활성화 함수 그래프에서 봤던 점선(도함수)이 바로 이 값이다.
3단계 — 역전파 (오른쪽에서 왼쪽으로). 이제 남은 일은 곱하기뿐이다. 손실에서 출발해, 목적지까지 지나가는 화살표들의 국소 미분을 차례로 곱한다:
역전파 한 번으로 손실이 감소했다. 이것이 딥러닝 학습의 한 스텝 전부이며, 실제 프레임워크(PyTorch 등)는 이 계산을 자동미분으로 대신해줄 뿐 원리는 동일하다. 이 수업에서 손으로 하는 역전파는 여기까지다 — 층이 많아지면 곱하는 항이 늘어날 뿐, 새로운 아이디어는 없다.
6.4.6 기울기 소실 — Ch02의 복선 회수
위 계산에서 \(\sigma'(z_1) = 0.2350\)이었다. Sigmoid의 도함수는 최대값이 0.25이다.
층이 10개라면? 그래디언트에 \(\sigma'\)이 10번 곱해지고, 최선의 경우에도 \(0.25^{10} \approx 0.0000010\). 앞쪽 층의 그래디언트가 사실상 0이 되어 학습이 멈춘다. 이것이 기울기 소실(Vanishing Gradient) 문제다.
Ch02에서 “ReLU가 현재 가장 많이 쓰인다”고 했던 이유가 바로 이것이다 — ReLU는 \(z > 0\)인 구간에서 도함수가 항상 1이라, 곱해도 그래디언트가 줄어들지 않는다.
6.5 일반화와 과적합
6.5.1 훈련 손실 0 = 좋은 모형?
여기 함정이 있다. 학습의 목표가 “훈련 데이터의 손실 최소화”라면, 훈련 데이터를 통째로 암기하는 모형이 최고가 된다. 손실이 0이니까.
하지만 우리가 모형을 만드는 이유는 본 적 없는 새 데이터를 예측하기 위해서다. 시험 족보를 암기한 학생과 원리를 이해한 학생의 차이 — 새로운 문제가 나왔을 때 드러난다.
일반화 (Generalization)
학습에 사용하지 않은 새로운 데이터에 대해서도 좋은 예측을 하는 능력. 딥러닝의 진짜 목표는 훈련 손실 최소화가 아니라 일반화다.
과적합과 과소적합
과적합 (Overfitting): 모형이 훈련 데이터의 노이즈까지 암기하여, 훈련 성능은 좋지만 새 데이터에서 나쁜 상태
과소적합 (Underfitting): 모형이 너무 단순하여 훈련 데이터의 패턴조차 담지 못한 상태
6.5.2 훈련/검증 데이터 분할
일반화 능력은 어떻게 측정하는가? 학습에 쓰지 않은 데이터를 남겨두고 그것으로 평가한다.
데이터
용도
비유
훈련 (Train)
파라미터 학습
교과서 연습문제
검증 (Validation)
하이퍼파라미터 선택, 과적합 감시
모의고사
테스트 (Test)
최종 성능 보고 (한 번만)
수능
핵심 규칙: 검증·테스트 데이터는 학습에 절대 사용하지 않는다. 모의고사 문제로 공부하면 모의고사 점수는 의미를 잃는다.
6.5.2.1 얼마나 나누는가
데이터 크기
관례
작음 (수백 ~ 수천 행)
훈련 60% / 검증 20% / 테스트 20%
보통 (수만 행)
훈련 80% / 검증 10% / 테스트 10%
매우 큼 (수십만 행 이상)
훈련 98% / 검증 1% / 테스트 1%
데이터가 많을수록 검증·테스트의 비율은 줄여도 된다. 중요한 것은 비율이 아니라 개수이기 때문이다 — 10,000건이면 성능을 충분히 안정적으로 잴 수 있다.
분할은 가장 먼저 한다
전처리(표준화, 결측치 대치)보다 분할이 먼저다. 순서가 바뀌면 검증 데이터의 정보가 훈련 과정에 새어 들어간다.
데이터 누수 (Data Leakage)
훈련 시점에 알 수 없어야 할 정보가 모형에 흘러 들어가는 것. 검증 성능은 좋아 보이지만 실제 배포에서 무너진다.
전체 데이터로 평균을 구해 표준화한 뒤 나누면, 그 평균에는 이미 검증 데이터의 정보가 섞여 있다.
6.5.2.2 나눌 때의 두 가지 주의
층화 추출 (Stratified Split) — 분류 문제에서는 각 분할이 원본과 같은 클래스 비율을 갖도록 나눈다. 불량률 3%인 데이터를 무작정 나누면, 검증 세트에 불량이 하나도 안 들어갈 수 있다.
시계열 데이터는 무작위로 나누지 않는다 — 반드시 과거로 학습하고 미래로 검증한다. 시간을 섞어 나누는 것은 내일 신문을 보고 오늘을 맞히는 것과 같다.
인터랙티브 — 모형 복잡도와 과적합
다항식의 차수를 조절해 보세요. 차수가 낮으면 훈련 데이터조차 못 맞추고(과소적합), 차수가 높으면 훈련 점들은 완벽히 통과하지만 검증 오차가 폭발합니다(과적합).