pytorch筆記:03)softmax和log_softmax,以及CrossEntropyLoss
阿新 • • 發佈:2018-11-10
softmax在神經網路裡面比較常見,簡而言之,就是多分類的概率輸出
但是在pytorch裡面發現額外有個log_softmax( 對softmax取了一個In的對數),為啥這樣做呢?
其實涉及到 對數似然損失函式,對於用於分類的softmax啟用函式,對應的損失函式一般都是用對數似然函式,即:
其中 為softmax函式的輸出元, 的取值為0或者1,如果某一訓練樣本的輸出為第i類。則 ,其餘的 都有 =0。由於每個樣本只屬於一個類別,所以這個對數似然函式可以簡化為:
其中 即為訓練樣本真實的類別序號。
pytorch裡面提供了一個實現 torch.nn.CrossEntropyLoss(This criterion combines nn.LogSoftmax() and nn.NLLLoss() in one single class),其整合了上面的步驟。這和tensorflow中的tf.nn.softmax_cross_entropy_with_logits函式的功能是一致的。必須明確一點:在pytorch中若模型使用CrossEntropyLoss這個loss函式,則不應該在最後一層再使用softmax進行啟用。
然而在keras中,我們固化了模型的搭建,諸如:
model.add(Dense(num_classes, activation='softmax'))
model.compile(loss=keras.losses.categorical_crossentropy,optimizer=keras.optimizers.Adadelta(),metrics=['accuracy'])
我們通常在最後一層使用softmax進行啟用,保證輸出神經元的值即分類的概率值,然後在compile中使用損失函式categorical_crossentropy,這符合常理。其實可以看下keras底層的實現,其實它幫我們手動地計算了crossentropy。
def categorical_crossentropy(target, output, from_logits=False):
if not from_logits:
# scale preds so that the class probas of each sample sum to 1
output /= tf.reduce_sum(output,
len(output.get_shape()) - 1,
True)
# manual computation of crossentropy
_epsilon = _to_tensor(epsilon(), output.dtype.base_dtype)
output = tf.clip_by_value(output, _epsilon, 1. - _epsilon)
return - tf.reduce_sum(target * tf.log(output),
len(output.get_shape()) - 1)
else:
return tf.nn.softmax_cross_entropy_with_logits(labels=target,
logits=output)
題外話:
為什麼要糾結這個問題?
在天池的一個比賽中,要輸出每個類別的取值概率,使用keras直接輸出最後一層即可;然而在pytorch中softmax整合到了損失函式中,最後一層沒有使用softmax進行啟用。
reference:
對數似然損失函式 http://www.cnblogs.com/pinard/p/6437495.html