경사 하강법의 두 가지 문제
지금까지 경사 하강법으로 파라미터를 업데이트하는 방법을 배웠습니다. 그런데 실제로 써보면 두 가지 골치 아픈 문제가 생겨요. 하나는 미니배치에서 생기는 그래디언트 잡음 문제고, 다른 하나는 오버슈팅 문제입니다.
그래디언트 잡음부터 얘기하면, 전체 데이터가 아닌 일부 샘플만 가지고 그래디언트를 추정하다 보니까 그 그래디언트에 잡음이 낄 수밖에 없어요. 잡음이 끼면 어떤 일이 생기냐 하면, 원래는 직진으로 쭉 가야 되는데 들쭉날쭉하게 업데이트가 되어서 수렴 속도가 매우 느려집니다.
오버슈팅은 loss landscape 모양 때문에 생겨요. loss landscape가 동그란 게 아니라 타원형으로 찌그러져 있으면 한 방향으로는 기울기가 굉장히 크고 다른 방향으로는 기울기가 작습니다. 결과적으로 우리가 원하는 방향과 정반대로 그래디언트가 팍 튀는 현상이 발생해요. 타원이 길쭉하면 길쭉할수록 오버슈팅이 더 심해집니다.
이 두 가지 문제를 해결하기 위해 나온 것이 모멘텀과 적응적 학습률입니다.
모멘텀
기본 아이디어
모멘텀은 쉽게 말하면 부스터를 쓰는 거예요. 바람이 세서 왼쪽으로 갔다 오른쪽으로 갔다 갈팡질팡할 때 부스터를 딱 켜면 그 바람을 극복하고 원하는 방향으로 쭉 갈 수 있는 것처럼, 모멘텀은 과거의 그래디언트를 이용해서 현재 노이즈를 극복하고 앞으로 더 밀어주는 역할을 합니다.
수식으로 보면 이렇습니다. v라는 속도 벡터를 따로 관리해요.
v ← αv - ρ∇J(θ)
θ ← θ + v
v는 과거 그래디언트를 누적한 속도 벡터이고, α는 0에서 1 사이의 할인율(discount factor)입니다. α가 0이면 과거 그래디언트를 완전히 무시하는 거니까 일반 SGD랑 똑같이 동작해요. α가 1에 가까울수록 과거 그래디언트를 손실 없이 반영합니다. 보통은 0.5에서 0.9 정도를 씁니다.
모멘텀을 쓰면 세 가지 긍정적인 효과가 있어요. 첫째, 그래디언트 스무딩 효과입니다. 과거 그래디언트를 반영하기 때문에 궤적이 더 부드러워져요. 둘째, 오버슈팅 완화입니다. 꺾이는 각도가 완만해지면서 오버슈팅이 누그러집니다. 셋째, 로컬 미니멈 탈출입니다. 로컬 미니멈에서 그래디언트가 0이 되어도, 속도 벡터 v에 누적된 에너지가 남아 있어서 그걸 받아 탈출할 수 있어요.
네스테로프 모멘텀
모멘텀에서 한 발 더 나아간 것이 네스테로프 모멘텀입니다. 아이디어는 이렇습니다. 현재 위치에서 그래디언트를 구하는 게 아니라, 과거의 v 벡터로 먼저 한 번 업데이트해서 예견된 위치로 이동한 뒤 거기서 그래디언트를 구해요.
축구의 스루패스랑 똑같은 거예요. 상대 선수가 막고 있을 때 공을 바로 주는 게 아니라 동료 선수가 달려갈 미래 위치에 미리 패스하는 거죠. 예견된 곳에서 그래디언트를 구하기 때문에 궤적이 훨씬 더 스무스해지고, 좋은 로컬 미니멈으로 향하는 더 짧은 경로를 만들어냅니다.

