딥러닝 최적화의 세계: 왜 학습은 이토록 어려운가
딥러닝 모델을 학습시키는 일은 생각보다 훨씬 복잡하고 섬세한 작업이다. 단순히 데이터를 넣고 버튼을 누르면 마법처럼 최적의 모델이 만들어지는 것이 아니라, 수많은 함정과 장애물을 피해가며 조심스럽게 모델을 훈련시켜야 한다. 오늘은 딥러닝 최적화가 왜 어려운지, 그리고 어떻게 하면 효과적으로 학습시킬 수 있는지에 대한 이야기를 해보려 한다.
학습의 근본적인 딜레마
딥러닝을 처음 배울 때 많은 사람들이 간과하는 사실이 하나 있다. 바로 우리가 학습할 때 사용하는 목적 함수와 실제로 모델의 성능을 평가하는 지표가 다르다는 점이다. 예를 들어, 우리가 이미지 분류 모델을 학습시킬 때 실제로 관심 있는 것은 '정확도'다. 100장의 사진 중 90장을 맞추면 90%의 정확도를 얻는 것처럼 말이다. 하지만 정작 학습할 때는 정확도를 직접 사용하지 못한다.
왜 그럴까? 정확도라는 것은 본질적으로 미분이 불가능한 함수이기 때문이다. 맞으면 1점, 틀리면 0점. 이렇게 계단식으로 뚝뚝 끊어지는 함수에서는 기울기를 구할 수 없다. 그런데 딥러닝의 핵심인 경사하강법은 기울기를 따라 가중치를 업데이트하는 방법이다. 기울기가 없으면 어느 방향으로 가야 할지 알 수 없다. 그래서 우리는 어쩔 수 없이 MSE나 Cross Entropy 같은 미분 가능한 대리 목적 함수를 사용한다. 이것이 첫 번째 근본적인 어려움이다. 우리가 정말 원하는 것과 실제로 최적화하는 것 사이에 괴리가 존재한다는 점.
더 나아가, 딥러닝의 목적 함수는 엄청나게 복잡한 형태를 띤다. 수학 시간에 배운 2차 함수처럼 아래로 볼록한 그릇 모양이었다면 얼마나 좋았을까. 그런 함수는 어디서 시작하든 결국 바닥으로 굴러떨어지면 된다. 하지만 실제 딥러닝의 Loss Landscape는 마치 험준한 산맥처럼 수많은 봉우리와 골짜기, 그리고 평평한 고원으로 이루어져 있다. 이런 비볼록 공간에서 최적점을 찾는다는 것은 눈을 가리고 산속에서 가장 낮은 지점을 찾는 것과 비슷하다.
여기에 더해 특징 공간은 고차원이고, 데이터는 그 광활한 공간의 아주 작은 부분에만 분포한다. 그리고 학습에는 엄청난 시간이 소요된다. VGGNet이라는 유명한 모델을 당시 최고 사양의 GPU 4대로 훈련시키는데 무려 3주가 걸렸다고 한다. 이 모든 요소들이 복합적으로 얽혀 딥러닝 최적화를 어렵게 만든다.
시험 채점과 목적 함수
목적 함수가 얼마나 중요한지 이해하기 위해 간단한 비유를 들어보자. 학생들이 시험을 봤는데, 선생님이 0점을 받은 학생에게도 100점을 주고, 100점을 받은 학생에게도 100점을 준다면 어떻게 될까? 0점 받은 학생은 당장은 기뻐할지 모르지만, '공부하지 않아도 되는구나'라는 잘못된 교훈을 얻게 된다. 100점 받은 학생은 '내가 이렇게 열심히 했는데 0점 받은 애랑 똑같다니'라며 좌절할 것이다. 결과적으로 학급 전체의 학습이 망가진다.
딥러닝도 마찬가지다. 모델이 얼마나 틀렸는지에 비례해서 적절한 '벌점'을 받아야 한다. 많이 틀렸으면 큰 벌점, 조금 틀렸으면 작은 벌점. 그래야 다음 번에 더 나아질 수 있다. 이것이 목적 함수가 가져야 할 가장 기본적인 성질이다.
Sigmoid와 MSE의 치명적인 결합
초창기 신경망에서는 Sigmoid 활성화 함수와 MSE 목적 함수를 함께 사용했다. 직관적으로는 합리적인 선택처럼 보인다. MSE는 예측값과 실제값의 차이를 제곱하니까 틀릴수록 에러가 커진다. Sigmoid는 출력을 0과 1 사이로 만들어주니 확률처럼 해석할 수 있다. 하지만 이 둘을 결합하면 심각한 문제가 발생한다.
구체적인 예를 들어보자. 같은 입력 1.5가 들어왔는데, 첫 번째 경우는 bias 0.5, 가중치 0.4를 거쳐 Sigmoid를 통과해서 0.75가 나왔다. 두 번째 경우는 bias 3, 가중치 1.9를 거쳐 0.997이 나왔다. 타겟이 0이라고 했을 때, 어느 쪽이 더 많이 틀렸을까? 당연히 두 번째다. 0.997은 0에서 훨씬 멀다. 그러면 두 번째 경우에 더 큰 gradient가 발생해서 더 많이 업데이트되어야 상식적이다.
그런데 실제로 계산해보면 놀라운 일이 벌어진다. 첫 번째 경우의 gradient는 약 0.002이고, 두 번째 경우는 0.004 정도다. 더 많이 틀렸는데 gradient는 비슷하거나 오히려 작을 수도 있다. 이게 대체 어떻게 된 일일까?
비밀은 Sigmoid 함수의 미분에 있다. Sigmoid 함수를 미분하면 종 모양의 Gaussian 같은 그래프가 나온다. 입력이 0 근처일 때는 미분값이 최대 0.25 정도 나오지만, 입력이 크거나 작으면 미분값이 0에 가까워진다. 두 번째 경우는 Sigmoid에 들어가는 값 자체가 컸기 때문에, 아무리 오차가 크더라도 Sigmoid 미분값이 거의 0이 되어버린 것이다. 이것이 악명 높은 Vanishing Gradient 문제다.
비유하자면, 시험을 못 본 학생에게 "너 공부 더 해야 돼"라고 말해야 하는데, 목소리가 너무 작아서 안 들린다. 반면 조금만 틀린 학생에게는 "조금만 더 노력하면 돼"라고 크게 말한다. 완전히 뒤바뀐 상황이다.
Softmax와 Cross Entropy: 우아한 해결책
이 문제를 해결하기 위해 등장한 것이 Softmax 활성화 함수와 Cross Entropy 목적 함수의 조합이다. 이 둘을 이해하려면 먼저 확률 분포의 관점에서 생각해볼 필요가 있다.
모델의 출력을 하나의 확률 분포로 보는 것이다. 예를 들어 성별 분류라면 [0.7, 0.3]은 "70% 여자, 30% 남자"라는 모델의 믿음을 나타낸다. 정답 레이블도 마찬가지로 [1, 0]은 "100% 여자, 0% 남자"라는 확실한 분포다. 그렇다면 학습의 목표는 무엇인가? 모델의 분포를 정답 분포에 가깝게 만드는 것이다. 이 두 분포 사이의 거리를 재는 도구가 바로 Cross Entropy다.
Cross Entropy는 정보 이론에서 나온 개념인데, 수식으로 쓰면 -[y log(o) + (1-y) log(1-o)] 같은 형태가 된다. 여기서 y는 정답, o는 예측이다. 이 함수가 놀라운 이유는 그 기울기 때문이다. y가 1일 때를 생각해보자. 그러면 Loss는 -log(o)가 된다. o가 1에 가까우면 log(1) = 0이니까 Loss가 0이다. 완벽하다. 하지만 o가 0에 가까우면? log(0)는 음의 무한대로 발산한다. 앞에 마이너스가 붙으니 Loss는 양의 무한대가 된다. 즉, 틀리면 틀릴수록 기하급수적으로 벌점이 커진다.
이것이 핵심이다. MSE는 선형적으로 증가했다면, Cross Entropy는 지수적으로 폭발한다. 조금 틀렸을 때와 많이 틀렸을 때의 차이가 극명하다. 이것이 모델에게 더 강력한 학습 신호를 준다.
Softmax의 비밀
그렇다면 Softmax는 무엇인가? 이름부터 흥미롭다. "Soft"와 "Max"의 결합. 마치 "순살 뼈해장국"처럼 모순적으로 들린다. 하지만 이 이름에는 깊은 의미가 담겨 있다.
Max 함수를 생각해보자. [1, 3, 7, 2, 5]라는 입력이 있으면 Max는 7을 선택한다. 혹은 one-hot 벡터로 [0, 0, 1, 0, 0]을 출력한다. 하나만 1, 나머지는 0. 매우 결단력 있는 함수다. 하지만 이 함수는 미분이 안 된다. If-else 구조로 되어 있기 때문이다.
Softmax는 Max 함수를 부드럽게(Soft) 만든 버전이다. 완전히 0과 1로 딱딱 떨어지는 대신, [0.05, 0.11, 0.84, 0.03, 0.07] 같은 식으로 "가장 큰 값은 1에 가깝게, 나머지는 0에 가깝게" 만든다. 그러면서도 미분 가능한 매끄러운 함수다.
이를 어떻게 달성할까? 비법은 exponential 함수다. 입력 x에 대해 exp(x)를 취하면, 큰 값은 기하급수적으로 더 커지고, 작은 값은 상대적으로 미미해진다. 예를 들어 2와 4는 2배 차이지만, exp(2)와 exp(4)는 약 7배 이상 차이난다. 이렇게 격차를 벌린 다음, 전체 합으로 나눠서 확률 분포로 만든다. 그러면 Multinomial Distribution이 완성된다.
왜 굳이 이렇게 복잡하게 할까? 정답 레이블이 one-hot 벡터, 즉 Multinomial Distribution이기 때문이다. 둘 다 같은 종류의 분포면 Cross Entropy로 거리를 재기가 훨씬 자연스럽다. 사과와 사과를 비교하는 것이지, 사과와 오렌지를 비교하는 게 아니다.
수학의 아름다운 만남
여기서 흥미로운 사실이 하나 있다. Softmax와 Cross Entropy를 결합해서 gradient를 계산하면, 엄청나게 복잡한 미적분이 나와야 할 것 같지만, 실제로는 놀랍도록 간단한 식이 나온다. 바로 x(o - y)다. 입력 곱하기 (예측 - 정답). 이게 끝이다.
이 식이 얼마나 아름다운지 생각해보자. x는 입력의 크기를 나타낸다. 중요한 특징일수록 큰 값이다. (o - y)는 오차다. 많이 틀렸을수록 크다. 즉, "중요한 특징에서 많이 틀렸으면 크게 업데이트하라"는 완벽하게 직관적인 규칙이 수식으로 표현된 것이다.
더 놀라운 것은 두 다른 세계의 만남이다. Cross Entropy는 정보 이론에서 왔고, Log Likelihood는 통계학에서 왔다. 완전히 다른 철학과 배경을 가진 두 개념이, 수식으로 전개해보면 정확히 같은 형태로 수렴한다. Cross Entropy = -Log Likelihood. 단지 음수 하나 차이다. 이것은 마치 서로 다른 길을 걸어온 두 사람이 산 정상에서 만나는 것과 같다. 진리는 하나라는 것을 보여주는 수학적 증거다.
데이터 전처리의 중요성
아무리 좋은 목적 함수를 쓰더라도, 데이터가 엉망이면 학습이 제대로 되지 않는다. 특히 두 가지 문제가 심각하다. 규모의 문제와 양수의 문제다.
규모의 문제를 건강 데이터로 설명해보자. 키와 몸무게를 특징으로 쓴다고 하자. 키는 미터 단위로 1.88m, 1.55m 같은 식이다. 몸무게는 킬로그램으로 65.5kg, 45kg 같은 식이다. 언뜻 보면 문제없어 보인다. 하지만 숫자를 보면, 키는 12 사이에서 놀고, 몸무게는 4080 사이에서 논다. 약 100배의 차이다.
이게 왜 문제일까? Gradient 공식을 다시 보자. x(o - y). 특징값 x가 크면 gradient도 비례해서 커진다. 몸무게는 gradient가 100배 크고, 키는 100배 작다. 그러면 몸무게 가중치는 확확 업데이트되는데, 키 가중치는 거의 움직이지 않는다. 학습률을 몸무게에 맞춰 낮추면 학습은 되지만, 키는 사실상 무시된다. 키가 성별 구분에 엄청나게 중요한 특징일 수 있는데도 말이다.
양수의 문제는 더 미묘하다. 자연계의 대부분 데이터는 양수다. 키, 몸무게, 혈압, 나이, 거리. 모두 양수다. 음수는 인간이 발명한 추상적 개념이다. 그런데 모든 입력이 양수면 어떤 일이 벌어질까?
한 노드로 들어가는 여러 가중치를 생각해보자. w1, w2, w3가 있고, 입력 x1, x2, x3가 모두 양수라고 하자. Gradient를 계산하면 δ × x1, δ × x2, δ × x3가 된다. 여기서 δ는 그 노드의 공통 gradient다. x들이 모두 양수니까, δ가 양수면 모든 gradient가 양수고, δ가 음수면 모두 음수다. 즉, 가중치들이 항상 같은 방향으로만 움직인다.
이것을 좌표평면에 그려보자. w1과 w2를 축으로 하는 평면에서, 우리는 1사분면(모두 양수)이나 3사분면(모두 음수)으로만 움직일 수 있다. 2사분면과 4사분면은 금지구역이다. 최적점이 2사분면에 있다면? 직선으로 갈 수 없다. 1사분면으로 갔다가 3사분면으로 가는 식으로 지그재그로 우회해야 한다. 엄청나게 비효율적이다.
정규화: 모든 문제의 해결사
이 두 문제를 한 방에 해결하는 방법이 정규화다. Z-Score Normalization이라고 부르는데, 방법은 간단하다. 각 특징마다 평균을 빼고 표준편차로 나눈다.
평균을 빼면 어떻게 될까? 분포의 중심이 0으로 이동한다. 키 170cm가 평균이었다면, 정규화 후에는 0이 된다. 170보다 큰 값은 양수, 작은 값은 음수가 된다. 데이터가 양수와 음수에 골고루 분포하게 되고, 가중치들이 모든 방향으로 자유롭게 움직일 수 있다. 양수 문제 해결.
표준편차로 나누면? 모든 특징의 표준편차가 1이 된다. 키도 1, 몸무게도 1. 규모가 통일된다. 이제 gradient가 공정하게 발생한다. 중요도는 데이터가 결정하는 것이지, 측정 단위가 결정하는 게 아니다. 규모 문제 해결.
어떤 사람은 걱정한다. "원래 값이 바뀌는데 정보가 손실되는 거 아닌가요?" 좋은 질문이다. 170cm가 0이 되고, 160cm가 -0.5가 되면 원래 값은 사라진다. 하지만 중요한 것은 절대값이 아니라 관계다. 180cm가 170cm보다 크다는 사실은 변하지 않는다. 정규화 후에도 여전히 더 크다. 순서가 보존된다. 순서가 보존되면 정보는 보존된 것이다.
화씨와 섭씨를 생각해보자. 같은 온도를 다른 단위로 재는 것뿐이다. 정규화는 "표준 단위"로 변환하는 것과 같다. 패턴과 관계는 그대로 유지된다.
명목형 변수의 함정
숫자로 된 연속형 변수는 정규화로 해결됐다. 하지만 명목형 변수는 어떻게 할까? 성별, 혈액형, MBTI 같은 카테고리 데이터 말이다.
흔한 실수는 이렇게 하는 것이다. 남자=1, 여자=2. 태양인=1, 소양인=2, 태음인=3, 소음인=4. 숫자를 그냥 매겨버린다. 하지만 이것은 심각한 문제를 일으킨다.
여자(2)가 남자(1)보다 크다는 게 무슨 의미인가? 없다. 비교 자체가 불가능하다. 그런데 모델은 이 숫자를 보고 순서가 있다고 착각한다. 더 큰 문제는 거리 개념이다. 소음인을 맞춰야 하는데 소양인으로 예측한 것과 태양인으로 예측한 것, 어느 쪽이 더 나쁠까? 둘 다 똑같이 틀렸다. 하지만 숫자로는 소양인이 3-4=1 차이, 태양인이 1-4=3 차이가 된다. 말도 안 되는 얘기다.
해결책은 One-Hot Encoding이다. 성별이면 [1, 0] 또는 [0, 1]로 표현한다. 체질이면 [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]이 된다. MBTI 16가지면 16차원 벡터가 된다. 이렇게 하면 모든 카테고리가 동등하게 취급되고, 순서나 거리 같은 개념이 사라진다. 틀리면 무조건 완전히 틀린 것이다.
차원이 늘어나는 것이 단점이라고 생각할 수 있지만, 정확한 표현을 위해서는 감수할 가치가 있다. 잘못된 표현으로 잘못 학습하는 것보다는 차원이 조금 늘어나더라도 올바르게 표현하는 게 낫다.
가중치 초기화의 예술
데이터 전처리가 끝났다. 이제 모델을 학습시킬 차례다. 하지만 여기서 또 하나의 중요한 선택이 기다린다. 가중치를 처음에 어떤 값으로 시작할 것인가?
절대로 해서는 안 되는 것이 있다. 모든 가중치를 똑같은 값으로 초기화하는 것이다. 예를 들어 모두 0.5로 시작한다면? 첫 번째 층의 두 노드가 같은 가중치를 가지므로, 같은 출력을 만든다. 그러면 두 번째 층에서도 같은 신호를 받는다. 결국 전체 네트워크에서 같은 값들이 전파된다. 노드를 100개 쓰든 1000개 쓰든, 실제로는 1개만 쓰는 것과 다름없다. 완전한 자원 낭비다.
그래서 난수로 초기화해야 한다. 하지만 난수의 범위도 중요하다. 너무 크면 어떻게 될까? 가중치가 1000이고, 입력 노드가 1000개라면, 한 노드의 출력은 대략 1000 × 1000 = 1,000,000이 된다. 다음 층에서도 곱해지면 1조가 된다. 순식간에 폭발한다. Gradient Explosion.
반대로 너무 작으면? 0.001 같은 값이면, 층을 거칠 때마다 점점 작아진다. 10층쯤 가면 거의 0에 가까워진다. 깊은 층에는 신호가 도달하지 못한다. Vanishing Gradient.
그렇다면 적절한 범위는 무엇일까? 물리학에서 공진 현상이라는 게 있다. 영국에 다리가 하나 있었는데, 바람의 주파수가 우연히 다리의 고유 주파수와 일치했다. 두 진동이 만나 증폭되어 다리가 붕괴됐다. 신경망에서도 비슷한 일이 일어날 수 있다. 우연히 모든 입력이 크고, 가중치도 크면, 공진처럼 폭발적인 활성화가 일어난다.
이를 방지하려면 입력 노드 수를 고려해야 한다. 노드가 많으면 합이 커질 가능성이 높으니, 가중치 범위를 √n 으로 나눠준다. Kaiming He라는 연구자가 이를 수학적으로 유도했다. He Initialization이라고 불리는 이 방법은 현재 표준이 되었다. 가중치를 대략 √(2/n_in) 정도의 표준편차를 가진 정규분포에서 샘플링한다. 이렇게 하면 층을 거쳐도 분산이 크게 변하지 않아 안정적인 학습이 가능하다.
Bias는 어떻게 할까? 보통 0으로 초기화한다. Bias는 신호 전체를 위아래로 이동시키는 역할이다. 처음에는 신호의 본래 형태를 유지하는 게 좋다. 학습하면서 필요한 만큼 조정하면 된다.
현대의 안전장치
재미있는 사실은, 현대 딥러닝에서는 가중치 초기화의 중요성이 예전보다 조금 줄어들었다는 점이다. Batch Normalization이라는 기법 덕분이다. Batch Norm은 각 층의 출력을 자동으로 정규화한다. 가중치가 좀 이상하게 초기화되어도, Batch Norm이 적당히 바로잡아준다. 일종의 안전장치다.
하지만 그렇다고 해서 초기화를 아무렇게나 해도 된다는 뜻은 아니다. 좋은 초기화는 여전히 더 빠른 수렴을 가져온다. 그리고 Batch Norm을 쓰지 않는 상황도 많다. 기본기는 여전히 중요하다.
MBTI와 딥러닝의 철학
강의 중 흥미로운 주제가 나왔다. MBTI 얘기다. 요즘 많은 사람들이 MBTI로 자기 성격을 규정한다. "나는 INTJ야." 하지만 여기에는 근본적인 문제가 있다.
MBTI는 연속적인 성격을 이산적으로 나눈다. E와 I를 55% 대 45%로 나눌 수 있는데, 그냥 51%만 넘으면 E, 그렇지 않으면 I다. Hard Decision이다. 하지만 55% E인 사람과 99% E인 사람은 엄청나게 다르다. 둘 다 그냥 E로 분류되는 게 과연 맞을까?
딥러닝은 다르다. Softmax는 Soft Decision을 한다. [0.55, 0.45]처럼 확률 분포로 표현한다. 불확실성을 인정하고, 정도의 차이를 표현한다. 이것이 훨씬 현실적이다. 세상은 0과 1로만 이루어지지 않았다. 수많은 회색 지대가 있다. 딥러닝은 그것을 받아들인다.
이것이 딥러닝의 철학이기도 하다. 세상은 복잡하고, 불확실하고, 연속적이다. 우리는 그것을 있는 그대로 모델링하려 한다. 무리하게 단순화하지 않고, 확률로 표현하고, 데이터가 스스로 말하게 한다.
경험과 이론의 균형
마지막으로 중요한 조언이 있다. "Neural Networks: Tricks of the Trade"라는 책이 있다. 수많은 경험적 기법들이 담겨 있다. 하지만 책 제목에 주목하라. "Tricks"다. 이론적으로 증명된 법칙이 아니라, 해봤더니 잘 되더라는 요령들이다.
이런 경험 규칙을 대할 때는 신중해야 한다. Black Swan을 기억하라. "모든 백조는 희다"는 것이 유럽의 통념이었다. 수천 년 동안 하얀 백조만 봤으니까. 하지만 호주에서 검은 백조가 발견되면서 이 통념은 깨졌다. 하나의 반례가 통념을 무너뜨린다.
마찬가지로, "배치 크기는 32가 좋다"든지 "학습률은 0.001로 시작하라"같은 경험 규칙은 일반적으로는 맞지만, 당신의 문제에서는 다를 수 있다. 데이터가 다르고, 모델이 다르고, 목적이 다르면, 최적의 설정도 달라진다.
그래서 실험이 중요하다. 많은 모델을 돌려보고, GPU를 활용하고, 큰 데이터로 연습하고, 기록을 남겨라. 이론은 나침반이지만, 경험은 지도다. 둘 다 필요하다.
정리하며
딥러닝 최적화는 예술과 과학의 결합이다. 수학적으로 엄밀한 이론이 있지만, 실전에서는 직관과 경험이 필요하다. Softmax + Cross Entropy는 수학적으로 아름답지만, 그것만으로는 부족하다. 데이터를 정규화하고, 가중치를 신중하게 초기화하고, 학습 과정을 주의 깊게 관찰해야 한다.
핵심을 요약하면 이렇다. 첫째, 올바른 목적 함수를 선택하라. Classification에는 Cross Entropy, Regression에는 MSE. 둘째, 데이터를 전처리하라. 연속형은 정규화, 명목형은 One-Hot. 셋째, 가중치를 신중히 초기화하라. 난수로, 적절한 범위로. 넷째, Gradient가 잘 흐르게 하라. Vanishing과 Explosion을 피하라.
이 모든 것의 목표는 하나다. 모델이 데이터로부터 제대로 배울 수 있게 하는 것. 너무 빨라도, 너무 느려도 안 된다. 너무 확신해도, 너무 주저해도 안 된다. 적절한 속도로, 적절한 방향으로, 꾸준히 나아가게 하는 것. 그것이 최적화의 본질이다.
마지막으로, 겸손하라. 딥러닝은 여전히 많은 부분이 미스터리다. 왜 작동하는지 정확히 모르는 것도 많다. 그래서 더 흥미롭다. 우리는 거대한 산을 오르고 있다. 정상이 어디인지도 모르고, 최선의 길이 무엇인지도 확신할 수 없다. 하지만 한 걸음 한 걸음, 우리는 앞으로 나아간다. 그리고 때로는 놀라운 풍경을 마주한다. 그것이 딥러닝을 연구하는 기쁨이다.