이 장에서 배울 것
손실 함수와 역전파에서는 손실 함수가 예측의 틀린 정도를 숫자로 만들고, 역전파가 각 가중치에 대한 기울기를 계산한다는 것을 배웠다. 이번 장에서는 그 기울기를 실제로 어떻게 사용할지 다룬다.
이 장의 목표는 단순하다. 모델을 잘 만드는 것만큼, 모델을 잘 학습시키는 것이 중요하다는 점을 이해하는 것이다. 같은 신경망이라도 학습률, 배치 크기, 옵티마이저, 정규화 방법에 따라 전혀 다른 결과가 나온다.
이번 장을 마치면 다음을 설명할 수 있어야 한다.
확률적 경사하강법, 미니배치, epoch, iteration, batch size의 차이
학습률이 너무 크거나 작을 때 loss curve가 어떻게 달라지는지
Momentum, RMSprop, Adam의 직관적 차이
L2 정규화, Dropout, 조기 종료, 데이터 증강, 배치 정규화의 역할
train loss와 validation loss를 보고 과적합을 판단하는 방법

왜 이 주제가 중요한가
딥러닝 모델은 한 번에 정답을 찾지 않는다. 처음에는 무작위에 가까운 가중치로 시작하고, 데이터를 여러 번 보면서 조금씩 수정한다. 이때 수정 방향은 기울기가 알려 주지만, 얼마나 크게 움직일지, 어떤 방식으로 움직일지, 언제 멈출지는 따로 정해야 한다.
이 선택이 최적화다. 최적화는 손실을 줄이는 과정이다.
하지만 손실이 줄어든다고 항상 좋은 모델이 되는 것은 아니다. 학습 데이터에서는 잘 맞지만, 처음 보는 데이터에서는 틀릴 수 있다. 이것이 과적합이다. 과적합을 줄이고 새 데이터에서도 성능을 유지하게 만드는 방법이 정규화다.
따라서 딥러닝 학습은 두 가지 질문을 동시에 다룬다.
학습 데이터의 손실을 안정적으로 줄이고 있는가?
검증 데이터에서도 성능이 유지되는가?
첫 번째 질문은 최적화의 문제이고, 두 번째 질문은 일반화의 문제다. 좋은 딥러닝 실험은 이 둘을 함께 본다.
핵심 개념 설명
경사하강법과 확률적 경사하강법
경사하강법은 손실을 줄이는 방향으로 가중치를 업데이트하는 방법이다. 기울기가 양수라면 가중치를 줄이고, 기울기가 음수라면 가중치를 늘린다. 수식으로 쓰면 다음과 같다.
새 가중치 = 현재 가중치 - 학습률 × 기울기여기서 학습률은 한 번에 얼마나 움직일지를 정하는 값이다. 기울기는 방향을 알려 주고, 학습률은 보폭을 정한다.
전체 데이터를 모두 사용해 한 번 기울기를 계산하는 방법을 배치 경사하강법이라고 한다. 데이터가 작다면 가능하지만, 이미지나 텍스트 데이터처럼 데이터가 많으면 계산이 오래 걸린다.
그래서 실제 딥러닝에서는 보통 일부 데이터만 뽑아 기울기를 계산한다. 이를 확률적 경사하강법, 줄여서 SGD라고 부른다. 엄밀히 말하면 샘플 하나씩 업데이트하는 방식이 확률적 경사하강법이고, 여러 샘플을 묶어 업데이트하는 방식은 미니배치 경사하강법이다. 하지만 실무에서는 미니배치 방식도 넓은 의미로 SGD라고 부르는 경우가 많다.
batch size, iteration, epoch
딥러닝 로그를 읽으려면 세 단어를 구분해야 한다.
batch size: 한 번에 모델에 넣는 데이터 개수
iteration: 가중치를 한 번 업데이트하는 횟수
epoch: 전체 학습 데이터를 한 번 모두 본 단위
예를 들어 학습 데이터가 60,000개이고 batch size가 128이라면, 한 epoch에는 약 469번의 iteration이 있다.
60,000 ÷ 128 ≈ 469즉 로그에 Epoch 3, Iteration 200이라고 적혀 있다면, 모델이 전체 데이터를 세 번째로 보는 중이고 그 안에서 200번째 미니배치를 처리하고 있다는 뜻이다.
배치 크기는 학습의 성격을 바꾼다. 작은 배치는 기울기가 흔들리지만 업데이트가 자주 일어난다. 큰 배치는 기울기가 안정적이지만 한 번 업데이트하는 데 계산량이 크고, 때로는 일반화 성능이 떨어질 수 있다. 초보 단계에서는 32, 64, 128 정도를 기준으로 비교해 보면 좋다.
학습률과 loss curve
학습률은 최적화에서 가장 중요한 하이퍼파라미터 중 하나다. 하이퍼파라미터는 모델이 스스로 학습하지 않고 사람이 정하는 설정값을 말한다.
학습률이 너무 크면 손실이 줄어들지 않고 튄다. 심하면 손실이 계속 커져 발산한다. 기울기가 알려 준 방향은 맞더라도 보폭이 너무 커서 최소 지점을 지나쳐 버리기 때문이다.
학습률이 너무 작으면 손실은 줄어들지만 매우 느리다. 학습 시간이 오래 걸리고, 정해진 epoch 안에 충분히 좋은 지점에 도달하지 못할 수 있다.
loss curve를 볼 때는 다음처럼 해석한다.
| 현상 | 가능한 원인 | 조치 |
|---|---|---|
| train loss가 큰 폭으로 오르내림 | 학습률이 너무 큼 | 학습률 낮추기 |
| train loss가 거의 줄지 않음 | 학습률이 너무 작거나 모델이 부적절함 | 학습률 높이기, 구조 확인 |
| train loss는 감소, validation loss는 증가 | 과적합 | 정규화, 조기 종료, 데이터 증강 |
| train loss와 validation loss가 모두 높음 | 과소적합 | 모델 용량 증가, 학습 더 진행, 특성 확인 |
loss curve는 단순한 그래프가 아니다. 모델이 학습 중에 어떤 상태인지 알려 주는 진단 도구다.
Momentum: 방향을 기억한다
기본 SGD는 현재 미니배치의 기울기만 보고 움직인다. 그런데 미니배치마다 데이터가 다르므로 기울기가 조금씩 흔들린다. 지그재그로 움직이면 학습이 느려진다.
Momentum은 이전에 움직이던 방향을 일부 기억한다. 공이 경사면을 내려갈 때 관성이 붙는 모습을 떠올리면 된다. 같은 방향으로 계속 기울기가 나오면 더 빠르게 이동하고, 반대 방향의 작은 흔들림은 어느 정도 무시한다.
직관적으로 Momentum은 이렇게 말한다.
"방금 전에도 이쪽으로 갔고, 지금도 비슷한 방향이면 조금 더 힘 있게 가자."
그래서 Momentum은 SGD보다 더 안정적이고 빠르게 수렴하는 경우가 많다.
RMSprop: 변수마다 보폭을 조절한다
모든 가중치가 같은 속도로 학습되어야 하는 것은 아니다. 어떤 가중치는 기울기가 자주 크게 변하고, 어떤 가중치는 작게 변한다. 같은 학습률을 적용하면 특정 방향으로는 너무 크게 움직이고, 다른 방향으로는 너무 느리게 움직일 수 있다.
RMSprop은 최근 기울기 제곱의 평균을 기억한다. 기울기가 자주 크게 나온 변수는 보폭을 줄이고, 기울기가 작게 나온 변수는 상대적으로 더 움직일 수 있게 한다.
직관적으로 RMSprop은 이렇게 말한다.
"자주 크게 흔들리는 변수는 조심해서 움직이고, 덜 움직인 변수는 조금 더 움직이게 하자."
이 방식은 손실 지형이 방향마다 기울기 크기가 다른 경우에 도움이 된다.
Adam: 방향 기억과 보폭 조절을 함께 쓴다
Adam은 Momentum과 RMSprop의 아이디어를 결합한 옵티마이저다. 한쪽으로는 기울기의 평균을 이용해 방향을 기억하고, 다른 한쪽으로는 기울기 제곱의 평균을 이용해 변수별 보폭을 조절한다.
그래서 Adam은 많은 딥러닝 문제에서 기본 선택지로 자주 쓰인다. 특히 처음 실험을 시작할 때 Adam으로 기준 성능을 만든 뒤, 필요하면 SGD with Momentum이나 AdamW 등을 비교하는 방식이 좋다.
하지만 Adam이 항상 최고라는 뜻은 아니다. 데이터, 모델, 학습률, 정규화 설정에 따라 SGD 계열이 더 좋은 일반화 성능을 보일 때도 있다. 중요한 것은 옵티마이저 이름을 외우는 것이 아니라, 학습 로그를 보고 적절히 조정하는 능력이다.
정규화: 잘 외우는 모델보다 잘 일반화하는 모델
모델이 학습 데이터를 지나치게 외우면 train loss는 계속 낮아지지만 validation loss는 올라간다. 이때 모델은 학습 데이터의 본질적인 패턴뿐 아니라 우연한 잡음까지 기억하고 있다.
정규화는 이런 과적합을 줄이는 방법이다. 정규화는 모델을 일부러 조금 제한하거나, 학습을 어렵게 만들거나, 더 다양한 데이터를 보게 해서 보지 못한 데이터에도 잘 맞도록 돕는다.
L2 정규화와 weight decay
L2 정규화는 큰 가중치에 벌점을 주는 방법이다. 손실 함수에 가중치 크기에 대한 항을 추가해서, 모델이 필요 이상으로 큰 가중치를 갖지 않게 만든다.
큰 가중치는 입력의 작은 변화에도 출력을 크게 바꿀 수 있다. 반대로 가중치가 지나치게 커지지 않으면 결정 경계가 더 부드러워지는 경향이 있다.
PyTorch에서는 보통 옵티마이저의 weight_decay 값으로 설정한다.
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3, weight_decay=1e-4)초보 실험에서는 0, 1e-5, 1e-4, 1e-3 정도를 비교해 보면 효과를 관찰하기 쉽다.
Dropout
Dropout은 학습 중 일부 뉴런의 출력을 무작위로 0으로 만드는 방법이다. 매번 일부 뉴런이 빠진 상태로 학습되므로, 모델은 특정 뉴런 몇 개에만 의존하기 어려워진다.
비유하자면 팀 프로젝트에서 매번 일부 팀원이 빠진 채 발표 연습을 하는 것과 비슷하다. 특정 한 사람만 모든 내용을 알고 있으면 팀은 불안정하다. 모두가 조금씩 역할을 나누면 더 튼튼한 팀이 된다.
Dropout은 학습할 때만 적용하고, 평가할 때는 꺼야 한다. PyTorch에서는 model.train()과 model.eval()이 이 차이를 관리한다. 이 부분은 PyTorch 학습 루프에서 다시 다룬다.
조기 종료
조기 종료는 validation loss가 더 이상 좋아지지 않으면 학습을 멈추는 방법이다. epoch을 많이 돌린다고 항상 좋은 것은 아니다. 어느 순간부터 모델은 일반 패턴을 배우기보다 학습 데이터를 외우기 시작할 수 있다.
조기 종료에서는 보통 patience라는 값을 둔다. 예를 들어 patience가 5라면, validation loss가 5epoch 동안 개선되지 않을 때 학습을 멈춘다.
중요한 점은 마지막 epoch의 모델이 아니라, validation loss가 가장 좋았던 시점의 모델을 저장해야 한다는 것이다.
데이터 증강
데이터 증강은 학습 데이터를 인위적으로 다양하게 만드는 방법이다. 이미지에서는 회전, 좌우 이동, 자르기, 색상 변화 등을 사용할 수 있다. 텍스트에서는 단어 일부를 바꾸거나 문장을 약간 변형하는 방법이 있지만, 의미가 깨질 수 있으므로 더 조심해야 한다.
데이터 증강의 핵심은 정답을 바꾸지 않는 범위에서 입력을 다양하게 만드는 것이다. 숫자 이미지가 조금 이동해도 여전히 같은 숫자라면 좋은 증강이다. 그러나 6을 뒤집어 9처럼 보이게 만들면 잘못된 증강이 될 수 있다.
배치 정규화
배치 정규화는 각 층의 입력 분포가 지나치게 흔들리지 않도록 조정하는 방법이다. 여기서 정규화라는 말은 과적합 방지뿐 아니라 학습 안정화의 의미도 갖는다.
신경망에서는 앞 층의 가중치가 바뀌면 뒤 층이 받는 입력의 분포도 계속 바뀐다. 그러면 뒤 층은 매번 달라지는 환경에서 학습해야 한다. 배치 정규화는 미니배치 단위로 평균과 분산을 이용해 값을 조정하고, 학습 가능한 스케일과 이동 값을 적용한다.
그 결과 더 큰 학습률을 사용할 수 있거나, 학습이 안정되는 경우가 많다. 다만 배치 크기가 너무 작으면 배치 통계가 불안정해질 수 있다.
쉬운 비유 또는 사례
산을 내려가는 사람을 떠올려 보자. 목표는 가장 낮은 지점에 도착하는 것이다.
기울기는 어느 방향으로 내려가야 하는지 알려 준다. 학습률은 한 걸음의 크기다. 배치 크기는 길을 판단할 때 몇 사람의 의견을 들을지와 비슷하다. 한 사람의 말만 들으면 빠르지만 흔들릴 수 있고, 많은 사람의 의견을 들으면 안정적이지만 느리다.
Momentum은 이전에 내려가던 방향을 기억하는 것이다. RMSprop은 미끄러운 길과 험한 길에서 보폭을 다르게 조절하는 것이다. Adam은 방향 기억과 보폭 조절을 함께 사용하는 방식이다.
정규화는 산을 내려가는 사람이 지름길처럼 보이는 위험한 길에 과하게 적응하지 않도록 하는 장치다. 학습 데이터에서만 통하는 요령을 익히지 말고, 새로운 길에서도 안정적으로 내려가게 만드는 훈련이다.
직접 해보는 실습
이번 실습의 목적은 최고 성능을 내는 것이 아니다. 설정을 바꾸면 학습 곡선이 어떻게 달라지는지 관찰하는 것이다.
실습 목표
같은 MLP 모델에 대해 다음 설정을 바꿔 본다.
learning rate:
1e-1,1e-2,1e-3,1e-4batch size:
32,128,512dropout:
0.0,0.3,0.5weight decay:
0,1e-4,1e-3optimizer:
SGD,SGD + Momentum,Adam
데이터는 MNIST처럼 작은 이미지 분류 데이터나, 앞 장에서 사용한 간단한 표 형태 데이터를 사용해도 된다. 중요한 것은 train set과 validation set을 나누는 것이다.
기록해야 할 값
각 epoch마다 다음 값을 기록한다.
epoch
train loss
validation loss
train accuracy
validation accuracy
learning rate
batch size
optimizer
dropout
weight decay실험 결과는 표로 정리한다.
| 실험 | lr | batch size | optimizer | dropout | weight decay | 관찰 |
|---|---|---|---|---|---|---|
| A | 1e-1 | 128 | SGD | 0.0 | 0 | loss가 크게 흔들림 |
| B | 1e-3 | 128 | Adam | 0.0 | 0 | 안정적으로 감소 |
| C | 1e-3 | 128 | Adam | 0.5 | 1e-4 | train loss는 높지만 validation이 개선될 수 있음 |
실험 해석 질문
그래프를 그린 뒤 다음 질문에 답한다.
train loss가 가장 빠르게 줄어든 설정은 무엇인가?
validation loss가 가장 낮았던 설정은 무엇인가?
train loss와 validation loss의 차이가 가장 컸던 설정은 무엇인가?
학습률이 너무 큰 실험에서는 어떤 현상이 보였는가?
dropout이나 weight decay를 넣었을 때 train loss는 어떻게 변했는가?
validation 성능은 좋아졌는가, 나빠졌는가?
여기서 중요한 판단은 "train loss가 낮다"가 아니다. 최종 목표는 처음 보는 데이터에 잘 맞는 모델이다. 따라서 validation loss와 validation accuracy를 함께 봐야 한다.
흔한 실수와 오류 분석
train loss만 보고 결론 내린다
초보자는 train loss가 낮으면 좋은 모델이라고 생각하기 쉽다. 하지만 train loss만 낮고 validation loss가 높다면 모델은 학습 데이터를 외운 것이다. 보고서에는 반드시 train과 validation을 함께 기록해야 한다.
학습률을 한 번에 크게 바꾼다
학습률은 보통 10배 단위로 탐색한다. 예를 들어 1e-1, 1e-2, 1e-3, 1e-4를 비교한다. 0.001에서 0.0011로 바꾸는 것은 초반 탐색에서는 큰 의미가 없다. 먼저 대략적인 범위를 찾고, 그다음 세밀하게 조정한다.
dropout을 무조건 많이 넣는다
Dropout은 과적합을 줄일 수 있지만, 너무 강하면 모델이 충분히 배우지 못한다. dropout 비율이 높아질수록 학습은 어려워진다. train loss와 validation loss가 모두 높다면 dropout이 과한지 확인해야 한다.
weight decay와 학습률을 따로 보지 않는다
weight decay가 커지면 가중치를 작게 유지하려는 힘이 강해진다. 이 설정은 학습률과 함께 작동한다. 학습률은 큰데 weight decay도 크면 학습이 불안정하거나 성능이 떨어질 수 있다. 하나의 설정만 바꾸며 비교하는 습관이 필요하다.
검증 데이터를 학습에 사용한다
validation set은 모델 선택을 위한 데이터다. 이 데이터를 학습에 섞으면 검증 성능을 믿을 수 없다. 데이터 분리는 실험의 기본이다. 최종 평가용 test set이 있다면, 모든 설정을 결정한 뒤 마지막에 한 번만 사용한다.
model.train()과 model.eval()을 혼동한다
Dropout과 배치 정규화는 학습 모드와 평가 모드에서 다르게 동작한다. 평가할 때 model.eval()을 호출하지 않으면 validation 결과가 흔들릴 수 있다. 반대로 학습할 때 model.train()을 호출하지 않으면 Dropout이 적용되지 않는다.
요약
최적화는 손실을 줄이는 과정이다. 기울기는 방향을 알려 주고, 학습률은 이동 크기를 정한다. 미니배치는 전체 데이터 대신 일부 데이터를 사용해 자주 업데이트하는 방식이며, batch size, iteration, epoch은 학습 로그를 해석하는 기본 단위다.
SGD는 단순하지만 흔들릴 수 있다. Momentum은 이전 방향을 기억해 흔들림을 줄인다. RMSprop은 변수마다 보폭을 조절한다. Adam은 이 두 아이디어를 함께 사용한다.
정규화는 모델이 학습 데이터를 지나치게 외우지 않도록 돕는다. L2 정규화는 큰 가중치를 억제하고, Dropout은 특정 뉴런 의존을 줄인다. 조기 종료는 validation 성능이 나빠지기 전에 멈춘다. 데이터 증강은 다양한 입력을 만들어 일반화를 돕고, 배치 정규화는 학습을 안정화한다.
좋은 실험은 단순히 정확도 하나만 보지 않는다. train loss, validation loss, 학습률, 배치 크기, 옵티마이저, 정규화 설정을 함께 기록하고 해석한다.
퀴즈
batch size가 100이고 학습 데이터가 10,000개라면 한 epoch에는 몇 iteration이 있는가?
학습률이 너무 클 때 loss curve는 보통 어떤 모습을 보이는가?
Momentum은 어떤 정보를 기억하는가?
RMSprop이 변수마다 보폭을 다르게 조절하는 이유는 무엇인가?
Adam은 어떤 두 가지 아이디어를 결합한 옵티마이저인가?
train loss는 계속 줄어드는데 validation loss가 증가한다면 어떤 문제가 의심되는가?
Dropout은 학습 시점과 평가 시점에서 어떻게 다르게 동작해야 하는가?
조기 종료에서 가장 좋은 모델은 마지막 epoch의 모델인가, validation loss가 가장 낮았던 모델인가?
체크리스트
epoch, iteration, batch size의 차이를 설명할 수 있다.
학습 로그에서 한 epoch의 iteration 수를 계산할 수 있다.
학습률이 너무 클 때와 너무 작을 때의 loss curve를 구분할 수 있다.
SGD, Momentum, RMSprop, Adam의 직관적 차이를 설명할 수 있다.
train loss와 validation loss를 함께 보고 과적합을 판단할 수 있다.
L2 정규화, Dropout, 조기 종료, 데이터 증강, 배치 정규화의 역할을 설명할 수 있다.
같은 모델에서 학습률, 배치 크기, dropout, weight decay를 바꿔 실험할 수 있다.
실험 결과를 표와 그래프로 정리하고 해석할 수 있다.
다음 장 연결
이번 장에서는 기울기를 이용해 가중치를 업데이트하는 방법과, 모델이 학습 데이터를 외우지 않게 만드는 방법을 배웠다. 이제 필요한 것은 이 과정을 코드로 정확히 구현하는 일이다.
다음 장에서는 PyTorch로 학습 루프를 직접 만든다. 순전파, 손실 계산, backward(), 옵티마이저 업데이트, gradient 초기화, train/eval 모드 전환을 하나의 흐름으로 연결한다. 이번 장에서 배운 학습률, 옵티마이저, 정규화 설정이 실제 코드에서 어디에 들어가는지 확인하게 될 것이다.
이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.