Skip to content

[Machine Learning] BinaryCrossEntropy 介紹與程式實作

Last Updated on 2021-05-17 by Clay

假設 target 為我們預測標籤的『正確答案』、output 為我們模型預測的『預測標籤』—— 那麼我們便可以透過 BinaryCrossEntropy 計算 target 以及 output 之間的『二元交叉熵』。

雖然常用於『二元分類』,但是用在『多標籤分類』也是沒有問題的。當然在應用上,我們需要透過 Sigmoid 函數來計算出每一個預測數值的分數。

公式為:

以下假設我們有一組這樣多標籤分的『預測標籤』以及『正確答案』:

output = [-1, -2, -3, 1, 2, 3]
target = [0, 1, 0, 0, 0, 1]



然後我們需要先將 output (也就是模型預測的分數)先進入 Sigmoid 函數處理:

def sigmoid(x):
    return 1/(1+math.exp(-x))

output = [sigmoid(x) for x in output]
print(output)



Output:

[0.2689414213699951, 0.11920292202211755, 0.04742587317756678, 0.7310585786300049, 0.8807970779778823, 0.9525741268224334]

Sigmoid 的相關討論可以參考我之前寫過的《Sigmoid function》

然後我們按照上方 BCELoss 的公式開始實做:

def BCE(output, target):
    n = len(output)
    total_value = 0

    for i in range(n):
        total_value += (target[i]*math.log(output[i])+(1-target[i])*math.log(1-output[i]))
   
    total_value *= -1/n
    print(total_value)



然後我們來計算我們 output 以及 target 之間的 BCELoss:

BCE(output, target)



Output:

0.9962590167116456

驗算

最後,我們拿 PyTorch 當中已經封裝好的 nn.BCELoss() 來驗證一下答案是否正確:

import torch
import torch.nn as nn

sigmoid = nn.Sigmoid()
BCELoss = nn.BCELoss()
output = torch.tensor([-1., -2., -3., 1., 2., 3.])
output = sigmoid(output)
target = torch.tensor(([0., 1., 0., 0., 0., 1.]))

print(BCELoss(output, target))



Output:

tensor(0.9963)

可以看到, PyTorch 封裝好的 BCELoss 應該是有四捨五入的。


References


Read More

Leave a Reply