적응적 학습률
필요성
오버슈팅 문제를 다른 각도에서 보면 이렇습니다. 각 파라미터마다 loss에 기여하는 민감도가 달라요. 어떤 가중치는 조금만 바꿔도 loss가 크게 달라지고, 어떤 가중치는 많이 바꿔도 별 영향이 없습니다. 그런데 학습률은 모든 가중치에 똑같이 적용되죠. 그래서 문제가 생기는 겁니다.
적응적 학습률은 각 가중치마다 개별 학습률을 부여하는 방식이에요. 그래디언트가 크면 학습률을 작게 만들고, 그래디언트가 작으면 크게 만들어서 모든 그래디언트가 비슷한 크기가 되도록 만드는 거죠. 결과적으로 찌그러진 loss landscape를 동그랗게 펴주는 효과를 냅니다.
Adagrad

Adagrad는 r이라는 벡터를 추가로 관리합니다. 매 iteration마다 현재 그래디언트를 제곱해서 r에 누적해요.
r ← r + g ⊙ g (원소별 제곱을 누적)
θ ← θ - (ρ / (√r + ε)) ⊙ g
r이 크면(= 그래디언트가 크면) 학습률이 작아지고, r이 작으면(= 그래디언트가 작으면) 학습률이 커져서 모든 그래디언트의 크기가 1에 가깝게 됩니다. ε은 분모가 0이 되는 것을 막기 위한 아주 작은 값이에요.
그런데 Adagrad는 치명적인 문제가 있어요. r이 단조롭게 계속 커지기만 한다는 겁니다. 제곱값이 계속 더해지니까요. 결국 학습이 진행될수록 r이 너무 커져서 그래디언트가 거의 0에 수렴해 버리는 학습 정체 현상이 생깁니다.
RMSProp
이 문제를 해결한 것이 RMSProp입니다. r을 단순 누적하는 게 아니라 지수 이동 평균으로 관리해요.
r ← αr + (1-α)(g ⊙ g)
α가 0에서 1 사이의 값이니까 두 항의 합이 항상 1이 되는 가중 평균입니다. 과거의 r에 할인율을 먹였기 때문에 r이 무한정 커지는 문제가 해결됩니다.
Adam - 모멘텀 + 적응적 학습률
Adam은 이름 그대로 Adaptive momentum의 줄임말로, 적응적 학습률과 모멘텀을 그냥 합친 겁니다. 모멘텀을 대표하는 v 벡터와 적응적 학습률을 대표하는 r 벡터를 함께 관리해요.

