Softmax用於手寫數字識別(Tensorflow實現)-我的理解

softmax函數的做用

  對於分類方面,softmax函數的做用是從樣本值計算獲得該樣本屬於各個類別的機率大小。例如手寫數字識別,softmax模型從給定的手寫體圖片像素值得出這張圖片爲數字0~9的機率值,這些機率值之和爲1。預測的結果取最大的機率表示的數字做爲這張圖片的分類。
html

能夠從下面這張圖理解softmax


softmax示意圖

x1,x2,x3表明輸入的值,b1,b2,b3表明類別1,2,3的偏置量,是由於輸入的值可能存在無關的干擾量。

將上圖寫成等式

\[ \left[\begin{matrix}temp_1\\temp_2\\temp_3\end{matrix}\right] =\left(\begin{matrix}W_{1,1}x_1+W_{1,2}x_2+W_{1,3}x_3+b_1\\ W_{2,1}x_1+W_{2,2}x_2+W_{2,3}x_3+b_2\\ W_{3,1}x_1+W_{3,2}x_2+W_{3,3}x_3+b_3\end{matrix}\right)\\ \left[\begin{matrix}y_1\\y_2\\y_3\end{matrix}\right] =softmax\left(\begin{matrix}temp_1\\ temp_2\\ temp_3\end{matrix}\right)\\ 其中y_i = softmax(temp_i) = \frac{exp(temp_i)}{\sum_{j=0}^{n}exp(temp_j)}\\ y_1,y_2,y_3分別表示該樣本屬於類別1,2,3的機率值。 \]
  在神經網絡中,經過訓練集訓練模型中的權重值W和偏置值b,來提升分類的準確性。
(訓練方法是定義一個損失函數(表明預測值與真實值之間的差別),而後採用梯度降低法(經過對W,b求偏導)來最小化這個損失函數,具體過程有點複雜,下面只是直接拿tensorflow的函數來實現,後面有空的話再來補充原理)

用Tensorflow實現手寫數字識別

首先從tensorflow導入mnist數據集,裏面包含了手寫數字圖片的像素矩陣,以及這些圖片所對應的數字類別:編程

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)

說明一下圖片的像素矩陣是將28x28壓平爲[1x784]大小的向量;標籤是[1x10]的向量,其中某一個數是1,其他全爲0,好比說若是標籤表示的是數字5,那麼這個標籤向量爲[0,0,0,0,1,0,0,0,0,0]。
構建模型:網絡

x = tf.placeholder("float",[None,784])
#一個二維向量的佔位符,None表示第一位能夠是任意長度,784表示一張圖片壓平後的長度
W = tf.Variable(tf.zeros([784,10]))
b = tf.Variable(tf.zeros([10]))

#temp = x*W + b
#softmax(temp)獲得一個[None,10]的向量,表示None個圖片可能表明0~9的機率。
y = tf.nn.softmax(tf.matmul(x,W)+b)

構建模型訓練過程:定義損失函數,最小化這個損失函數,從而獲得W,b函數

y_ = tf.placeholder("float",[None,10])
#這裏用佔位符來表明y_(每一個圖片的真實類別),後面運行時會將真實類別填給佔位符。
cross_entropy = -tf.reduce_sum(y_*tf.log(y))
#y是模型的預測類別,y_是真實類別,用交叉熵來表明損失函數(說明預測值和真實值之間的差別)
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)
#用梯度降低法來最小化損失函數

運行以前構造的模型:學習

init = tf.initialize_all_variables()#init表示初始化全部變量
sess = tf.Session()#啓動會話,用於運行模型
sess.run(init)#運行init才真正的使全部變量初始化
for i in range(1000):#訓練模型1000遍
    batch_xs,batch_ys = mnist.train.next_batch(100)
    #從數據集中取出100個樣本
    sess.run(train_step, feed_dict={x:batch_xs, y_:batch_ys})
    #將樣本填入以前定義的佔位符,而後運行剛纔構建的訓練過程

評估模型:測試

correct_prediction = tf.equal(tf.argmax(y,1),tf.argmax(y_,1))
#逐個判斷預測值和真實值是否相等,返回一個矩陣。
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
#tf.cast將bool型轉化爲float型,reduce_mean計算平均值(即正確率)
print(sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels}))
#將測試集填入以前的佔位符,運行以前的模型,獲得正確率

輸出結果爲:
0.9181spa

總結

  tensorflow讓用戶先從更大的層面上構建模型,其中須要的數據先由佔位符代替,而後在運行模型時再填入對應的數據。用戶不須要對具體運算過程一步步編程實現,使得神經網絡的構建簡便了許多。

正在學習tensorflows時寫的筆記,歡迎評論探討!
code

參考網址:tensorflow中文社區htm

相關文章
相關標籤/搜索