지난 포스팅에서 회귀 문제와 분류 문제에서의 loss function은 분포를 가정하고 세운 maximum likelihood function의 간단한 변형임을 살펴보았다.
https://steady-programming.tistory.com/36
[ML / DL] Cost function과 Maximum likelihood estimation과의 관계
서울대학교 딥러닝 기초 강의를 듣고 정리하였다. 딥러닝에서 파라미터를 근사하기 위해 필수적으로 세워야하는 cost function와 통계학에서 파라미터를 추정하기 위해 필수적으로 세우는 maximum li
steady-programming.tistory.com
간략하게 정리하면 회귀 문제에서의 mean squared error을 최소화하는 것은 error 항을 정규분포로 가정했을 때의 maximum likelihood을 최대화하는 것과 동일하고 분류 문제에서 cross entropy loss을 최소화하는 것은 bernoulli (또는 multinomial) 분포로 가정했을 때의 maximum likelihood을 최대화하는 것과 동일함을 보였다.
이전 포스팅에서는 통계학과의 연계성 관점에서 cross entropy loss와 maximum likelihood을 살펴보았다면, 이번 포스팅에서는 information theory 관점에서 cross entropy을 살펴보고자 한다.
Entropy
cross entropy을 살펴보기 전에, entropy의 개념을 짚고 넘어가자.
random variable X의 entropy는 가능한 결과에 대한 불확실성의 정도를 나타낸다.
이를 수식으로 나타내면 아래와 같다.
\[ H(p) = - \sum_{i=1}^{n} p(x_i) \log p(x_i) \]
discrete random variable일 때의 상황이며 여기서 $n$은 클래스의 수를 의미한다. entropy는 클수록 불확실성이 큼을 의미하고 작을수록 적음을 의미한다. 수식을 조금 바꿔서 생각해보자.
\[ H(p) = \sum_{i=1}^{n} p(x_i) (-\log p(x_i)) \]
우선, 정의상 $0 \leq p(x) \leq 1$ 이기 때문에 노란색으로 표시한 x축을 봐야한다. 잘 생각해보면, $p(x)$가 1에 가까울수록 해당 클래스일 확률이 높다는 뜻이고, 이는 불확실성이 해소되는 상황으로 해석할 수 있다. 즉, entropy가 작아지는 상황이다. $y=\log p(x)$는 x축이 1에 가까워질수록 entropy가 커지고 $y=-\log p(x)$는 entropy가 작아진다. 이런 맥락에서 entropy를 $y=-\log p(x)$의 관점에서 해석할 수 있는 것이다.
그렇다면, entropy을 정의한 식에서 왜 $\log$가 사용되는 것일까? 분홍색으로 표시한 부분을 보면 $p(x)$가 0에 가까워질수록 y축의 값이 exponential하게 증가하는 것을 알 수 있다. 즉, entropy 값이 지수적으로 증가하는 것이다. 그러면.. 불확실한 상황을 표현하는 수치인 entropy를 log 함수를 사용할 때 불확실하면할수록 더 극단적으로 표현할 수 있기 때문에 log 함수를 쓴게 아닌가.. 라는 개인적인 추측을 해본다. (댓글로 피드백은 언제든지 환영이다.)
동전 던지기와 주사위 던지기 예시를 통해서 entropy을 계산해보자.
직관적으로 생각해보면 동전을 던지는 상황보다 주사위를 던지는 상황에서 무엇이 나올지 더 예측하기 힘들기 때문에 불확실하다. 그것이 앞서 정의한, 더 높은 entropy 값으로 나오는 것이다.
Cross Entropy
entropy는 단일 확률 분포에 대한 불확실성을 의미한다면, cross entropy는 실제 데이터 분포를 $p$, 학습된 확률 분포를 $q$라고 할 때, 두 분포간의 일종의 차이를 의미한다. 이를 불확실성 관점에서 해석해본다면.. 학습된 모델을 통해 나온 확률 분포인 $q$는 불확실성을 갖는다. 말 그대로 학습된 것이고 true distribution은 아니기 때문이다. 이 학습된 분포인 $q$가 true distribution인 $p$와 많이 떨어져있다면 불확실성이 크다는 뜻이고 가깝다면 덜하다는 뜻일 것이다. 이와 같이 두 분포 사이의 차이에서 발생하는 일종의 '불확실성'을 cross entropy 개념으로 표현했다고 이해하면 될 것 같다.
\[ H_q (p) = -\sum_{i=1}^{n} p(x_i) \log q(x_i) \]
실제 데이터 분포인 $p$는 말그대로 true distribution이기 때문에 one-hot encoded 벡터이다. 학습된 확률 분포인 $q$는 $n$차원의 벡터로, 합이 1인 벡터이다. summation이 각 클래스별로 되어 있다. 즉, $p(x_i)=1$인 부분만 summation에서 살아남을 것이다. 이때, 해당 클래스의 학습된 확률이 $q(x_i)$이고, $y=-\log q(x_i)$을 통해서 그 확률이 1에 가깝다면 cross entropy 값을 0에 가깝게 만드는 것이다.
직관적인 얘기이긴한데, $H_q (p) \geq H(p)$일 것이다. 가장 이상적으로, $q = p$, 즉 학습된 분포가 실제 데이터 분포와 동일하다면 $H_q (p) = H(p)$인데, 현실 세계에서는 이럴 가능성은 거의 없다.
사실, 두 entropy의 차이인 $H_q (p) - H(p)$는 kullback leibler divergence로 정의된다. 이와 관련된 논의는 나중에 하도록 하자.
Binary cross entropy loss
이진 분류 문제에서 cross entropy loss을 살펴보자. 클래스가 두개이기 때문에 아래와 같이 적을 수 있다.
\[ \begin{align} H_q (p) &= -\sum_{i=1}^{2} p(x_i) \log q(x_i) \\ &= - ( p(x_1) \log q(x_1) + p(x_2) \log q(x_2) ) \\ &= -( p \log q + (1-p) \log (1-q) ) \end{align} \]
여기서 notation 편의를 위해 $p(x_1) = p, q(x_1) = q$로 두고, $p(x_1) + p(x_2) = 1, q(x_1) + q(x_2) = 1$을 사용하였다.
위의 수식은 데이터 샘플 하나에 대한 cross entropy 값이다. 즉, $j$번째 데이터에 대한 truth label이 one hot으로 있을 것이고 $p$ 이 데이터를 입력값으로 넣었을 때, 모델링된 확률값이 $q$로 나오는 것이다. 따라서 모든 데이터 $N$개에 대한 cross entropy의 평균이 최종 구하고자 하는 loss가 된다.
\[ H_q (p) = L = - \dfrac{1}{N} \sum^{N}_{j=1} (p_j \log q_j + (1-p_j) \log (1-q_j)) \]
잘 살펴보면 bernoulli distribution에서 likelihood에 -을 붙인 것과 같다!
Categorical cross entropy loss
일반적인 상황에서 클래스가 C개인 상황에서도 cross entropy을 구할 수 있다.
\[ H_q (p) = -( p_1 \log q_1 + \cdots + p_C \log q_C ) \]
여기서 $\sum^{C}_{i=1} p_i = 1, \sum^{C}_{i=1} q_i = 1$이다. 마찬가지로 N개의 데이터에 대한 cross entropy의 평균이 최종 categorical cross entropy loss가 된다.
\[ H_q (p) = L = - \dfrac{1}{N} \sum^{N}_{j=1} \sum^{C}_{i=1} p_{ij} \log q_{ij} \]
예시로 살펴보자.
4개의 클래스로 분류해야하는 문제에서 첫번째 케이스는 동일하게 0.25의 확률을, 두번째는 올바르게 첫번째 클래스의 확률을 0.93로 가장 높게 계산했다고 가정해보자. true distribution은 $p$로, one hot encoded vector이고 모델링된 확률값은 $q$이다. 첫번째 케이스의 cross entropy가 두번째 케이스의 cross entropy보다 확연하게 높음을 알 수 있다. 즉, 두번째 케이스가 true distribution을 더 잘 맞추는 상황이고 loss을 적게 주는 것이 합리적인 결론이다.
numpy로 간단하게 구현한 코드는 아래와 같다.
import numpy as np
def cross_entropy(y_true, y_pred):
y_true = y_true.reshape(-1)
y_pred = y_pred.reshape(-1)
return -(y_true * np.log2(y_pred)).mean()
a = np.array([1, 0, 0, 0])
b = np.array([0.25, 0.25, 0.25, 0.25])
c = np.array([0.93, 0.02, 0.01, 0.04])
print(cross_entropy(a, b))
print(cross_entropy(a, c))
"""
0.5
0.02617434466667331
"""
손으로 직접 계산했을 때와 동일한 결과가 나옴을 확인할 수 있다.
분류 문제에서 가장 대중적으로 사용되는 손실함수인 cross entropy loss을 살펴보았다. 사실 information theory까지 들어갈 줄은 몰랐는데 조금 깊게 들어가니까 cross entropy에서 왜 -가 붙게 되었는지, $p_i \log q_i$에서 $p,q$가 의미하는게 무엇인지, 왜 $\log$을 사용하는지 등을 알게 되어서 꽤나 유익한 시간이었다. 다음 포스팅에서는 pytorch에서 mse, ce loss 등을 살펴볼 예정이다.
'ML&DL > Basics' 카테고리의 다른 글
[DL][Implementation] Backpropagation in convolution (0) | 2024.08.31 |
---|---|
[ML / DL] Backpropagation in softmax function (1) | 2024.08.31 |
[DL][Implementation] Numpy을 사용하여 MLP 구현하기 (1) | 2024.07.13 |
[DL / Paper review] Auto-Encoding Variational Bayes (2) | 2023.05.06 |
[DL] Why multiple layer perceptron? (0) | 2023.04.25 |
댓글