21個項目玩轉深度學習:基於TensorFlow的實踐詳解01—MNIST機器學習入門


數據集

由Yann Le Cun建立,訓練集55000,驗證集5000,測試集10000,圖片大小均為28*28

下載

# coding:utf-8
# 從tensorflow.examples.tutorials.mnist引入模塊。這是TensorFlow為了教學MNIST而提前編制的程序
from tensorflow.examples.tutorials.mnist import input_data
# 從MNIST_data/中讀取MNIST數據。這條語句在數據不存在時,會自動執行下載
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)

# 查看訓練數據的大小
print(mnist.train.images.shape)  # (55000, 784)
print(mnist.train.labels.shape)  # (55000, 10)

# 查看驗證數據的大小
print(mnist.validation.images.shape)  # (5000, 784)
print(mnist.validation.labels.shape)  # (5000, 10)

# 查看測試數據的大小
print(mnist.test.images.shape)  # (10000, 784)
print(mnist.test.labels.shape)  # (10000, 10)

# 打印出第0幅圖片的向量表示
print(mnist.train.images[0, :])

# 打印出第0幅圖片的標簽
print(mnist.train.labels[0, :]) 
train-images-idx3-ubyte.gz 9.45 MB 訓練圖像數據
train-labels-idx1-ubyte.gz 0.03MB 訓練圖像的標簽
t10k-images-idx3-ubyte.gz 1.57MB 測試圖像數據
t10k-labels-idxl-ubyte.gz 4.4KB 測試圖像的標簽

 

存成圖片

#coding: utf-8
from tensorflow.examples.tutorials.mnist import input_data
import scipy.misc
import os

# 讀取MNIST數據集。如果不存在會事先下載。
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)

# 我們把原始圖片保存在MNIST_data/raw/文件夾下
# 如果沒有這個文件夾會自動創建
save_dir = 'MNIST_data/raw/'
if os.path.exists(save_dir) is False:
    os.makedirs(save_dir)

# 保存前20張圖片
for i in range(20):
    # 請注意,mnist.train.images[i, :]就表示第i張圖片(序號從0開始)
    image_array = mnist.train.images[i, :]
    # TensorFlow中的MNIST圖片是一個784維的向量,我們重新把它還原為28x28維的圖像。
    image_array = image_array.reshape(28, 28)
    # 保存文件的格式為 mnist_train_0.jpg, mnist_train_1.jpg, ... ,mnist_train_19.jpg
    filename = save_dir + 'mnist_train_%d.jpg' % i
    # 將image_array保存為圖片
    # 先用scipy.misc.toimage轉換為圖像,再調用save直接保存。
    scipy.misc.toimage(image_array, cmin=0.0, cmax=1.0).save(filename)

print('Please check: %s ' % save_dir)

 

識別

softmax回歸

簡單的把圖像flatten了,沒考慮位置等信息,代碼如下(熟悉一下tensorflow的使用流程):

# coding:utf-8
# 導入tensorflow
# 這句import tensorflow as tf是導入TensorFlow約定俗成的做法,請大家記住。
import tensorflow as tf
# 導入MNIST教學的模塊
from tensorflow.examples.tutorials.mnist import input_data
# 與之前一樣,讀入MNIST數據
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)

# 創建x,x是一個占位符(placeholder),代表待識別的圖片
x = tf.placeholder(tf.float32, [None, 784])

# W是Softmax模型的參數,將一個784維的輸入轉換為一個10維的輸出
# 在TensorFlow中,變量的參數用tf.Variable表示
W = tf.Variable(tf.zeros([784, 10]))
# b是又一個Softmax模型的參數,我們一般叫做“偏置項”(bias)。
b = tf.Variable(tf.zeros([10]))

# y=softmax(Wx + b),y表示模型的輸出
y = tf.nn.softmax(tf.matmul(x, W) + b)

# y_是實際的圖像標簽,同樣以占位符表示。
y_ = tf.placeholder(tf.float32, [None, 10])

# 至此,我們得到了兩個重要的Tensor:y和y_。
# y是模型的輸出,y_是實際的圖像標簽,不要忘了y_是獨熱表示的
# 下面我們就會根據y和y_構造損失

# 根據y, y_構造交叉熵損失
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y)))

# 有了損失,我們就可以用隨機梯度下降針對模型的參數(W和b)進行優化
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)

# 創建一個Session。只有在Session中才能運行優化步驟train_step。
sess = tf.InteractiveSession()
# 運行之前必須要初始化所有變量,分配內存。
tf.global_variables_initializer().run()
print('start training...')

# 進行1000步梯度下降
for _ in range(1000):
    # 在mnist.train中取100個訓練數據
    # batch_xs是形狀為(100, 784)的圖像數據,batch_ys是形如(100, 10)的實際標簽
    # batch_xs, batch_ys對應着兩個占位符x和y_
    batch_xs, batch_ys = mnist.train.next_batch(100)
    # 在Session中運行train_step,運行時要傳入占位符的值
    sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})

# 正確的預測結果
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
# 計算預測准確率,它們都是Tensor
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
# 在Session中運行Tensor可以得到Tensor的值
# 這里是獲取最終模型的正確率
print(sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels}))  # 0.9185

 

兩層卷積網絡

# coding: utf-8
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data

def weight_variable(shape):
    initial = tf.truncated_normal(shape, stddev=0.1)
    return tf.Variable(initial)

def bias_variable(shape):
    initial = tf.constant(0.1, shape=shape)
    return tf.Variable(initial)

def conv2d(x, W):
    return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')

def max_pool_2x2(x):
    return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],
                          strides=[1, 2, 2, 1], padding='SAME')

