소프트맥스 함수

taetae·2023년 2월 8일

정의

소프트맥스 함수는 분류될 클래스가 n개라 할 때, n차원의 벡터를 입력받아, 각 클래스에 속할 확률을 추정하는 출력층 함수입니다.

확률을 출력하기 때문에 0~1 사이의 숫자를 출력합니다.

소프트맥스 함수의 식

yk=exp(ak)i=1nexp(ai)y_k=\frac{\exp \left(a_k\right)}{\sum_{i=1}^n \exp \left(a_i\right)}

exp(x)에서 e^x를 뜻하는 지수함수, n은 출력층의 뉴런 수, softmax(x)i 는 k번째 출력임을 뜻합니다.

  1. 파이썬으로 소프트맥스 함수 구현
a = np.array([0.6, 2.7, 4.6])
exp_a = np.exp(a)
print(exp_a)

>>> [ 1.8221188  14.87973172 99.48431564]

sum_exp_a = np.sum(exp_a)
print(sum_exp_a)

>>> 116.18616616719711

y = exp_a / sum_exp_a
print(y)

>>> [0.01568275 0.12806802 0.85624923]
  1. 함수 정의
def softmax(a):
  exp_a = np.exp(a)
  sum_exp_a = np.sum(exp_a)
  y = exp_a / sum_exp_a
  return y

💥 주의할점 : 소프트맥스 함수구현할때 오버플로 문제가 발생가능

오버플로란?

컴퓨터는 수가 4바이트나 8바이트와 같이 크기가 유한한 데이터를 주로 다룹니다.

그런데, 소프트맥스 함수에서는 exp(a)를 사용하게 됩니다.

이는 지수함수가 너무 무한한, 큰 값을 다루기 때문에 표현할 수 있는 범위가 한정되어 문제가 발생하고 이런 큰 값들을 나눗셈을 하면서 결과 수치가 ‘불안정’하게 되는 현상을 말합니다 !


값이 너무 커지면, nan(not a number) 이 출력된다.

오버플로 문제점을 개선한 수식

yk=exp(ak)i=1nexp(ai)=Cexp(ak)Ci=1nexp(ai)=exp(ak+logC)i=1nexp(ai+logC)=exp(ak+C)i=1nexp(ai+C)\begin{aligned}y_k=\frac{\exp \left(a_k\right)}{\sum_{i=1}^n \exp \left(a_i\right)} & =\frac{C \exp \left(a_k\right)}{C \sum_{i=1}^n \exp \left(a_i\right)} \\& =\frac{\exp \left(a_k+\log C\right)}{\sum_{i=1}^n \exp \left(a_i+\log C\right)} \\& =\frac{\exp \left(a_k+C^{\prime}\right)}{\sum_{i=1}^n \exp \left(a_i+C^{\prime}\right)}\end{aligned}

전개 과정 설명

  1. C라는 임의 정수를 분자와 분모 모두 곱해줍니다. (분자 분모에 곱해줬으므로 계산 결과의 영향 안미침.)
  2. C를 지수함수 안으로 옮겨 log C로 만들기
  3. log C 를 C’라는 새로운 기호로 바꾸기

수식을 통해 확인할 수 있는 부분

  • 소프트맥스의 지수함수를 계산할때 어떤 정수를 더해도 결과는 바뀌지 않음을 확인 가능합니다.
  • 오버플로를 막기 위해서는 입력신호의 값 중 최댓값을 이용해 빼준다면, 계산이 가능해 질 것입니다.

문제점을 개선한 코드

a = np.array([1000, 1010, 990])
c = np.max(a)

y = np.exp(a-c) / np.sum(np.exp(a-c))
print(y)

>>> [4.53978686e-05 9.99954600e-01 2.06106005e-09]
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

# 출력 확인
arr = np.array([1000, 1010, 990])
softmax(arr)

>>> array([4.53978686e-05, 9.99954600e-01, 2.06106005e-09])

소프트맥스 함수 이용방식

다 더했을때 합이 1 이므로 이를 ‘확률’로 해석이 가능합니다.

예를 들어 설명하자면

y[0] 확률이 0.1 , y[1] 확률이 0.6, y[2]의 확률이 0.3으로 위와 같은 array형태로 나오게 된다면, 이를 통해서 ‘0.6을 가진 y[2]의 확률이 60%으로 답은 y[2] 이다.’라는 결론을 내릴 수 있게 됩니다.

이는 딥러닝 모델들의 분류과정을 거친후, 결론을 내릴 때 출력층에서 사용하게 됩니다.

profile
interested in Data Science & AI

0개의 댓글