mxnet SigmoidBinaryCrossEntropy代碼分析

主要對下面這段代碼進行一下詳細的分析吧

# We use the stable formula: max(x, 0) - x * z + log(1 + exp(-abs(x))) 
loss = F.relu(pred) - pred * label + F.Activation(-F.abs(pred), act_type='softrelu')

可能有會疑惑,這不像是交叉熵的公式。這個式子只是對原式loss = -(label * log(sigmoid(pred)) - (1-label)*log(1-sigmoid(x))的一種變換,但變化後的loss更加具有穩定性。

對原式loss = -(label * log(sigmoid(pred)) - (1-label)*log(1-sigmoid(x))展開,x=pred,z=label

loss = -z * log( sigmoid(x) ) - (1-z) * log(1 - sigmoid(x))
     = -z * log(1 / (1 + e^(-x))) - (1-z) * log ( 1 - 1 / (1 + e^(-x)))
     = -z * (-log(1+e^(-x))) - (1 - z) * (log(e^(-x)) - log(1 + e^(-x)))
     = z * log (1 + e^(-x)) - (1 - z) * (-x - log(1+e^(-x)))
     = z * (-x) + x + log (1 + e^(-x))

但這裏還是和代碼中的loss部分看上去不太相同,原因在於爲了保持loss的穩定性,對它做了一點小小的變動。
對於z * (-x) + x + log (1 + e^(-x))
當x>0時,0<e^(-x)<1,數值穩定
當x<0時,e^(-x)隨着x的減小而增大趨向於正無窮,導致數值不夠穩定

但log (1 + e^(-|x|))就不存在數值不穩定的現象,所以可以對z * (-x) + x + log (1 + e^(-x))進行一點變動使它既能保持數值上的穩定,還和原式等價。
 

當x>0時:
z * (-x) + x + log (1 + e^(-x)) = z * (-x) + x + log (1 + e^(-|x|))

首先有等式:
 x + log (1 + e^(-x)) = log(1 + e^(x))
當x<0時(x = -|x|):
z * (-x) + x + log (1 + e^(-x)) = z * (-x) + 0 + log (1 + e^(-|x|))

所以loss = z * (-x) + x + log (1 + e^(-x))與loss = max(x, 0) - x * z + log(1 + exp(-abs(x)))是等價的 

注:
loss = max(x, 0) - x * z + log(1 + exp(-abs(x))) 
其中max(x,0)就等價於x>0,中的x項及x<0中的0項。
max(x,0)寫成代碼就是F.relu(x),
log (1 + e^(-|x|))就是F.Activation(-F.abs(pred), act_type='softrelu')

 

發佈了77 篇原創文章 · 獲贊 77 · 訪問量 34萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章