본문 바로가기
Language-LAB/Python

softmax, log_softmax

by JS LAB 2025. 2. 13.
728x90
반응형

Softmax와 Log-Softmax 함수 설명 및 구현 분석

딥러닝에서 분류(Classification) 문제를 해결할 때 자주 사용되는 Softmax 함수Log-Softmax 함수를 구현하고, 이를 분석해보겠습니다.


1. Softmax 함수란?

개념

Softmax 함수는 주어진 입력 벡터(점수, logits)를 확률 분포로 변환하는 함수입니다.
출력 벡터의 각 요소는 0과 1 사이의 값을 가지며, 모든 요소의 합이 1이 됩니다.
이를 통해 입력값을 확률적인 해석이 가능하도록 변환할 수 있습니다.

수식으로 표현하면 다음과 같습니다.

$$S_i= \frac{e^{x_i}}{\sum_{j} e^{x_j}}$$

여기서:

  • $x_i$는 입력 점수 (logit)
  • $S_i$는 Softmax로 변환된 확률 값
  • 분자는 해당 점수의 지수 함수 적용 값
  • 분모는 모든 점수의 지수 값의 총합

Python 구현

import numpy as np
import math

def softmax(scores: list) -> np.ndarray:
    answer = np.zeros(len(scores))  # 결과 저장 배열
    total = sum([math.exp(score) for score in scores])  # 지수 함수 값들의 합

    for i in range(len(scores)):
        answer[i] = math.exp(scores[i]) / total  # Softmax 계산
    
    return np.array(answer)

# 테스트
print(softmax([1, 2, 3]))  
print(sum(softmax([1, 2, 3])))  # 확률 분포이므로 합은 1

설명

  • math.exp(score)를 사용하여 각 점수에 대해 지수 함수를 적용합니다.
  • total 변수에 모든 점수의 지수 값을 더한 값을 저장합니다.
  • 최종적으로 각 요소를 지수 값의 총합으로 나누어 확률 분포로 변환합니다.
  • Softmax 함수의 결과는 확률 분포이므로 모든 값의 합이 1이 됩니다.

2. Log-Softmax 함수란?

개념

Log-Softmax 함수는 Softmax 함수를 변형한 함수로, 로그를 적용하여 안정적인 확률 값을 계산하는 방식입니다.
Softmax 함수에서 직접 로그를 적용하면 수치적으로 불안정한 값이 나올 수 있는데,
이를 방지하기 위해 Softmax 계산 과정에서 로그를 먼저 취하는 방법을 사용합니다.

수식은 다음과 같습니다.

$$log⁡S_i = x_i - \max(x) - \log \sum_{j} e^{x_j - \max(x)}$$

여기서:

  • max(x)를 빼주는 것은 **수치적 안정성(numerical stability)**을 위한 것입니다.
  • 직접 Softmax 후 로그를 취하는 것보다 더 안전한 방식입니다.

Python 구현

def log_softmax(scores: list) -> np.ndarray:
    answer = np.zeros(len(scores))  # 결과 저장 배열
    max_score = max(scores)  # 안정성을 위한 최대값
    total = sum([math.exp(score - max_score) for score in scores])  # 정규화된 지수 값들의 합

    for i in range(len(scores)):
        answer[i] = scores[i] - max_score - np.log(total)  # Log-Softmax 변환
    
    return np.array(answer)

# 테스트
print(log_softmax([1, 2, 3]))  
print(sum(log_softmax([1, 2, 3])))  # 합이 0에 가까운 값이 됨

설명

  • 먼저 max(scores)를 계산하여 가장 큰 값을 찾습니다.
  • 모든 점수에서 max(scores)를 빼고 지수 함수를 적용하여 오버플로우(overflow) 방지를 합니다.
  • 이후 로그를 적용하여 Log-Softmax 변환을 수행합니다.
  • 결과 값들의 합은 0에 가까운 값을 가집니다.

3. Softmax vs Log-Softmax 비교

 

 

항목 Softmax  Log-Softmax
출력 값의 범위 (0,1) (−∞,0]
합의 값 1 0
계산 방식 확률 분포로 변환 확률 값에 로그 적용
수치 안정성 다소 불안정 (오버플로우 가능) 상대적으로 안정적
사용 예시 분류 확률 계산 크로스 엔트로피 손실 계산

4. 딥러닝에서의 활용

  • Softmax 함수
    • 딥러닝에서 마지막 출력층(출력 레이어)에 사용됨
    • 분류 문제에서 다중 클래스 확률을 얻기 위해 활용됨
    • torch.nn.Softmax() 또는 tensorflow.nn.softmax()로 쉽게 사용 가능
  • Log-Softmax 함수
    • 크로스 엔트로피 손실(CrossEntropyLoss)을 계산할 때 사용됨
    • Log를 적용하면 곱셈 연산이 덧셈 연산으로 변환되어 계산 효율성이 증가
    • torch.nn.LogSoftmax()로 사용 가능
    • Log-Softmax와 NLLLoss(negative log likelihood loss)를 함께 쓰면 CrossEntropyLoss와 동일한 효과를 가짐

5. 개선할 수 있는 점

위 코드에서는 math.exp()를 사용하여 개별적으로 Softmax와 Log-Softmax를 계산했는데,
NumPy의 벡터 연산을 활용하면 성능을 더 최적화할 수 있습니다.

최적화된 코드

def softmax(scores: list) -> np.ndarray:
    scores = np.array(scores)
    exp_scores = np.exp(scores - np.max(scores))  # 수치 안정성을 위해 최대값을 빼줌
    return exp_scores / np.sum(exp_scores)

def log_softmax(scores: list) -> np.ndarray:
    scores = np.array(scores)
    max_score = np.max(scores)
    return scores - max_score - np.log(np.sum(np.exp(scores - max_score)))
  • np.exp(scores - np.max(scores)): 최대값을 빼서 안정성을 확보
  • np.sum()을 사용하여 한 번에 연산 처리하여 효율성 증가

6. 결론

  • Softmax는 확률 분포를 얻을 때 유용하며, Log-Softmax는 크로스 엔트로피 손실을 계산할 때 안정적인 방식으로 활용됩니다.
  • 직접 구현할 수도 있지만, 딥러닝 라이브러리(PyTorch, TensorFlow)에서 제공하는 함수를 사용하면 더욱 효율적입니다.
  • 수치 안정성을 고려하여 max(scores)를 빼주는 것이 중요한 최적화 기법입니다.
728x90
반응형

'Language-LAB > Python' 카테고리의 다른 글

One-hot Encoding 구현  (0) 2025.02.11
range 와 np.arange()  (1) 2025.02.10
[Pytorch] 2  (0) 2023.08.30
[pytorch] 1  (0) 2023.08.30