Softmax란? AI가 여러 점수를 합계 1의 비율로 바꾸는 원리
지난 글에서는 코사인 유사도가 두 벡터의 방향을 비교해 관계 점수를 만드는 원리를 살펴봤습니다. AI에는 이렇게 여러 후보를 나타내는 점수가 자주 등장합니다. 그런데 점수 2, 1, 0만 보고 각 후보가 전체에서 어느 정도 비중을 차지하는지 바로 이해하기는 어렵습니다.
Softmax는 여러 실수 점수를 0과 1 사이의 값으로 바꾸고, 전체 합을 1로 만드는 함수입니다. 분류 모델의 클래스 점수, 언어 모델의 다음 토큰 점수, Transformer의 Attention 점수를 비교 가능한 비율로 바꿀 때 사용됩니다. 이번 글에서는 지수함수가 왜 필요한지, 직접 계산하면 어떤 값이 나오는지, 확률처럼 보이는 결과를 어떻게 해석해야 하는지 알아보겠습니다.
Softmax란?
Softmax는 점수 벡터 z의 각 원소를 지수화한 뒤, 모든 지수값의 합으로 나눕니다.
softmax(zᵢ) = ezᵢ / Σⱼezⱼ
e는 약 2.718인 자연상수이고, zᵢ는 i번째 입력 점수입니다. 지수값은 항상 양수이므로 결과도 0보다 작아지지 않습니다. 각 지수값을 동일한 합으로 나누기 때문에 모든 출력의 합은 정확히 1이 됩니다. PyTorch 공식 문서도 Softmax가 지정한 차원의 값을 0과 1 사이로 재조정하고 합을 1로 만든다고 설명합니다. PyTorch Softmax 공식 문서
입력 점수 로짓이란?
Softmax에 들어가기 전의 원시 점수를 흔히 로짓(Logit)이라고 부릅니다. 로짓은 양수일 수도, 0일 수도, 음수일 수도 있으며 합이 1일 필요도 없습니다. 예를 들어 이미지 분류 모델이 고양이, 강아지, 토끼에 대해 [2, 1, 0]을 출력했다면 이는 아직 확률이 아니라 클래스별 상대 점수입니다.
로짓 사이의 차이는 중요하지만 절대적인 기준점은 중요하지 않습니다. [2, 1, 0]에 같은 숫자 10을 더한 [12, 11, 10]은 Softmax를 통과하면 같은 결과를 냅니다. 모든 점수에 같은 값을 더해도 후보 사이의 차이가 유지되고, 분자와 분모에 같은 배율이 적용되어 상쇄되기 때문입니다.
Softmax를 직접 계산해 보기
로짓 [2, 1, 0]을 Softmax에 넣어 보겠습니다. 먼저 각 점수를 지수화합니다.
[e², e¹, e⁰] ≈ [7.389, 2.718, 1.000]
세 값을 더하면 11.107입니다. 각 값을 이 합으로 나누면 다음 결과를 얻습니다.
[7.389/11.107, 2.718/11.107, 1/11.107] ≈ [0.665, 0.245, 0.090]
반올림한 세 값의 합은 1.000입니다. 첫 번째 후보의 로짓은 두 번째보다 1만큼 컸지만 Softmax 출력은 약 2.7배 큽니다. e²/e¹ = e이기 때문입니다. 즉 Softmax는 단순히 점수를 합으로 나누는 것이 아니라 지수화를 통해 높은 점수와 낮은 점수의 차이를 더 분명하게 만듭니다.
왜 단순히 합으로 나누지 않을까?
[2, 1, 0]을 합 3으로 나누면 [0.667, 0.333, 0]처럼 보일 수 있습니다. 하지만 입력에 음수가 포함되면 음의 비율이 생기고, 모든 점수의 합이 0이면 나눌 수도 없습니다. 또한 모든 로짓에 같은 값을 더했을 때 결과가 달라져 상대적인 점수 차이를 안정적으로 표현하지 못합니다.
Softmax는 지수화로 모든 값을 양수로 만들고, 공통된 이동에 영향을 받지 않으며, 큰 점수를 더 강조합니다. 입력 순서도 보존합니다. 가장 큰 로짓은 가장 큰 Softmax 값을 받고, 두 로짓이 같다면 출력 비율도 같습니다.
음수 로짓도 문제없이 처리할 수 있습니다. 예를 들어 [−1, −2, −3]은 모든 값이 음수지만 지수화하면 양수가 됩니다. 또한 세 값에 3을 더한 [2, 1, 0]과 차이가 동일하므로 Softmax 결과도 같습니다. 로짓의 0은 ‘가능성 없음’을 뜻하지 않으며, 다른 후보와 비교했을 때의 상대적 위치가 중요합니다.
Softmax 출력은 확률일까?
출력이 0과 1 사이이고 합이 1이므로 확률분포처럼 사용할 수 있습니다. 분류에서는 각 클래스의 예측 분포로, 언어 모델에서는 다음 토큰 후보의 분포로 해석합니다. 그러나 0.665가 현실에서 실제로 66.5%의 정확도를 보장한다는 뜻은 아닙니다.
신경망은 과도하게 자신 있는 분포를 출력할 수 있습니다. Softmax는 주어진 로짓을 수학적으로 정규화할 뿐, 모델의 판단이 옳은지 검증하지 않습니다. 예측 확률과 실제 정답 빈도가 잘 맞는지는 별도의 보정과 평가가 필요합니다. 따라서 높은 Softmax 값과 사실성, 안전성, 불확실성은 구분해야 합니다.
수치 안정성: 가장 큰 값을 먼저 빼는 이유
컴퓨터는 표현할 수 있는 숫자 범위가 제한되어 있습니다. 로짓이 [1000, 999, 998]이면 e¹⁰⁰⁰은 너무 커서 오버플로가 발생할 수 있습니다. 하지만 세 점수에서 공통으로 최댓값 1000을 빼면 [0, −1, −2]가 되고 Softmax 결과는 변하지 않습니다.
softmax(z) = softmax(z − max(z))
실제 구현에서는 이 방식을 사용해 큰 지수 계산을 피합니다. 손으로 공식을 옮겨 적기보다 검증된 라이브러리 함수를 사용하는 편이 안전합니다. 손실 함수 계산에서는 Softmax 후 로그를 따로 취하기보다 수치적으로 안정적인 LogSoftmax나 CrossEntropyLoss 계열을 사용하는 경우가 많습니다. PyTorch 문서도 NLLLoss와 함께 사용할 때 LogSoftmax가 더 빠르고 수치적 특성이 좋다고 안내합니다.
분류 모델에서는 어떻게 사용할까?
다중 클래스 분류 모델의 마지막 선형층은 클래스마다 로짓을 출력할 수 있습니다. Softmax는 이 로짓을 클래스 분포로 바꿉니다. 예를 들어 [고양이 0.665, 강아지 0.245, 토끼 0.090]이라면 가장 큰 값의 고양이를 예측 후보로 선택할 수 있습니다.
학습할 때는 정답 클래스의 값이 커지도록 교차 엔트로피 손실을 사용합니다. 많은 프레임워크의 교차 엔트로피 함수는 내부에서 LogSoftmax에 해당하는 계산을 결합하므로, 모델 출력에 Softmax를 먼저 적용하면 중복 계산이나 잘못된 사용이 생길 수 있습니다. 사용하는 손실 함수가 로짓을 기대하는지 확률을 기대하는지 문서를 확인해야 합니다.
Attention에서는 어떤 역할을 할까?
Transformer의 Scaled Dot-Product Attention은 Query와 Key의 내적으로 관련성 점수를 만든 뒤 차원 크기의 제곱근으로 나누고 Softmax를 적용합니다. Softmax 결과는 각 Value를 얼마나 반영할지 나타내는 가중치가 되며, 한 Query를 기준으로 가중치 합은 1입니다.
Attention(Q,K,V) = softmax(QKT/√dk)V
원 논문은 큰 차원에서 내적의 크기가 커질 수 있어 √dk로 나눈 뒤 Softmax를 적용한다고 설명합니다. Attention Is All You Need 논문 이 과정은 이후 ‘Attention Score 직접 만들어보기’ 편에서 실제 숫자로 연결하겠습니다.
어느 차원에 적용하는지도 중요하다
배치와 클래스가 함께 있는 2차원 텐서에서는 보통 각 샘플의 클래스 방향에 Softmax를 적용합니다. Attention 행렬에서는 각 Query가 바라보는 Key 방향에 적용합니다. 잘못된 차원을 지정하면 전체 값의 모양은 그대로인데 전혀 다른 축의 합이 1이 되어 오류를 알아채기 어려울 수 있습니다.
결과를 검사할 때는 원하는 축의 합이 1인지, 마스킹된 위치가 실제로 0에 가까운지, NaN이나 무한대가 없는지 확인하는 습관이 좋습니다.
Attention에서는 참고하면 안 되는 미래 토큰이나 패딩 위치를 마스킹합니다. 보통 해당 위치의 로짓에 매우 큰 음수 또는 −∞를 넣은 뒤 Softmax를 적용합니다. e−∞는 0에 가까우므로 그 위치의 가중치가 0이 됩니다. 마스크를 Softmax 이후에 잘못 적용하면 남은 값들의 합이 더 이상 1이 아니게 될 수 있어, 구현 순서가 중요합니다.
Softmax 분포가 얼마나 뾰족한지는 로짓 차이에 달려 있습니다. [10, 0, 0]처럼 차이가 크면 첫 후보에 거의 모든 비중이 모이고, [0.1, 0, 0]처럼 차이가 작으면 비교적 고른 분포가 나옵니다. 이후 Temperature 편에서는 로짓을 온도로 나누어 이 뾰족함을 조절하는 원리를 별도로 다루겠습니다.
자주 헷갈리는 점
- Softmax는 가장 큰 값 하나만 고르는 함수가 아닙니다. 모든 후보에 연속적인 비율을 배정합니다.
- 출력은 모델의 정확성을 보장하지 않습니다. 로짓을 분포 형태로 바꾼 결과입니다.
- 각 원소에 독립적으로 적용되지 않습니다. 분모에 모든 후보가 들어가므로 한 로짓이 변하면 다른 출력도 달라집니다.
- 시그모이드와 목적이 다릅니다. Softmax는 서로 경쟁하는 여러 클래스에, 시그모이드는 각 항목을 독립적으로 판단하는 다중 라벨 문제에 자주 사용됩니다.
- 적용 차원을 확인해야 합니다. 어느 축의 합을 1로 만들지 명시해야 합니다.
한눈에 정리하기
Softmax는 여러 로짓을 지수화하고 전체 합으로 나누어 0과 1 사이의 분포로 바꿉니다. 순위를 유지하면서 큰 점수의 차이를 강조하고, 출력 합을 1로 만듭니다. 분류, 다음 토큰 예측, Attention 가중치 계산에서 같은 원리가 반복됩니다.
실제 구현에서는 최댓값을 먼저 빼는 수치 안정화, 적용 차원, 손실 함수와의 결합을 확인해야 합니다. 다음 글에서는 단어나 문장의 의미가 벡터 공간에 어떻게 배치되는지 살펴보는 임베딩 심화로 이어가겠습니다.
댓글
댓글 쓰기