if __name__ == '__main__':
    # 讀入數據
    mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
    # x為訓練圖像的占位符、y_為訓練圖像標簽的占位符
    x = tf.placeholder(tf.float32, [None, 784])
    y_ = tf.placeholder(tf.float32, [None, 10])

    # 將單張圖片從784維向量重新還原為28x28的矩陣圖片
    x_image = tf.reshape(x, [-1, 28, 28, 1])

    # 第一層卷積層
    W_conv1 = weight_variable([5, 5, 1, 32])
    b_conv1 = bias_variable([32])
    h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)
    h_pool1 = max_pool_2x2(h_conv1)
    print(h_pool1.get_shape())

    # 第二層卷積層
    W_conv2 = weight_variable([5, 5, 32, 64])
    b_conv2 = bias_variable([64])
    h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)
    h_pool2 = max_pool_2x2(h_conv2)
    print(h_pool2.get_shape())

    # 全連接層,輸出為1024維的向量
    W_fc1 = weight_variable([7 * 7 * 64, 1024])
    b_fc1 = bias_variable([1024])
    h_pool2_flat = tf.reshape(h_pool2, [-1, 7 * 7 * 64])
    h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
    # 使用Dropout,keep_prob是一個占位符,訓練時為0.5,測試時為1
    keep_prob = tf.placeholder(tf.float32)
    h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)

    # 把1024維的向量轉換成10維,對應10個類別
    W_fc2 = weight_variable([1024, 10])
    b_fc2 = bias_variable([10])
    y_conv = tf.matmul(h_fc1_drop, W_fc2) + b_fc2

    # 我們不采用先Softmax再計算交叉熵的方法,而是直接用tf.nn.softmax_cross_entropy_with_logits直接計算
    cross_entropy = tf.reduce_mean(
        tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y_conv))
    # 同樣定義train_step
    train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)

    # 定義測試的准確率
    correct_prediction = tf.equal(tf.argmax(y_conv, 1), tf.argmax(y_, 1))
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

    # 創建Session和變量初始化
    sess = tf.InteractiveSession()
    sess.run(tf.global_variables_initializer())

    # 訓練20000步
    for i in range(20000):
        batch = mnist.train.next_batch(50)
        # 每100步報告一次在驗證集上的准確度
        if i % 100 == 0:
            train_accuracy = accuracy.eval(feed_dict={x: batch[0], y_: batch[1], keep_prob: 1.0})
            print("step %d, training accuracy %g" % (i, train_accuracy))
        train_step.run(feed_dict={x: batch[0], y_: batch[1], keep_prob: 0.5})

    # 訓練結束后報告在測試集上的准確度
    print("test accuracy %g" % accuracy.eval(feed_dict={x: mnist.test.images, y_: mnist.test.labels, keep_prob: 1.0}))

 

運行結果:

root@node5 chapter_01]# python convolutional.py
Extracting MNIST_data/train-images-idx3-ubyte.gz
Extracting MNIST_data/train-labels-idx1-ubyte.gz
Extracting MNIST_data/t10k-images-idx3-ubyte.gz
Extracting MNIST_data/t10k-labels-idx1-ubyte.gz
(?, 14, 14, 32)
(?, 7, 7, 64)
2018-10-30 12:39:14.394778: I tensorflow/core/platform/cpu_feature_guard.cc:137] Your CPU supportsinstructions that this TensorFlow binary was not compiled to use: SSE4.1 SSE4.2 AVX AVX2 FMA
step 0, training accuracy 0.06
step 100, training accuracy 0.9
step 200, training accuracy 0.92
step 300, training accuracy 0.96
step 400, training accuracy 0.92
step 500, training accuracy 0.94
step 600, training accuracy 0.9
...
...
step 19300, training accuracy 1
step 19400, training accuracy 1
step 19500, training accuracy 1
step 19600, training accuracy 1
step 19700, training accuracy 1
step 19800, training accuracy 1
step 19900, training accuracy 1
test accuracy 0.9919
View Code

 

拓展閱讀

- 本章介紹的MNIST 數據集經常被用來檢驗機器學習模型的性能,在它的官網(地址:http://yann.lecun.com/exdb/mnist/ )中,可以找到多達68 種模型在該數據集上的准確率數據,包括相應的論文出處。這些模型包括線性分類器、K 近鄰方法、普通的神經網絡、卷積神經網絡等。
- 本章的兩個MNIST 程序實際上來自於TensorFlow 官方的兩個新手教程,地址為https://www.tensorflow.org/get_started/mnist/beginnershttps://www.tensorflow.org/get_started/mnist/pros 。讀者可以將本書的內容和官方的教程對照起來進行閱讀。這兩個新手教程的中文版地址為http://www.tensorfly.cn/tfdoc/tutorials/mnist_beginners.htmlhttp://www.tensorfly.cn/tfdoc/tutorials/mnist_pros.html
- 本章簡要介紹了TensorFlow 的tf.Tensor 類。tf.Tensor 類是TensorFlow的核心類,常用的占位符(tf.placeholder)、變量(tf.Variable)都可以看作特殊的Tensor。讀者可以參閱https://www.tensorflow.org/programmers_guide/tensors 來更深入地學習它的原理。
- 常用tf.Variable 類來存儲模型的參數, 讀者可以參閱https://www.tensorflow.org/programmers_guide/variables詳細了解它的運行機制,文檔的中文版地址為http://www.tensorfly.cn/tfdoc/how_tos/ variables.html
- 只有通過會話(Session)才能計算出tf.Tensor 的值。強烈建議讀者 在學習完tf.Tensor 和tf.Variable 后,閱讀https://www.tensorflow.org/programmers_guide/graphs 中的內容,該文檔描述了TensorFlow 中 計算圖和會話的基本運行原理,對理解TensorFlow 的底層原理有很大幫助。

 


免責聲明!

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



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