tensorflow處理mnist(一)


這個文章是對google官方教程的解釋

預備知識

\[\begin{equation*} \left[ \begin{array}{cccc} a_1 & a_2 & a_3 \end{array} \right] \end{equation*} \]

\[\begin{equation*} softmax(a)= \left[ \begin{array}{cccc} \frac{e^{a_1}}{e^{a_1}+e^{a_2}+e^{a_3}} & \frac{e^{a_2}}{e^{a_1}+e^{a_2}+e^{a_3}} & \frac{e^{a_3}}{e^{a_1}+e^{a_2}+e^{a_3}} \end{array} \right] \end{equation*} \]

tensorflow里面有softmax的函數.可以直接調用.

import tensorflow as tf
a = tf.constant([.0, .0, .0, .0], tf.float32)
b = tf.constant([1., 2., 3., 4.], tf.float32)
result1 = tf.nn.softmax(a)
result2 = tf.nn.softmax(b)
sess = tf.Session()
print(sess.run(result1))
print(sess.run(result2))

模型訓練

mnist = input_data.read_data_sets(r"D:mnist\zip", one_hot=True)

把mnist數據集讀取內存.讀入方法的細節放在以后討論.這里只有注意one_hot=True這個參數.one_hot表示用非零即1的數組保存圖片表示的數值.比如一個圖片上寫的是0,內存中不是直接存一個0,而是存一個數組[1,0,0,0,0,0,0,0,0,0].一個圖片上面寫的是1,那個保存的就是[0,1,0,0,0,0,0,0,0,0]

x = tf.placeholder(tf.float32, [None, 784])
W = tf.Variable(tf.zeros([784, 10]))
b = tf.Variable(tf.zeros([10]))
y = tf.matmul(x, W) + b

構造一個模型.為了說明問題方便,假定數據集中只有16張照片(這個假設在后面的內容中一直存在).那么y的最終結果是一個16*10的矩陣,每一行代表一張圖片.

y_ = tf.placeholder(tf.float32, [None, 10])

定義一個占位符,用於圖片上的數.上面已經介紹過,一個圖片上面寫的是1,那么保存的就是[0,1,0,0,0,0,0,0,0,0]. 如果現在有16張圖片,y_就是一個16*10的矩陣.

cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ /* tf.log(tf.nn.softmax(y)), reduction_indices=[1]))

reduction_indices是已經過時的參數,現在已經改成了axis,所以這個代碼改為

cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ /* tf.log(tf.nn.softmax(y)), axis=1))

上面已經說過y是一個16*10的矩陣,tf.nn.softmax(y)也是一個16*10的矩陣.只不過y的每一行被歸一化到[0,1]之間.tf.log(tf.nn.softmax(y))是取自然對數,不影響結構.y_是16*10的矩陣,tf.log(tf.nn.softmax(y))也是16*10的矩陣,y_*tf.log(tf.nn.softmax(y))是把2個矩陣的對應項相乘.這一步起到的作用是把不是照片上數字的概率清0,這時候結果還是16*10的矩陣.tf.reduce_sum(y_ * tf.log(tf.nn.softmax(y)), axis=1)是把各列的值相加形成一個新的矩陣.這時候結果變成1維數組,長度是16.里面的值是分類正確的概率.因為這是正確的概率,希望正確的概率越大越好,但是梯度下降算法一般時求某個變量的極小值.所以前面要加一個負號.這是一種直觀但不嚴謹的解釋,更精度的解釋見有關熵的概念.tf.reduce_mean作用是把數組各個元素加起來.我們希望cross_entropy越小越好,求cross_entropy的極小值要用到反向傳播算法.算法原理要懂,細節tensorflow已經幫我們實現了.

train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)

這句的含義是訓練的過程是求cross_entropy的極小值,學習率是0.5.下面開始看訓練的代碼.

batch_xs, batch_ys = mnist.train.next_batch(16)

這行代碼的含義是從數據集中隨機取出16張照片.每次訓練所有照片效果理論上應該是比較好的,但是這樣很花費時間和空間.所以每次隨機取出若干張.這就是所謂的隨機梯度下降算法.有關隨機梯度下降算法收斂的原理這里不再討論.batch_xs是一個16*784的矩陣,是訓練的數據,batch_ys是一個16*10的矩陣,是訓練數據的標簽.

sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})

這行代碼才是把實際數據放到x,y_中,以上面指定的模型和方法更新W和b的值,使損失函數不斷減小.

評價訓練結果

correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))

y,y_都是在后面才賦具體值的.為了描述方便.假設y是16*10的矩陣.y_是16*10的矩陣.tf.argmax(y, 1)返回的是一個長度為16的一維數組,里面是最大概率的索引.y_是16*10的矩陣.tf.argmax(y_, 1)返回的是一個長度為16的一維數組,里面是圖片是是幾的索引.tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))返回的是一個長度為16的bool型的數組.相等的話為True,不相等的話為False. True越多說明訓練的結果越好.

accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

tf.cast(correct_prediction, tf.float32)是把bool型數組轉化為float型,True轉化為1.0, False轉化為0.0.reduce_mean時求float型數組的平均值,即正確的個數與所有個數之比.這個數越大越好,等於1說明100%分類正確.

sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels})

feed_dict={x: mnist.test.images, y_: mnist.test.labels}是把實際的數據放到x,y_中.


免責聲明!

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



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