搭建普通的卷積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)))
