ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 엔트로피와 크로스엔트로피 Cross Entropy
    딥러닝/활성화 함수 2022. 6. 5. 11:45

     

    엔트로피

    엔트로피 공식은 이렇게 생겼습니다.

    $$ \large -\sum x log({x}) $$

    엔트로피는 불확실성의 정도, 무질서함의 정도를 표현하는 것입니다. 예를 들어 동전과 주사위를 비교해 봅시다. 동전은 앞, 뒷면 2가지 경우의 수가 나오고 주사위는 6면 6가지 경우의 수가 나옵니다. 동전은 앞면과 뒷면 심플하게 2가지 경우이기 때문에 안정적이고 질서가 있습니다. 주사위는 좀 더 경우의 수가 다양하기 때문에 상대적으로 무질서해 보입니다. 엔트로피 공식에 대입해 보면 주사위 엔트로피 값이 큼을 알 수 있습니다.

     

    $$ \large -\frac{ 1 }{ 2 }log\frac{ 1 }{ 2 }-\frac{ 1 }{ 2 }log\frac{ 1 }{ 2 }\approx0.3 $$
    $$ \large -\frac{ 1 }{ 6 }log\frac{ 1 }{ 6 }-\frac{ 1 }{ 6 }log\frac{ 1 }{ 6 }-\frac{ 1 }{ 6 }log\frac{ 1 }{ 6 }-\frac{ 1 }{ 6 }log\frac{ 1 }{ 6 }-\frac{ 1 }{ 6 }log\frac{ 1 }{ 6 }-\frac{ 1 }{ 6 }log\frac{ 1 }{ 6 }\approx0.77 $$
     

     

    import math
    
    x = 0.5
    entropy = 0
    
    for _ in range(2):
        entropy = entropy - x * math.log10(x)
    print('entropy->', entropy) #entropy-> 0.3010299956639812
    x = 0.167
    entropy = 0
    
    for _ in range(6):
        entropy = entropy - x * math.log10(x)
    print('entropy->', entropy) #entropy-> 0.7788380959101218

     

     

    이때 같은 주사위라도 모양이 다르게 생겨서 1면이 나올 확률이 0.9 나머지 2,3,4,5가 0.02라고 해봅시다. 엔트로피 공식에 대입해 보면 값이 작아짐을 알 수 있습니다. 모든 면이 일정한 확률의 정육면체 주사위보다 안정적이고 질서 있게 되었습니다.

    x1 = 0.9
    x2 = 0.02
    entropy = 0
    
    entropy = entropy - x1 * math.log10(x1)
    for _ in range(5):
        entropy = entropy - x2 * math.log10(x2)
    print('entropy->', entropy) #entropy-> 0.21107874193820947

    크로스-엔트로피

    엔트로피는 x항과 y항으로 이루어져 있습니다. x항을 딥러닝 예측치라고 하고 y항을 정답 값이라고 해보겠습니다.

     

    $$ \large -\sum y log({x}) $$

     

    그리고 크로스 엔트로피는 보통 바이너리 크로스 엔트로피라고 해서 정답 값이 0 또는 1인 경우에 잘 쓰입니다. 이런 데이터 셋을 원-핫 인코딩이라고도 합니다.

     

    예를 들어 정답 (0, 1, 0) 인 경우 예측치가 (1, 0, 0) 이 될 수 있습니다. 그럼 틀렸습니다. 예측치도 (0, 1, 0)이 되어야 합니다. 이렇게 각 엘리먼트의 값 범위가 0-1이기 때문에 확률을 값으로 대입하는 엔트로피 공식을 사용할 수 있게 되었습니다.

     

    크로스 엔트로피를 파이썬 코드로 구해보겠습니다.

     

    • 먼저 크로스 엔트로피가 작동하지 않는 경우입니다. 정답이 0, 예측이 1인 경우 무조건 로스 0입니다. 이 점은 예외로 인정하고 씁니다.
    y = 0 #정답 값
    x = 1 #예측 값
    crossEntropy = -y * math.log10(x)
    print('크로스엔트로피 값 ->', crossEntropy) #크로스엔트로피 값 -> 0.0

     

    • 정답이 0 예측이 0인 경우입니다. 로스 0입니다.
    y = 0 #정답 값
    x = 0.001 #예측 값
    crossEntropyLoss = -y * math.log10(x)
    print('크로스엔트로피 값 ->', crossEntropyLoss) #크로스엔트로피 값 -> -0.0
    • 정답이 1 예측이 1인 경우입니다. 로스 0입니다.
    y = 1 #정답 값
    x = 1 #예측 값
    crossEntropyLoss = -y * math.log10(x)
    print('크로스엔트로피 값 ->', crossEntropyLoss) #크로스엔트로피 값 -> 0.0
    • 정답이 1 예측이 0인 경우입니다. 로스 3입니다. 정답과 예측치가 크게 벌어지니 로스가 커집니다.
    y = 1 #정답 값
    x = 0.001 #예측 값
    crossEntropyLoss = -y * math.log10(x)
    print('크로스엔트로피 값 ->', crossEntropyLoss) #크로스엔트로피 값 -> 3.0

    지금까지 스칼라 값에 대해 크로스 엔트로피를 구해봤습니다. 실제로는 엘리먼트들을 그룹핑 하여 벡터, 행렬 상에서 계산되어 SUM 값을 구해 최종적으로 로스를 구합니다.

    댓글

Designed by Tistory.