v ← α₁v + (1-α₁)g (모멘텀 항)
r ← α₂r + (1-α₂)(g ⊙ g) (적응적 학습률 항)
v̂ = v / (1 - α₁ᵗ) (바이어스 보정)
r̂ = r / (1 - α₂ᵗ)
θ ← θ - ρ × v̂ / (√r̂ + ε)
여기서 v̂와 r̂을 만드는 바이어스 보정 항이 눈에 띄죠. 학습 초반에 v와 r이 0으로 초기화된 상태라 모멘텀과 적응적 학습률 효과를 거의 못 누리는 전이 상태(transition state) 문제가 있어요. 컴퓨터를 켰을 때 바이오스 로딩하고 OS 올리고 하는 과정처럼요. 이 바이어스 보정이 초반에 v와 r을 인위적으로 뻥튀기해서 그 전이 상태를 최소화하는 역할을 합니다.
실제 실험에서 Adam이 가장 빠르게 로컬 미니멈으로 수렴하고, 그 뒤를 네스테로프 모멘텀, RMSProp 순서로 따라갑니다.
활성함수의 진화
활성함수도 시대별로 계속 발전해 왔습니다. 핵심 목표는 하나였어요. 미분 가능하면서 그래디언트 소멸 문제를 막아라.
계단 함수는 전 구간에서 그래디언트가 0이라 아예 쓸 수 없었고, 시그모이드와 tanh는 양 극단에서 그래디언트가 0에 가까워져 깊은 레이어에선 그래디언트 소멸 문제를 심각하게 일으켰습니다. 그래서 나온 게 ReLU예요. 양수면 그대로 통과하고 음수면 0으로 만드는 함수로, 그래디언트 소멸 문제를 어느 정도 해결했습니다.
ReLU 이후에도 변형들이 나왔어요. Softplus는 ReLU의 미분 불가능한 꼴을 부드럽게 만든 버전인데, 계산 복잡도가 더 높은 데 비해 성능 차이는 없어서 그냥 ReLU를 씁니다.
Leaky ReLU는 철학이 이렇습니다. 음수 특징에도 중요한 정보가 있을 수 있는데, 음수를 전부 0으로 날려버리면 정보 손실이 너무 크지 않겠냐는 거예요. 그래서 음수 구간에도 0.01이나 0.1 정도의 작은 기울기를 줘서 약간의 신호가 누수(leaky)되도록 만든 거죠.
PReLU는 여기서 한 발 더 나아가, 그 음수 구간의 기울기 α를 사람이 정하지 않고 학습으로 결정합니다. 레이어마다 가장 적합한 α를 스스로 찾아내요.
배치 정규화
공변량 시프트 문제
학습이 진행되면서 가중치가 업데이트되면, 각 레이어에 입력되는 데이터의 분포가 계속 달라집니다. 처음엔 평균이 0인 분포가 들어갔는데, 학습이 진행되면 평균이 1이 됐다가 10이 됐다가 100이 됐다가 점점 더 치우치는 거예요. 이 현상을 공변량 시프트(covariate shift)라고 합니다.
레이어가 깊어질수록 이 현상이 더 심각해지고, 레이어 안에 엄청나게 크거나 작은 값들이 넘쳐나게 되면 학습이 굉장히 불안정해집니다. 심한 경우엔 학습 자체가 중단되기도 해요.
배치 정규화가 이 문제를 해결하기 위해 나왔습니다. 방법은 단순합니다. 각 레이어마다 평균을 빼고 표준편차로 나눠서 분포를 매번 표준 정규분포로 되돌리는 거예요.
μ_B = (1/m) Σ xᵢ (미니배치 평균)
σ²_B = (1/m) Σ (xᵢ - μ_B)² (미니배치 분산)
x̂ = (x - μ_B) / √(σ²_B + ε) (정규화)
전체 훈련 집합에 대한 평균과 분산을 구하면 가장 좋겠지만, 파라미터가 업데이트될 때마다 전체를 다시 계산하는 건 비용이 너무 큽니다. 그래서 미니배치에 한정해서 평균과 분산을 구합니다.
정규화 후의 선형 변환
그런데 배치 정규화는 여기서 끝이 아닙니다. 평균 0, 분산 1이 모든 레이어에 최적인 분포는 아닐 수 있어요. 어떤 레이어는 평균이 1이고 분산이 2일 때 loss가 더 낮을 수도 있거든요. 그래서 정규화한 뒤에 선형 변환을 하나 더 수행합니다.
y = γx̂ + β
γ는 표준편차를 결정하고 β는 평균을 결정하는 파라미터예요. 이 둘은 학습을 통해 결정됩니다. 각 레이어마다 최적의 분포를 데이터가 스스로 찾아내는 거죠.
CNN에서는 Convolution Layer → Batch Normalization → ReLU의 세 단계가 하나의 기본 블록으로 묶여서 사용됩니다. Convolution 다음에는 항상 Batch Normalization이 따라오고, 그다음에 ReLU가 오는 세트로요.
배치 정규화가 가져다준 혜택은 굉장히 많습니다. 가중치 초기화에 덜 민감해지고, 학습률을 크게 해도 수렴이 빠르며, 심지어 시그모이드 활성함수를 써도 그래디언트 소멸이 어느 정도 해소됩니다. 규제 효과도 있어서 Dropout 없이도 높은 성능을 낼 수 있게 됐어요.
다양한 정규화 방법
배치 크기가 1이거나 매우 작은 경우에는 미니배치에 대한 평균과 분산이 불안정합니다. 이런 상황을 위해 다른 정규화 방법들도 개발됐어요.
Layer Normalization은 하나의 샘플에 대해 모든 채널 전체를 기준으로 정규화합니다. Instance Normalization은 하나의 샘플에서 각 채널마다 정규화하는데, 채널 하나당 값의 개수가 적어서 평균과 분산이 흔들리는 문제가 있어요. Group Normalization은 그 절충안으로, 채널을 몇 개 그룹으로 묶어서 그룹별로 정규화합니다. 지금도 레이어마다 무조건 정규화는 수행하고 있고, 상황에 따라 적절한 방법을 선택합니다.
규제 (Regularization)
왜 필요한가
딥러닝 모델은 어마어마하게 많은 파라미터를 가지고 있습니다. VGG만 해도 분류층에만 1억 2100만 개의 파라미터가 있어요. 이 모델은 규제가 없으면 훈련 집합을 그냥 통째로 암기해버립니다. 훈련 집합 오류는 0에 가깝게 줄어들지만 처음 보는 데이터에서는 성능이 뚝 떨어지는 과잉적합(overfitting)이 일어나는 거죠.
현대 기계학습의 전략은 이렇습니다. 모델 크기를 이리저리 바꿔가며 최적 용량을 찾는 게 아니라, 일단 큰 모델을 만들고 규제를 걸어서 알아서 적절한 용량으로 제한되도록 만드는 거예요.
규제는 크게 두 가지가 있습니다. 명시적 규제는 가중치 감소나 네트워크 구조 수정처럼 직접적으로 규제를 가하는 방식입니다. 암시적 규제는 직접적으로 규제하지 않아도 결과적으로 규제 효과를 내는 방법들, 예를 들어 조기 멈춤이나 데이터 확대가 여기에 해당해요. 현재 딥 뉴럴 네트워크는 사용 가능한 규제 방식을 총동원해서 일반화 성능을 최대화하고 있습니다.
매끄러운 과정 가정
대부분의 규제 기법은 자연 상태의 입출력 관계는 매끄럽다는 가정에 기반합니다. 뾰족뾰족하고 들쭉날쭉한 함수는 자연계에 잘 존재하지 않는다는 거예요. 함수가 뾰족할수록 앞에 붙는 가중치의 절댓값이 커지고, 반대로 가중치를 0에 가깝게 만들면 함수가 부드러워집니다. 이게 가중치 감소(weight decay)의 핵심 아이디어입니다.
L2 규제 - 리지 회귀
목적함수에 L2 노름 항을 추가합니다.
J(θ) = 원래 목적함수(x, y; θ) + λ ||θ||²
이 규제항을 미분하면 그래디언트에 2λθ가 추가로 붙습니다. 업데이트 식을 정리하면 이렇게 됩니다.
θ ← (1 - 2ρλ)θ - ρ∇J
원래 θ에 그대로 그래디언트를 빼는 게 아니라, 먼저 θ를 (1 - 2ρλ)배로 수축시키고 그다음 그래디언트만큼 빼는 거예요. 학습률이 0.01이고 λ가 2라면 (1 - 2×0.01×2) = 0.96, 즉 매 업데이트마다 θ를 96%만 보존하는 셈입니다. 야금야금 4%씩 원점으로 당기는 거죠.
중요한 특징은 θ 값이 크면 클수록 더 강하게 당긴다는 겁니다. θ가 1000이었으면 한 번에 40이 깎이고, θ가 1이었으면 0.04만 깎이는 거예요. 모난 돌이 정 맞는다고, 큰 가중치일수록 더 강하게 패는 거죠.
L1 규제 - 라소 회귀
L1 노름을 쓰면 업데이트 식에 λ×sign(θ)가 추가됩니다.
θ ← θ - ρ∇J - ρλ·sign(θ)
L2 노름과의 가장 큰 차이는 항상 일정한 값으로 원점을 향해 당긴다는 점입니다. L2는 θ 값에 비례해서 당기지만, L1은 θ가 얼마나 크든 상관없이 ρλ만큼 당겨요.
이렇게 되면 원점 근처에서 L2는 당기는 힘이 아주 작아져 0에 도달하지 못하는 반면, L1은 일정한 힘으로 계속 당기기 때문에 θ가 정확히 0이 될 확률이 훨씬 높습니다. 이를 희소성(sparsity) 효과라고 해요.
기하학적으로 보는 L1 vs L2

