解決tensorflow在訓練的時候權重是nan問題


搭建普通的卷積CNN網絡。

nan表示的是無窮或者是非數值,比如說你在tensorflow中使用一個數除以0,那么得到的結果就是nan。

在一個matrix中,如果其中的值都為nan很有可能是因為采用的cost function不合理導致的。

 

當使用tensorflow構建一個最簡單的神經網絡的時候,按照tensorflow官方給出的教程:

https://www.tensorflow.org/get_started/mnist/beginners

http://wiki.jikexueyuan.com/project/tensorflow-zh/tutorials/mnist_beginners.html  (中文教程)

 

具體的含義就不解釋了。大概分為三個部分:1,導入數據集;2,搭建模型,並且定義cost function(也叫loss function);3,訓練。

對於過程1,我們采用的不是mnist數據集,而是自己定義了一個數據集,其中

對於過程2,我們使用最簡單的CNN網絡,然后定義cost function的方式是:

cross_entropy = -tf.reduce_sum(y_*tf.log(y))

對於過程3,我們也采用教程中的例子去訓練。

 

但是在初始化W后就立刻查看W參數的結果,得到的結果都是nan,以下是輸出W權重后的結果:

這個現象是由於cost function引起的:

cross_entropy = -tf.reduce_sum(y_*tf.log(y))

上面的語句中的y_是數據集的label。我們做的是顯著性檢測,就是數據集的ground truth。

並且這個label或者ground truth一定要是one hot類型的變量。

那什么是one hot類型的變量呢?

舉一個例子:比如一個5個類的數據集,用0,1,2,3,4來表示5個類的標簽,因此label=0,1,2,3,4。這時候有的人會把y_=0,1,2,3,4。直接輸入到cost function——-tf.reduce_sum(y_*tf.log(y))中,那么這樣會導致W參數初始化都是nan。

解決辦法就是我們把label=0,1,2,3,4變為one hot變量,改變后的結果是:label=[1,0,0,0,0],[0,1,0,0,0],[0,0,1,0,0],[0,0,0,1,0],[0,0,0,0,1],這樣再輸入到tf.reduce_sum(y_*tf.log(y))中,就是正確的了,如下圖,我們采用的解決辦法是第二種,具體參考下文。

 

那么本文提供兩種方法來解決這個問題:

1,將y_從原來的類別數字變為one hot變量,使用

labels = tf.reshape(labels, [batch_size, 1])
indices = tf.reshape(tf.range(0, batch_size, 1), [batch_size, 1])
labels = tf.sparse_to_dense(
    tf.concat(values=[indices, labels], axis=1),
    [batch_size, num_classes], 1.0, 0.0)
將label轉為one hot(batch_size是你每次抓取的訓練集的個數)
2,換一個cost function,原來的cost function = -tf.reduce_sum(y_*tf.log(y))
使用的是交叉熵函數,現在我們換成二次代價函數 cost function = tf.reduce_sum(tf.square(tf.substract(y_,y)))

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM