손실 곡면에서 내려가는 방향, 기울기와 경사하강의 직관 | DAKER 커뮤니티

모델 학습을 이해할 때 가장 자주 마주치는 질문은 단순합니다. 손실을 줄이려면 파라미터를 어디로 움직여야 할까 하는 점입니다. 이 질문에 답하는 개념이 기울기이고, 그 기울기의 반대 방향으로 한 걸음씩 이동하는 방식이 경사하강입니다.

앞선 글이 행렬이 무엇을 계산하는지에 초점을 맞췄다면, 이번 글은 그 계산 결과를 바탕으로 파라미터의 숫자를 어떻게 고쳐 가는지 살펴봅니다. 미분 기호를 최소화하고, 손실 곡면에서 내려가는 방향이라는 그림으로 학습의 핵심을 정리해 보겠습니다.

경사하강과 기울기 썸네일

손실 L은 모델 파라미터 θ의 함수입니다. θ를 조금 바꾸면 L도 조금 바뀌고, 그 변화율의 모음이 ∇L(θ)입니다. 벡터의 각 성분은 특정 가중치를 아주 조금 키웠을 때 손실이 얼마나 오르는지를 뜻합니다. 양의 성분이면 그 방향으로 갈수록 손실이 커지고, 음의 성분이면 손실이 작아집니다.

손실을 줄이려면 기울기의 반대 방향으로 이동하면 됩니다.

대회 제출물을 튜닝할 때도 결국 같은 질문으로 돌아옵니다. 지금 어떤 신호가 파라미터를 밀고 있는가 하는 점입니다.

미분은 아주 작은 변화에 대한 반응입니다

한 변수 함수 f(x)에서 미분 f′(x)는 x를 아주 조금 키웠을 때 f가 얼마나 민감하게 변하는지를 나타냅니다. 기울기가 가파르면 같은 보폭에도 함수값 변화가 크고, 평평하면 거의 변하지 않습니다. 접선의 기울기라는 익숙한 그림이 여기서도 그대로 통합니다.

다변수 함수에서는 각 축마다 이런 변화율이 생기고, 그것들을 모은 벡터가 기울기입니다. 차원이 높아져도 의미가 달라지지는 않습니다. 성분 수만 많아질 뿐입니다. 편미분 ∂L/∂θᵢ는 다른 파라미터를 고정한 채 θᵢ만 움직일 때의 변화율입니다. 모델의 파라미터가 수백만 개, 수십억 개여도 개념은 같습니다.

지금 위치에서 손실이 가장 가파르게 증가하는 방향이 기울기이고, 학습은 그 반대 방향으로 이동합니다.

실제로는 자동미분이 이 계산을 대신하지만, 개념을 알고 있으면 학습 루프를 읽을 때 훨씬 덜 추상적으로 느껴집니다. 수치미분으로 검산하는 습관도 유용합니다. 파라미터를 ε만큼 흔들어 손실 차이를 ε로 나누면 근사 기울기를 얻을 수 있고, 자동미분 결과와 크게 어긋나면 구현 버그를 의심할 수 있습니다. 작은 모델과 작은 배치에서 한 번만 확인해도 이후 디버깅 시간이 줄어듭니다.

경사하강은 반대 방향으로 한 걸음 가는 일입니다

가장 기본적인 갱신식은 θ ← θ − η · ∇L(θ)입니다. 여기서 η는 학습률로, 한 번에 얼마나 움직일지를 정하는 보폭입니다. 너무 크면 최솟값 근처에서 진동하거나 발산할 수 있고, 너무 작으면 학습이 지나치게 느려집니다.

스케줄러가 학습률을 시간에 따라 줄이는 이유도 여기에 있습니다. 초반에는 넓게 탐색하고, 후반에는 더 섬세하게 맞추기 위함입니다. 워밍업은 초반 보폭을 천천히 키워 초기 불안정에서 폭주를 줄이는 방식입니다. 코사인 스케줄이나 계단형 스케줄은 결국 이 보폭을 언제, 어떻게 줄일지에 대한 설계입니다.