베타1, 베타2라는 두 파라미터가 있고 L1 규제를 건다는 말은, |β1| + |β2| ≤ 1이라는 마름모꼴 제약 영역 안에서 해를 구한다는 의미입니다. L2 규제는 β1² + β2² ≤ 1이라는 원형 제약 영역입니다.
loss landscape는 어딘가를 중심으로 동심원처럼 펼쳐져 있는데, 이 동심원과 제약 영역이 만나는 점이 최종 해가 됩니다. 마름모꼴에는 꼭짓점이 있어서 그 꼭짓점에서 만날 확률이 높아요. 꼭짓점이 바로 β1 = 0 또는 β2 = 0인 지점이니까, L1 규제를 쓰면 가중치가 0이 되는 경우가 많이 생기는 겁니다.
0이 된 가중치는 입력 특징을 아예 무시하는 거예요. MBTI 데이터를 넣고 악력을 예측하는 모델을 학습했더니, MBTI에 해당하는 가중치가 0이 됐다면 학습이 스스로 MBTI는 악력과 무관하다고 판단한 겁니다. 이걸 특징 선택(feature selection) 효과라고 해요.
암시적 규제
조기 멈춤
조기 멈춤은 구현이 매우 쉽습니다. 학습을 진행하면서 검증 집합 오류율을 계속 모니터링하다가, 오류율이 더 이상 감소하지 않고 증가하기 시작하면 그때 학습을 종료하는 거예요. 오버피팅이 시작되는 시점 직전에 딱 멈추는 겁니다.

