2.MNIST 最簡單的識別模型

  • 該模型是tensorflow官方文檔首個模型,沒有使用卷積網絡

  • 關鍵是構建一個公式

公式爲y=wx+b,帶有二維像素值的數組(圖片)作爲輸入x,標籤(圖片結果)作爲輸出y

用正向傳播把數據(x,y)帶入訓練,再反向傳播提升梯度來不斷調整參數(w,b),使得公式的輸出儘量準確。

  • 正確率約爲92%

一、模型構建(計算公式實現)

爲了得到一章圖片(28*28=784個像素值)屬於某個特定數字類的特徵,我們對像素值進行加權求和。如果結果特徵即加權值爲負,就不屬於該類,爲正就屬於該類。

1.特徵值(需要學習參數W、b)

image

2.softmax轉換特徵值爲概率(0-1之間):

image

其中xi是輸入數據,evidencei是特徵,y爲通過特徵softmax後得到的最終概率,

而參數W和b是我們要學習得到的數據,Wi是一個[784,10]的數據,bi是一個[10]的數據,就是模型(也是一個計算公式)的核心部分。

代碼:y=tf.nn.softmax(tf.matmul(x,W)+b)

3.構建交叉熵

可以將W和b初始化爲全0向量(或隨意設置),通過迭代輸入變量的計算結果反向傳播(bp),從而使用梯度下降算法(gradient descent algorithm)完成最優化參數W和b,最優化的結果可以計算出最終的模型準球率

梯度下降需要設置學習率即學習的速率,還需要一個損失函數(最長見的是交叉熵cross-entropy),該函數得到一個loss值來刻畫模型訓練的結果(準確率)

image

y是預測的分佈,y`是實際的分佈,

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

4.訓練(BP和反向傳播,學習過程)

訓練是一系列計算,包括1.計算梯度 2.每個參數的步長變化 3.更新參數

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

train_step是一個對象,計算時會使用梯度下降來更新參數,通過反覆運行該對象完成。

for i in range(1000):
    batch = mnist.train.next_batch(50)
    train_step.run(feed_ditc={x:batch[0],y:batch[1]})
    #x,y爲具體數據,替代佔位符(placeholder)
    #等價於:
    #train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)
    #sess.run(train_step,feed_ditc={x:batch[0],y:batch[1]})

二、實現代碼:

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

print(mnist.train.images)
print(type(mnist.train.images))
print(mnist.train.images.shape)

print(mnist.train.labels)
print(type(mnist.train.labels))
print(mnist.train.labels.shape)

x = tf.placeholder('float',[None,784]) #該佔位符第一維可以是任意長度,表示圖像數據可以是28*28=784的n張圖

W = tf.Variable(tf.zeros([784,10]))
b = tf.Variable(tf.zeros([10]))
#w和b是需要學習的值,初始化爲0

y = tf.nn.softmax(tf.matmul(x,W)+b)
#模型即計算公式,y是預測值

y_ = tf.placeholder('float',[None,10])
#y_是真實值

cross_entropy = -tf.reduce_sum(y_*tf.log(y))
#計算交叉熵

train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)
#優化器,計算梯度,並將梯度作用於變量.
#使用minimize()操作,該操作不僅可以優化更新訓練的模型參數,也可以爲全局步驟(global step)計數

init = tf.initialize_all_variables()

sess = tf.Session()
sess.run(init)

for i in range(1000):
    batch_xs,batch_ys = mnist.train.next_batch(100)
    sess.run(train_step,feed_dict={x:batch_xs,y_:batch_ys})
    
correct_predict = tf.equal(tf.argmax(y,1),tf.argmax(y_,1))
#y是一個含有10個元素的標籤
#argmax(a,b)返回集合a中和數值b相同的索引值

accuracy = tf.reduce_mean(tf.cast(correct_predict,"float"))
#tf.cast將bool值轉化爲浮點數
#tf.reduce_mean可以取平均值,如[1,0,1,1]爲0.75

sess.run(accuracy,feed_dict={x:mnist.test.images,y_:mnist.test.labels}) 
sess.close()
#準確率爲0.9129



三、實現代碼2

增加了測試過程的準確率,以1000次爲一步

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

x = tf.placeholder('float',[None,784]) #該佔位符第一維可以是任意長度,表示圖像數據可以是28*28=784的n張圖

W = tf.Variable(tf.zeros([784,10]))
b = tf.Variable(tf.zeros([10]))
#w和b是需要學習的值,初始化爲0

y = tf.nn.softmax(tf.matmul(x,W)+b)
#模型即計算公式,y是預測值
y_ = tf.placeholder('float',[None,10])
#y_是真實值

cross_entropy = -tf.reduce_sum(y_*tf.log(y))
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)

correct_predict = tf.equal(tf.argmax(y,1),tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_predict,"float"))

init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)

for i in range(10000):
    batch_xs,batch_ys = mnist.train.next_batch(100)
    sess.run(train_step,feed_dict={x:batch_xs,y_:batch_ys})
    if i%1000 == 0:
    	acc=sess.run(accuracy,feed_dict={x:mnist.validation.images,y_:mnist.validation.labels})
    	#訓練1000次後(更新的參數W,b),對整體validation的測試
    	print('step %d is %g'%(i,acc))
    	#上兩行代碼等價於:
    	#print(accuracy.eval(feed_dict={x:mnist.validation.images,y_:mnist.validation.labels}))
    

accFinal=sess.run(accuracy,feed_dict={x:mnist.test.images,y_:mnist.test.labels}) 
print(accFinal)
sess.close()
#準確率爲0.9129

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章