본문 바로가기

TIL/밑바닥부터 시작하는 딥러닝

소프트맥스 함수

1. 소프트맥스 함수

$$
y_k = \frac{exp(a_k)}{\sum_{i=1}^{n} exp(a_i)}
$$

  • exp(x)는 $e^{x}$을 뜻하는 지수 함수이다. e는 자연상수
  • n은 출력층의 뉴런 수, $y_k$는 그중 k번째 출력
  • 분모 : 모든 입력 신호의 지수 함수의 합
  • 분자 : 입력 신호 $a_k$의 지수 함수

1.1. 소프트맥스 함수 구현

def softmax(a):
    exp_a = np.exp(a)  # 지수 함수
    sum_exp_a = np.sum(exp_a)  # 지수 함수의 합

    y = exp_a / sum_exp_a
    return y


a = np.array([0.3, 2.9, 4.0])
print(softmax(a))
# 출력 : [0.01821127 0.24519181 0.73659691]
  • 이 softmax() 함수는 소프트맥스 함수의 수식을 제대로 표현하고 있지만
  • 컴퓨터로 계산할 때는 오버플로 문제가 있다.
  • 실제로 a = np.array([1010, 1000, 990])를 주고 돌려보면 [nan, nan, nan]이 나온다.
  • 오버플로를 해결하도록 함수를 개선해보자
def softmax(a):
    c = np.max(a)
    exp_a = np.exp(a - c)  # 오버플로 대책
    sum_exp_a = np.sum(exp_a)

    y = exp_a / sum_exp_a
    return y

a = np.array([1010, 1000, 990])
print(softmax(a))
# 츌력 : [9.99954600e-01 4.53978686e-05 2.06106005e-09]
  • 모든 입력 신호에 입력 신호의 최댓값을 빼서 오버플로를 해결한 코드

1.2. 소프트맥스 함수의 특징

a = np.array([0.3, 2.9, 4.0])
y = softmax(a)
print(y)
print(np.sum(y))
"""
출력
[0.01821127 0.24519181 0.73659691]
1.0
"""
  • 다음과 같이 소프트맥스 함수의 출력은 0에서 1.0 사이의 실수이다.
  • 또한, 소프트맥스 함수 출력의 총합은 1이다.
  • 이 성질 덕분에 소프트맥스 함수의 출력을 확률이라고 해석하고 사용할 수 있다.
  • 이 코드에서는 y[0] = 1.8% , y[1] = 24.5%, y[2] = 73,7% 라고 해석할 수 있는 것이다.

1.3. 주의점

  • 소프트맥스 함수를 적용해도 각 원소의 대소 관계는 변하지 않는다.
  • 이는 지수 함수 y = exp(x) 가 단조 증가 함수이기 때문
  • 즉, 소프트맥스 함수를 적용해도 출력이 가장 큰 뉴런의 위치는 달라지지 않는다.
  • 결과적으로 신경망으로 분류할 때는 출력층의 소프트맥스 함수를 생략해도 됨

머신러닝은 학습추론 두 단계를 거쳐 이뤄진다.
머신러닝 학습단계에서 모델을 학습하고, 추론 단계에서 앞서 학습한 모델로 미지의 데이터에 대해서 추론(분류)을 수행한다.
이 때 추론 단계에서는 출력층의 소프트맥스 함수를 생략하는 것이 일반적이다.
한편, 신경망을 학습시킬 때는 출력층에서 소프트맥스 함수를 사용하면 된다.


'TIL > 밑바닥부터 시작하는 딥러닝' 카테고리의 다른 글

학습 알고리즘  (1) 2024.06.18
경사법  (1) 2024.06.16
손실 함수  (1) 2024.06.15
Numpy 다차원 배열의 계산  (0) 2024.06.14
활성화 함수  (0) 2024.06.14