1. 程式人生 > 實用技巧 >Tensorflow踩坑系列---softmax_cross_entropy_with_logits

Tensorflow踩坑系列---softmax_cross_entropy_with_logits

一:常見啟用函式Sigmoid、Relu、Tanh、Softmax

(一)sigmoid:https://www.jianshu.com/p/506595ec4b58---以作為啟用函式

1)  值域在0和1之間
2)  函式具有非常好的對稱性
3)  函式對輸入超過一定範圍就會不敏感

(二)tanh:http://www.ai-start.com/dl2017/html/lesson1-week3.html---以作為啟用函式

tanh函式或者雙曲正切函式是總體上都優於sigmoid函式的啟用函式,值域是位於+1和-1之間,其均值是更接近零均值的。在訓練一個演算法模型時,如果使用tanh函式代替sigmoid

函式中心化資料,使得資料的平均值更接近0而不是0.5.

但是在二分類中(0,1)還是用sigmoid更好,因為範圍在(0,1)之間。

sigmoid與tanh缺點:sigmoid函式和tanh函式兩者共同的缺點是,在特別大或者特別小的情況下,導數的梯度或者函式的斜率會變得特別小,最後斜率就會接近於0,導致降低梯度下降的速度

(三)relu:http://www.ai-start.com/dl2017/html/lesson1-week3.html---可以作為啟用函式

修正線性單元的函式(ReLu所以,只要是正值的情況下,導數恆等於1,當是負值的時候,導數恆等於0。

補充:從實際上來說,當使用的導數時,=0的導數是沒有定義的。但是當程式設計實現的時候,

的取值剛好等於0.00000001,這個值相當小,所以,在實踐中,不需要擔心這個值,是等於0的時候,假設一個導數是1或者0效果都可以。

注意:這裡也有另一個版本的Relu被稱為Leaky Relu

當是負值時,這個函式的值不是等於0,而是輕微的傾斜,這個函式通常比Relu啟用函式效果要好,儘管在實際中Leaky ReLu使用的並不多。

Relu優點:

第一,在的區間變動很大的情況下,啟用函式的導數或者啟用函式的斜率都會遠大於0,在程式實現就是一個if-else語句,而sigmoid函式需要進行浮點四則運算,在實踐中,使用ReLu啟用函式神經網路通常會比使用sigmoid或者tanh啟用函式學習的更快。

第二,sigmoid

tanh函式的導數在正負飽和區的梯度都會接近於0,這會造成梯度彌散,而ReluLeaky ReLu函式大於0部分都為常數,不會產生梯度彌散現象。(同時應該注意到的是,Relu進入負半區的時候,梯度為0,神經元此時不會訓練,產生所謂的稀疏性,而Leaky ReLu不會有這問題)

ReLu的梯度一半都是0,但是,有足夠的隱藏層使得z值大於0,所以對大多數的訓練資料來說學習過程仍然可以很快。

(四):迴歸函式softmax

1)softmax第一步就是將模型的預測結果轉化到指數函式上,這樣保證了概率的非負性。
2)各種預測結果概率之和等於1

softmax不同於其他啟用函式,一般只用於輸出層上!!之前,我們的啟用函式都是接受單行數值輸入,例如SigmoidReLu啟用函式,輸入一個實數,輸出一個實數。Softmax啟用函式的特殊之處在於,因為需要將所有可能的輸出歸一化,就需要輸入一個向量,最後輸出一個向量。

補充:hardmax

二:交叉熵函式

(一)錯誤記憶-XXX

由於先去學習的二分類,所以把交叉熵求解記成了如下格式:https://www.jianshu.com/p/b07f4cd32ba6

這只是二分類當中的交叉熵函式!!!,對於多分類是錯誤的!!!!

(二)正確版本-√√√

其中,k是類別。交叉熵刻畫的是通過概率分佈y^來表達概率分佈y的困難程度。因為正確答案是希望得到的結果,所以當交叉熵作為神經網路的損失函式時,y代表的是正確答案,y^代表的是預測值。

交叉熵刻畫的是兩個概率分佈的距離,也就是說交叉熵值越小, 兩個概率分佈越接近。

補充:交叉熵代價函式見:https://www.zhihu.com/question/341500352/answer/795497527

(三)在tensorflow中的交叉熵求解

labels = [[0.2,0.3,0.5]] #真實值
logits = [[2,0.5,1]] #預測值

#直接計算交叉熵
result1 = tf.nn.softmax_cross_entropy_with_logits(labels=labels,logits=logits) #輸入的不是經過softmax縮放過的值

#需要先對預測值進行縮放
logits_scaled = tf.nn.softmax(logits)
result2 = -tf.reduce_sum(labels*tf.log(logits_scaled),1)

with tf.Session() as sess:
    print(sess.run(result1))
    print(sess.run(result2))    

三:softmax_cross_entropy_with_logits解惑

其實上面案例(三)已經給出瞭解答:就是Tensorflow交叉熵計算函式輸入中的logits都不是softmax或sigmoid的輸出,而是softmax或sigmoid函式的輸入,因為它在函式內部進行sigmoid或softmax操作。softmax_cross_entropy_with_logits內部會實現縮放,即softmax操作。

(一)案例一如二中(三)

(二)案例二

labels = [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0]
logits = [5.414214045506107, 1.0364190761952838, 1.0931452034494957, 3.894246202026429, 2.3824730004342136, 5.965072403073978, 2.076533529367469, 1.4828656147245602, 2.3414934241076537, 3.5602012920818584, 0.11375485316768152, 3.450451299129589, 2.8094892586761437, 1.788879710725854, 2.80663522176181, 4.924723247878252, 2.4961140164238786, 5.9613323377434995, 0.7989157311136863, 4.2635188203807335, 3.4873045567789664, 5.11255294433231, 3.2693959007989832, 4.490670418324648, 1.6669091076779448, 5.747519715144237, 1.4899624466441748, 4.077105711625433, 0.1835752962824988, 5.337763177515887, 5.809078207371751, 3.070040261173903, 2.4653770382715177, 0.03311200569409323, 3.3492673710270733, 3.477621449855114, 3.63523160480906, 2.312116025458221, 0.45082654327315574, 0.4283251243179722]
#logits是隨機初始化的值
labels = np.array([labels])
logits = np.array([logits])
logits_scaled = tf.nn.softmax(logits)
#兩種交叉熵正確解法
result1 = tf.nn.softmax_cross_entropy_with_logits(labels=labels,logits=logits)
result2 = -tf.reduce_sum(labels*tf.log(logits_scaled),1)
#使用縮放後的值作為輸入,是錯誤的
result3 = tf.nn.softmax_cross_entropy_with_logits(labels=labels,logits=logits_scaled)
with tf.Session() as sess:
    print(sess.run(result1))
    print(sess.run(result2))
    print(sess.run(result3)) #使用縮放的值作為輸入,結果會出錯

(三)使用縮放後的值作為softmax_cross_entropy_with_logits輸入,導致的錯誤

CNN實現驗證碼識別中:

正確使用softmax_cross_entropy_with_logits時:

在4000次迭代後,誤差降為0.03,準確率在98%。

錯誤使用softmax_cross_entropy_with_logits時:

發現5000+迭代,誤差沒有變化,準確率也沒有增加.....!!!