이론적으로는 단순하지만 현실에서 그대로 적용하면 문제가 생깁니다. 미니배치의 노이즈 때문에 검증 집합 오류율이 오르락내리락 하는 거예요. 조금 올랐다고 바로 종료해버리면 설익은 수렴이 됩니다.
그래서 두 가지 인자를 추가합니다. 참을성(patience) 인자 P는 검증 오류가 증가해도 P번까지 참고 기다리겠다는 겁니다. 세대 반복 인자 Q는 매 iteration마다 체크하는 게 아니라 Q 간격마다 한 번씩 체크하겠다는 거예요. P와 Q를 크게 하면 학습을 더 오래 진행하고, 작게 하면 빠르게 조기 종료합니다. GPU가 빵빵하고 시간이 넉넉하다면 P를 늘려서 더 좋은 미니멈을 찾도록 하면 됩니다.
데이터 확대
과잉적합을 막는 가장 확실한 방법은 훈련 데이터를 많이 확보하는 겁니다. 데이터가 무한히 많으면 규제고 뭐고 다 필요 없어요. 그냥 돌리면 모델이 커질수록 성능이 계속 올라가요.
하지만 현실에서는 데이터를 많이 모으기 어려운 경우가 많습니다. 그래서 자연상에서 발생할 수 있는 변형을 프로그램으로 흉내 내서 인위적으로 데이터를 늘리는 거예요.
가장 기본적인 방법은 어파인 변환입니다. 하나의 샘플을 이동, 회전, 크기 변환해서 거의 무한하게 새 샘플을 만들어냅니다. 다만 6을 180도 회전하면 9처럼 보이는데 레이블은 그대로 6이 되는 것처럼, 레이블이 바뀌어버리는 경우가 생길 수 있으니 주의해야 해요.
AlexNet에서는 256×256 이미지를 224×224로 랜덤 크로핑하고 좌우 반전까지 해서 1장에서 2,048장을 만들었습니다. 예측 단계에서도 한 장을 5가지 위치로 크로핑하고 반전까지 해서 10장을 만들어 모두 통과시킨 뒤 출력을 평균 냈어요. 서로 조금씩 다른 영역에 집중한 결과들을 앙상블하는 효과를 얻은 겁니다.
한 가지 재미있는 발견이 있어요. 자연상에서 절대 발생하지 않는 이상한 방식으로 증강해도, 오히려 일반화 성능이 올라간다는 거예요. 노이즈를 추가하는 방식이 그 예입니다. 각 픽셀을 확률적으로 0으로 만들거나(pixel dropout), 아예 특정 구간 전체를 0으로 블랙아웃(coarse dropout)하는 방식이죠. 자연상에 이런 이미지는 없지만, 넣어주면 네트워크의 일반화 성능이 올라갑니다.
그 이유는 이렇습니다. 노이즈를 추가하면 학습 샘플이 원래 점 주변에 가우시안 분포로 퍼지는 효과가 생겨요. 그 퍼진 샘플들을 피팅하려면 뾰족뾰족한 과적합 곡선이 아닌 더 부드러운 곡선을 만들 수밖에 없어서 일반화 성능이 높아지는 거죠.
연구실에서 발표한 Saliency Mix 논문도 이 맥락에 있어요. 기존의 두 이미지를 합치는 방식(CutMix)은 배경 영역을 뜯어다 붙여서 의미 없는 부분에 레이블을 할당하는 문제가 있었어요. 그래서 사람이 공통적으로 집중하는 중요 영역(saliency)을 계산한 다음, 중요한 영역을 덜 중요한 영역에 붙여 넣는 방식으로 의미 있는 증강을 수행했습니다. 오류율이 거의 절반으로 떨어지는 결과를 얻었어요.
하이퍼파라미터 최적화
내부 매개변수와 하이퍼파라미터
학습 모델의 매개변수는 두 종류가 있어요. 내부 매개변수(θ)는 가중치로, 학습 과정에서 자동으로 업데이트됩니다. 하이퍼파라미터는 학습률, 가중치 감소 λ, 레이어 개수, 필터 개수, 컨볼루션 크기처럼 학습 전에 사람이 미리 결정해야 하는 값들이에요.
하이퍼파라미터 최적화는 내부 매개변수 최적화보다 훨씬 어렵습니다. 하이퍼파라미터 하나를 바꾸면 전체를 처음부터 재학습해야 하니까 비용이 너무 커요. 게다가 미분도 안 돼서 그래디언트 기반으로 찾을 수도 없습니다. 그래서 보통은 기존 문헌이 제시하는 기본값을 사용하거나, 후보 범위를 정해두고 몇 번 탐색해보는 방식을 씁니다.
격자 탐색 vs 임의 탐색
탐색하는 방식은 두 가지입니다. 격자 탐색은 각 하이퍼파라미터 값을 등간격으로 설정해서 모든 조합을 탐색하는 방법이고, 임의 탐색은 각 값을 지정 범위에서 랜덤하게 뽑아서 탐색하는 방법이에요.

