소프트맥스란? What is softmax?
softmax란? 신경망의 출력층에서 사용하는 활성화 함수로, 분류문제에 쓰이는 함수이다.
* 회귀에서는 항등함수(identity function)을 사용한다.
softmax의 식은 다음과 같다.
파이썬에서 소프트맥스 함수 구현하기 (softmax in python)
파이썬에서 seoftmax 함수는 다음과 같이 구현한다.
1 2 3 4 5 6 7 8 | import numpy as np def softmax(a) : exp_a = np.exp(a) sum_exp_a = np.sum(exp_a) y = exp_a / sum_exp_a return y | cs |
이를 한 줄씩 실행하면 다음과 같다.
1 2 3 4 | a = np.array([0.3,2.9,4.0]) exp_a = np.exp(a) sum_exp_a = np.sum(exp_a) y = exp_a / sum_exp_a | cs |
>>> print(a)
[0.3 2.9 4. ]
>>> print(exp_a)
[ 1.34985881 18.17414537 54.59815003]
>>> print(sum_exp_a)
74.1221542101633
>>> print(y)
[0.01821127 0.24519181 0.73659691]
>>> print(sum(y))
1.0
위 코드는 softmax식을 잘 표현하고 있지만, 컴퓨터로 계산할 때는 오버플로 문제가 발생할 수 있다.
예를들어, exp(10)은 20,000이 넘고, exp(100)은 0이 40개가 넘는 큰 값이 되고, exp(1000)은 무한대를 뜻하는 inf가 return된다. 그리고 이런 큰 값끼리 나눗셈을 하면 결과가 불안정해진다.
* 오버플로란? 컴퓨터가 표현할 수 있는 수의 범위가 한정되어, 너무 큰 값은 표현할 수 없는 문제.
이를 개선하기 위해 softmax 식을 다음과 같이 변형한다.
즉, softmax지수 함수를 계산할 때 어떤수를 더하거나 빼도 결과는 바뀌지 않는다.
일반적으로는 입력 신호 중 최댓값을 빼는방식으로 한다.
예를들면,
1 2 3 4 5 6 7 | a = np.array([1010,1000,990]) np.exp(a) / np.sum(np.exp(a)) c = np.max(a) a - c np.exp(a-c)/np.sum(np.exp(a-c)) | cs |
>>> np.exp(a) / np.sum(np.exp(a))
array([nan, nan, nan])
>>> a - c array([ 0, -10, -20])
>>> np.exp(a-c)/np.sum(np.exp(a-c)) array([9.99954600e-01, 4.53978686e-05, 2.06106005e-09])
이를 바탕으로 softmax 함수를 다시 구현하면 다음과 같다.
1 2 3 4 5 6 7 | 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 | cs |
소프트맥스 함수의 특징
softmax() 함수를 사용하면 다음과 같이 계산할 수 있다.
1 2 3 4 5 | a = np.array([0.3,2.9,4.0]) y = softmax(a) print(y) np.sum(y) | cs |
>>> print(y)
[0.01821127 0.24519181 0.73659691]
>>> np.sum(y)
1.0
즉, softmax 함수의 출력은 0부터 1사이의 실수이며, 출력의 총합은 1이다. 따라서 이를 "확률"로 해석할 수 있다.
예를 들어, 위의 예제에서 y[0]의 확률은 1.8%, y[1]의 확률은 24.5%, y[2]의 확률은 73.7%로 해석할 수 있으며, 따라서 input a는 y[2] class에 속한다. 라고 결론내릴 수 있다.