전체 데이터로 기울기를 매번 계산하면 정확하지만 비용이 큽니다. 그래서 보통은 미니배치의 평균 기울기로 근사합니다. 이것이 SGD의 핵심입니다. 노이즈가 생기지만, 그 노이즈가 얕은 지역 최솟값을 빠져나오는 데 도움이 되기도 합니다. 모멘텀은 이전 걸음의 방향을 기억해 진동을 줄이고, Adam 같은 적응형 최적화는 각 파라미터마다 실효 보폭을 조절합니다. 다만 뼈대는 같습니다. 모두 기울기 정보를 이용해 손실이 줄어드는 쪽으로 이동합니다.

손실 곡면과 기울기 반대 방향 갱신을 보여주는 다이어그램

손실 곡면을 떠올리면 방향이 보입니다

파라미터를 가로축, 손실을 세로축으로 두면 언덕과 골짜기가 있는 곡면을 상상할 수 있습니다. 실제 모델은 차원이 너무 높아 그대로 그릴 수 없지만, 2차원 접시 모양만 떠올려도 충분합니다. 현재 θ에 점을 찍고 기울기 화살표를 그리면, 학습 한 스텝은 그 화살표의 반대쪽으로 점을 옮기는 일입니다. 여러 스텝이 쌓이면 점은 골짜기 바닥 근처로 미끄러집니다.

손실 곡면 비유는 정확한 지형도가 아니라, 내려갈 방향을 잡는 나침반에 가깝습니다.

안장점, 고원, 날카로운 최솟값 같은 표현은 이 곡면의 형태를 설명합니다. 고원에서는 기울기가 거의 0에 가까워 학습이 멈춘 것처럼 보일 수 있습니다. 배치 정규화, 잔차 연결, 좋은 초기화가 학습을 안정화한다는 말도 이런 지형을 덜 험하게 만드는 설계로 이해하면 더 구체적으로 읽힙니다. 손실이 계단처럼 갑자기 떨어지는 구간은 학습률, 데이터 커리큘럼, 정규화 강도가 맞물리며 지형이 달라진 결과로 해석되기도 합니다.

디버깅할 때도 결국 기울기를 봅니다

손실이 줄지 않으면 학습률, 데이터, 라벨, 손실식, 기울기 폭주를 차례로 의심하게 됩니다. 기울기 노름이 폭발하면 클리핑을 검토하는 것이 좋고, 기울기가 거의 0이라면 활성화 포화, 지나치게 깊은 경로, 잘못된 동결 여부를 점검할 필요가 있습니다. 프레임워크에서 loss.backward() 이후 param.grad가 채워지는 흐름을 직접 출력해 보면, 학습이 곧 기울기 반영이라는 점이 분명해집니다.

검증 손실은 줄지 않는데 학습 손실만 줄어든다면 과적합 신호입니다. 기울기는 학습 데이터 기준으로 내려가는 방향을 알려 줄 뿐, 일반화를 보장하지는 않습니다. 이때는 정규화, 더 많은 데이터, 더 단순한 모델, 조기 종료 같은 대응이 다음 단계가 됩니다. 또한 손실 스케일이 바뀌면 실효 학습률도 달라지므로, 손실을 재정의했다면 η도 함께 다시 보는 편이 좋습니다.

전이학습에서는 일부 층을 동결하기도 합니다. 동결된 파라미터는 갱신에 쓰이지 않거나 기울기 계산을 생략합니다. 파인튜닝 범위를 정한다는 말은 결국 어느 좌표축을 움직일지 고르는 일입니다. LoRA처럼 저랭크 행렬만 학습하는 방법도 움직일 방향을 작은 부분공간으로 제한하는 설계로 볼 수 있습니다.

학습률은 보폭이라는 감각으로 보는 것이 좋습니다