이게 비직관적이지만, 실제로는 임의 탐색이 격자 탐색보다 훨씬 유리합니다. 이유가 있어요.
예를 들어 학습률은 성능에 굉장히 큰 영향을 주는 반면, 모멘텀 값은 0.6을 쓰든 0.7을 쓰든 성능에 별 차이가 없습니다. 격자 탐색을 하면 모멘텀처럼 별로 중요하지 않은 파라미터에 대해서도 같은 개수의 탐색 포인트를 쓰게 되어서, 정작 중요한 학습률에 대해 탐색하는 값의 수가 너무 적어집니다.
반면 임의 탐색은 학습률 관점에서 봤을 때 훨씬 다양한 값을 탐색하게 되어서 최적점을 찾을 확률이 높아요. 탐색 횟수가 굉장히 적은 극단적인 경우엔 격자 탐색이 유리할 수도 있지만, 일반적인 상황에서는 임의 탐색이 압도적으로 유리합니다.
로그 스케일을 쓰면 탐색 범위가 0에서 1000처럼 매우 넓을 때, 0에서 10 구간을 더 촘촘하게 탐색할 수 있어요.
'학교공부 > 딥러닝' 카테고리의 다른 글
| [딥러닝] 다층 퍼셉트론 (0) | 2026.03.05 |
|---|---|
| [딥러닝] 퍼셉트론 (0) | 2026.03.05 |
| [딥러닝] 기계학습과 수학(2) (0) | 2026.03.04 |
| [딥러닝] 기계학습과 수학(1) (0) | 2026.03.04 |
| 딥러닝 [수정중] (0) | 2025.12.12 |