識別手寫數字

識別手寫數字的數據集是mnist。

以下內容複製粘貼在py文件中,可以直接運行。

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import pylab

'''
自動下載 mnist 數據集並解壓到 mnist_data 目錄下
如果程序下載慢,就上網把數據集下載下來,放到 mnist_data 文件夾下
t10k-images-idx3-ubyte.gz
t10k-labels-idx1-ubyte.gz
train-images-idx3-ubyte.gz
train-labels-idx1-ubyte.gz

代碼中的 one_hot=True, 表示將樣本標籤轉化爲 one_hot 編碼
例: 假設一共 10 類。 0的 one_hot 編碼爲 1000000000,1的 one_hot 編碼爲 0100000000,
    2的 one_hot 編碼爲 0010000000 ...... 依次類推,1所在的位置就代表着幾類。
'''

mnist = input_data.read_data_sets('mnist_data/', one_hot=True)
'''
MNIST 數據集中的圖片是 28x28 Pixel,所以一幅圖就有 1x784 (28x28) 的數據,
如果是黑白圖片的話,黑色地方數值爲 0,有圖案的地方,數值爲 0~255 之間數字,代表顏色的深度
如果是彩色圖片的話,一個像素會有3個值來表示 RGB 
'''
# 測試數據集
print('input_data : ', mnist.train.images)
print('input_data_shape : ', mnist.train.images.shape)  # input_data_shape :  (55000, 784)
# 從 55000x784 的矩陣中返回第二個圖像的向量
im = mnist.train.images[1]
# 重塑取出的向量,reshape 爲 28x28 的矩陣
im = im.reshape(-1, 28)
# 將矩陣圖像化
pylab.imshow(im)
# 顯示圖像
pylab.show()
'''
輸入數據集是一個 55000x784 的矩陣,所以先創建一個[None, 784] 的佔位符 images 和一個 [None, 10]的佔位符 labels 
然後使用 feed 機制將圖片和標籤輸入進去
'''
# 定義變量
tf.reset_default_graph()
images = tf.placeholder(tf.float32, [None, 784], name='images')
labels = tf.placeholder(tf.float32, [None, 10], name='labels')
# 定義學習參數
weights = tf.Variable(tf.random_normal([784, 10]))  # weights 的維度是[784, 10]
biases = tf.Variable(tf.zeros([10]))                # biases 的shape是(10, )
# 構建模型
# softmax :輸出的是一個多維向量,不論有多少個分量,其加和都是1,每個向量的分量維度是小於1的值,而這個值可以做概率解釋的
pred = tf.nn.softmax(tf.matmul(images, weights) + biases)
# 定義方向傳播結構,優化參數
# 定義損失函數
cost = tf.reduce_mean(-tf.reduce_sum(labels*tf.log(pred), reduction_indices=1))
# 定義學習參數
learning_rate = 0.01
# 使用梯度下降優化參數
train = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)
# 定義保存模型的參數
model_path = 'model/mnist_model.ckpt'
saver = tf.train.Saver()
# 訓練模型
'''
training_epochs 訓練樣本迭代次數
batch_size  訓練過程中每次取出訓練的數據量 
'''
training_epochs = 25
batch_size = 100
display_step = 1
# 啓動session
with tf.Session() as sess_save:
    # 初始化參數
    sess_save.run(tf.global_variables_initializer())
    # 啓動訓練循環
    for epoch in range(training_epochs):
        avg_cost = 0
        total_batch = int(mnist.train.num_examples/batch_size)
        for _ in range(total_batch):
            batch_x, batch_y = mnist.train.next_batch(batch_size)
            # 傳參優化
            _, cost_result = sess_save.run([train, cost], feed_dict={images: batch_x, labels: batch_y})
            # 計算平均loss值
            avg_cost += cost_result/total_batch
        if (epoch + 1) % display_step == 0:
            print('Epoch: ', '%04d' % (epoch + 1), 'cost: ', '{:.9f}'.format(avg_cost))
    # 保存模型
    saver.save(sess_save, model_path)
    print('Finished!')
    # 測試模型
    correct_prediction = tf.equal(tf.argmax(pred, 1), tf.argmax(labels, 1))
    # 計算準確率
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
    print('Accuracy: ', accuracy.eval({images: mnist.test.images, labels: mnist.test.labels}))
# 讀取模型
print('下面是讀取模型,並輸入測試: ')
with tf.Session() as sess_restore:
    # 初始化全局變量
    sess_restore.run(tf.global_variables_initializer())
    # 載入模型
    saver.restore(sess_restore, model_path)
    # 測試模型
    correct_prediction = tf.equal(tf.argmax(pred, 1), tf.argmax(labels, 1))
    # 計算準確率
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
    print('Accuracy: ', accuracy.eval({images: mnist.test.images, labels: mnist.test.labels}))

    # 輸出預測的labels向量中值爲 最大概率值 的下標
    output = tf.argmax(pred, 1)
    # 選取兩張圖片進行預測
    batch_x, batch_y = mnist.train.next_batch(2)
    output_val, pred_v = sess_restore.run([output, pred], feed_dict={images: batch_x, labels: batch_y})
    print(output_val, pred_v, batch_y)

    im = batch_x[0]
    im = im.reshape(-1, 28)
    pylab.imshow(im)
    pylab.show()

    im = batch_x[1]
    im = im.reshape(-1, 28)
    pylab.imshow(im)
    pylab.show()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章