학습률 탐색은 보통 로그 스케일로 시도합니다. 1e-1, 1e-2, 1e-3, 1e-4처럼 자릿수를 바꿔 가며 짧게 돌려 보고, 손실이 부드럽게 내려가는 구간을 찾습니다. 한 에폭도 지나기 전에 손실이 NaN이 되면 보폭이 너무 큰 신호일 수 있습니다. 반대로 수십 스텝 동안 손실이 거의 평평하면 보폭이 너무 작거나, 기울기 자체가 거의 없는 상태일 수 있습니다. 다만 데이터 파이프라인 버그로 라벨이 섞여도 비슷한 증상이 나타날 수 있으므로 학습률만 원인으로 단정하지 않는 편이 좋습니다.

층마다 학습률을 다르게 주는 차등 학습률도 같은 원리입니다. 이미 잘 학습된 하위 층은 작게 움직이고, 새로 붙인 헤드는 더 크게 움직입니다. 이는 좌표축마다 보폭을 다르게 두는 것과 같습니다. 스케줄러와 함께 쓰면 시간에 따른 전역 보폭과 층별 상대 보폭이 곱해져 실제 이동량이 결정됩니다. 로그에 실효 학습률을 남겨 두면 재현에도 도움이 됩니다.

배치 크기를 키우면 기울기 추정은 덜 시끄러워집니다. 그래서 어떤 경험 법칙은 배치가 커질 때 학습률도 함께 키웁니다. 다만 과제, 정규화, 옵티마이저에 따라 예외가 많으므로 규칙보다 검증 곡선을 우선해서 보는 편이 안전합니다. 분산 학습에서는 글로벌 배치가 커질수록 이 조정이 더 중요해집니다.

손실 곡선을 읽을 때 함께 봐야 할 것들

학습 손실이 단조롭게 감소한다고 해서 곧바로 성공이라고 보기는 어렵습니다. 검증 손실과 검증 메트릭이 함께 개선되는지 봐야 합니다. 학습 손실은 내려가는데 검증이 올라가면 과적합이고, 둘 다 내려가지 않으면 과소적합, 구현 버그, 보폭 문제를 함께 의심할 수 있습니다. 초반 몇 스텝에서 손실이 랜덤 수준보다 의미 있게 내려가는지만 확인해도 라벨 연결 오류를 빨리 찾는 데 도움이 됩니다.

부드러운 이동평균으로 손실을 보면 추세가 잘 보이지만, 때로는 문제를 가릴 수도 있습니다. 특정 배치에서만 손실이 폭주한다면 데이터 이상치, 잘못된 augmentation, 수치 불안정 가능성을 살펴봐야 합니다. 기울기 노름을 같은 그래프에 올려 두면 손실 스파이크가 기울기 스파이크와 함께 나타나는지 바로 확인할 수 있습니다. 함께 튄다면 클리핑, 학습률, 혼합정밀도 설정을 먼저 점검하는 것이 좋습니다.

정리하면, 학습은 방향을 읽고 한 걸음씩 옮기는 일입니다

이 글은 헤세 행렬이나 2차 최적화, 수렴 증명을 다루는 글은 아닙니다. 학습 루프를 읽을 때 필요한 1차 직관에 집중했습니다. 또한 특정 옵티마이저의 하이퍼파라미터 튜닝 가이드나 데이터셋별 권장 학습률표를 제공하는 글도 아닙니다. 과제마다 검증 곡선을 바탕으로 판단해야 하는 부분은 그대로 남아 있습니다.

손실 곡면이 파라미터에게 내려갈 방향을 가리키고, 그 화살표의 반대가 학습의 한 걸음입니다.

다음 글에서는 분류 손실이 확률과 가능도와 어떻게 연결되는지, 교차엔트로피를 통해 이어서 살펴볼 수 있습니다.

실제로 모델을 학습시킬 때, 손실보다 먼저 기울기 로그를 확인해 본 경험이 있으신가요?