ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Loss] 크로스 엔트로피
    Implementation/Loss 2021. 9. 22. 13:07

    - Cross Entropy

    Entropy 는 확률분포 p 가 가지는 정보의 확신도 혹은 정보량을 수치로 표현한 것이며, 

    Cross-Entropy 는 정보 이론에서, 두 확률 분포 p 와 q를 구분하기 위해 필요한 평균 비트 수를 의미한다.

     

    # Define data
    p = [0.10, 0.40, 0.50]
    q = [0.80, 0.15, 0.05]
    
    # Define Entropy
    def entropy(p):
    	return -sum([p[i] * np.log2(p[i]) for i in range(len(p))])
    
    # Define Cross-Entropy  
    def cross_entropy(p, q):
        return -sum([p[i] * np.log2(q[i]) for i in range(len(p))])

    정보 이론에서의 Cross-Entropy 의 정의는 두 확률 분포 p, q 를 구분하기 위해 필요한 평균 비트 수를 의미한다. 

     

    따라서, np.log2(p[i]) 안의 p 값이 q로 바뀐 것을 확인해 볼 수 있다. 

     

    풀어서 말하면, P(x) 확률에다가 Q(x) 일 때의 엔트로피를 곱하게 되므로, P의 분포가 주어질 때, Q의 확률분포를 가정함

    으로써 늘어나는 정보량을 측정해 보겠다는 말이다. 

     

    Cross-Entropy 를 검색해서 찾아보다 보면은, KL divergence 라는 내용을 마주칠 수 있는데, 코드상 정의는 아래와 같다. 

    # calculate the kl divergence KL(P || Q)
    def kl_divergence(p, q):
    	return sum(p[i] * np.log2(p[i]/q[i]) for i in range(len(p)))

    kl-divergence 가 측정하게 되는 값은 cross-entropy 와 조금 다르다. 

     

    cross-entropy 가 p를 q 분포를 가정했을 때 나타나는 총 정보량을 의미한다면, 

    kl-divergence 는 p 대신 q 분포를 가정했을 때 나타나는 '추가적인' 정보량을 의미한다. 

     

    코드상에서는 p(entropy) -> q(cross-entropy) -> p/q(kl-divergence) 로 확인 가능하다. 

     

    H(x) 가 x 분포의 entropy 라고 가정한다면, 아래가 성립한다. 

    ### H(p,q) = H(p) + KL(P || Q)

     

    유추해 볼 수 있는 특징들..  

    H(p,q) != H(q,p)

    H(p,p) == H(p)

     

    - Loss function 으로서의 Cross Entropy

    보통 loss function 으로의 cross entropy 는 딥러닝에서의 분류 문제에 많이 사용하게 된다. 

    간단한 이진 분류의 예를 들어보자. 

    p = [1, 1, 1, 1, 1, 0, 0, 0, 0, 0]
    
    def entropy(p):
    	return -sum([p[i] * np.log2(p[i]) for i in range(len(p))])
    
    계산해보면, entropy 의 결과값이 0에 수렴하게 된다.
    이는 실제 데이터는 관측시에 확률의 관측이 아닌 실측을 하게 되므로
    각 현상을 목격할 확률이 100%가 되었을 때의 결과와 유사하다.

     

    하지만 y_pred 는 각 클래스가 될 수 있는 확률분포를 output 으로 가져오므로, 이 output 이 정답 label 에 가깝게

    만드는 모델을 만드는 것이 entropy 가 딥러닝 모델 안에서 loss function 으로 작동하는 원리이다. 

     

    # define classification data
    p = [1, 1, 1, 1, 1, 0, 0, 0, 0, 0]
    q = [0.8, 0.9, 0.9, 0.6, 0.8, 0.1, 0.4, 0.2, 0.1, 0.3]
    
    # calculate cross entropy for each example
    results = list()
    for i in range(len(p)):
    	# create the distribution for each event {0, 1}
    	expected = [1.0 - p[i], p[i]]
    	predicted = [1.0 - q[i], q[i]]
    	# calculate cross entropy for the two events
    	ce = cross_entropy(expected, predicted)
    	print('>[y=%.1f, yhat=%.1f] ce: %.3f nats' % (p[i], q[i], ce))
    	results.append(ce)
    print(results)
    print(np.mean(results))
    ### 0.3562
    p = [1, 1, 1, 1, 1, 0, 0, 0, 0, 0]
    q = [0.8, 0.9, 0.9, 0.6, 0.8, 0.1, 0.4, 0.2, 0.1, 0.3]
    bca = tf.keras.losses.BinaryCrossentropy(from_logits=True)
    bca(p, q).numpy()
    ### 0.5964

    keras 에서 가져온 BinaryCrossentropy 로 계산했을 때의 값과 하드코딩했을 때의 값이 다른데, 이 부분은 

    확인이 좀 더 필요하다. 

     

    #ref : https://machinelearningmastery.com/cross-entropy-for-machine-learning/

     

     

     

     

    'Implementation > Loss' 카테고리의 다른 글

    [Math] Perplexity-Language_Model  (0) 2021.09.21
    [Math] Entropy  (0) 2021.09.21
by eric