Softmax


1. Softmax

Softmax는 입력을 확률분포로 변환하는 함수입니다. 수식은 아래와 같습니다.

$$ \hat{y}_i = {e^{x_i} \over \sum_{j=1}^C e^{x_j}} $$

softmax-01.png

위 그림과 같이 Softmax는 분류 모델에서 최종 출력을 확률분포로 변환할 때 주로 사용됩니다.
모델 내에서도 확률분포를 이용할 경우가 필요할 경우 사용되기도 합니다.

부정(0), 긍정(1), 중립(2) 이렇게 3가지를 예측하는 모델을 가정해 보겠습니다.

# 모델의 출력
x = np.array([0.9, 1.2, -0.4])

위 코드와 같이 모델의 최종 출력이 [0.9, 1.2, -0.4] 라고 가정하고 softmax 함수를 이용해 확률분포를 구해보겠습니다.

# exp
exp_x = np.exp(x)

결과 >> array([2.45960311, 3.32011692, 0.67032005])

위 코드는 $e^x$를 구한 결과입니다.

# sum of exp
sum_x = np.sum(exp_x)

결과 >> 6.450040079929137

위 코드는 확률분포의 분모가 되는 $\sum_{j=1}^C e^{x_j}$를 구한 결과입니다.

# probability
y_pred = exp_x / sum_x

결과 >> array([0.38133145, 0.51474361, 0.10392494])

위 코드는 최종 확률분포를 구한 결과입니다. 확률분포이므로 [0, 1] 사이의 값이고 모두 더하면 1이 됩니다.


2. Softmax and Cross Entropy loss

위에서 구한 확률분포를 이용해 Cross Entropy loss를 구해보겠습니다. Cross Entropy loss위 수식은 아래와 같습니다.

$$ CE = -{1 \over N} \sum_{i=n}^N\sum_{j=1}^C y_{ij} \ \log \hat{y}_{ij} $$

위 수식에서 샘플 수를 의미하는 N은 1이므로 ${1 \over N} \sum_{i=n}^N$은 무시할 수 있습니다.

# true label
y_true = np.array([0, 1, 0])

위 코드와 같이 정답이 긍정(1)이라고 가정하면 정답 확률분포를 [0, 1, 0]이라고 할 수 있습니다.

# log y_pred
log_y_pred = np.log(y_pred)

결과 >> array([-0.96408634, -0.66408634, -2.26408634])

위 코드는 예측확률에 log를 취한 $ \log \hat{y}$를 구한 결과입니다.

# cross entropy loss
ce = - (y_true * log_y_pred)

결과 >> array([0.        , 0.66408634, 0.        ])

위 코드는 정답 확률과 예측 확률에 log를 취한 값을 곱한 $y \ \log \hat{y}$를 구한 결과입니다.
이 결과에서 정답은 0 또는 1이므로 0인 부분은 모두 0이 되어서 무시되었고 1인 부분은 $\ \log \hat{y}$값이 그대로 유지됩니다.
예측한 정답 확률이 1에 가까워질수록 Cross Entropy loss가 감소하게 됩니다.

# sum of cross entropy loss
np.sum(ce)

결과 >> 0.6640863447308765

위 코드는 Cross Entropy loss를 더한 결과 입니다. 샘플이 여러개일경우는 여러 값들의 평균을 계산하면 됩니다.