1. 程式人生 > >TensorFlow初識(MNIST資料集識別手寫體)

TensorFlow初識(MNIST資料集識別手寫體)

github部落格傳送門
csdn部落格傳送門
TensorFlow初識(MNIST資料集識別手寫體)

第一步 導包

import tensorflow as tf
import numpy as np
# 這裡使用tensorflow框架自帶的識別手寫體的資料集
import tensorflow.examples.tutorials.mnist.input_data as input_data  # 匯入下載資料集手寫體
mnist = input_data.read_data_sets('MNIST_data/', one_hot=True)       # 下載資料集

第二步 搭建神經網路框架

# 建立神經網路類 定義一個全連結
class MLPNet:
    # 初始化引數
    def __init__(self):
        pass
    
    # 正向傳播
    def forward(self):
        pass
    
    # 反向傳播
    def backward(self):
        pass

# 建立主函式入口
if __name__ == '__main__':
    net = MLPNet()  # 例項化物件
    net.forward()   # 呼叫forward(正向傳播)方法
    net.backward()  # 呼叫backward(反向傳播)方法
    init = tf.global_Variables_initializert()  # 初始化所有tensorflow變數的命令
    with tf.Session() as sess:  # 建立一個會話
        sess.run(init)  # 呼叫執行圖 init裡的命令

第三步 補全初始化引數 正向傳播 反向傳播

def __init__(self):
    # 定義一個佔位 資料型別 tf.float32 資料形狀是 [None, 3] 列是784,行不確定 使用時傳參
    self.x = tf.placeholder(dtype=tf.float32, shape=[None, 784])  # 輸入樣本 x (圖片)
    # 定義一個佔位 資料型別 tf.float32 資料形狀是 [None, 3] 列是10,行不確定 使用時傳參
    self.y = tf.placeholder(dtype=tf.float32, shape=[None, 10])  # 輸入標籤 y (人為標註的one_hot標籤)
    # 定義一個偽隨機的輸入層變數 服從正態分佈 資料形狀是 784, 100為神經元個數視情況而定 stddev是標準偏差 一般設定為 神經元個數的 sqrt(1/神經元個數) 
    self.in_w = tf.Variable(tf.truncated_normal(shape=[784, 100], stddev=tf.sqrt(1/100)))  # 輸入 w
    # 定義一個輸入層變數 偏值 b 裡面的值為 zeros 個數為 神經元個數
    self.in_b = tf.Variable(tf.zeros([100]))
    # 定義一個輸出層的變數 w  變數的值設定為 正態分佈的隨機值 資料的形狀是 100行 ,10列 stddev是標準偏差 一般設定為 神經元個數的 sqrt(1/神經元個數)
    self.out_w = tf.Variable(tf.truncated_normal(shape=[100, 10], stddev=0.1))
    # 定義一個輸出層的變數 b  變數的值設定為 神經元個數的 zeros值
    self.out_b = tf.Variable(tf.zeros([10]))

def forward(self):
    # tf.nn.relu(表示relu啟用函式) tf.layers.batch_normalization(對資料進行歸一化) tf.matmul(乘法表示 self.x * self.in_w)
    self.fc1 = tf.nn.relu(tf.layers.batch_normalization(tf.matmul(self.x, self.in_w)+self.in_b))  # 求 h=wx+b 中 h的值 然後歸一化 使用 tf.nn.relu 啟用函式 求出 σ(h) 得出 y冒 的 期望值
    # tf.nn.softmax(表示softmax分類器) tf.matmul(表示將self.fc1 * self.out_w相乘)
    self.output = tf.nn.softmax(tf.matmul(self.fc1, self.out_w)+self.out_b)  # 將求出的

def backward(self):
    # 求出 損失  預測值 和 標籤值的誤差的平方的均值
    self.loss = tf.reduce_mean((self.output-self.y)**2)
    # 優化器  設定訓練速率 0.1 tf.train.GradientDescentOptimizer(0.1)(梯度下降優化器, 學習速率0.1) .minimize將損失反向傳回去 做權重調整  opt返回很多引數 例:loss 
    self.opt = tf.train.GradientDescentOptimizer(0.1).minimize(self.loss)

第四步 補全主函式的訓練

# 建立主函式入口
if __name__ == '__main__':
    net = MLPNet()  # 例項化物件
    net.forward()   # 呼叫forward(正向傳播)方法
    net.backward()  # 呼叫backward(反向傳播)方法
    init = tf.global_Variables_initializert()  # 初始化所有tensorflow變數的命令
    with tf.Session() as sess:  # 建立一個會話
        sess.run(init)  # 呼叫執行圖 init裡的命令 初始化所有tensorflow變數
        for epoch in range(100000):  # 設定訓練的次數
            xs, ys = mnist.train.next_batch(100)  # 從mnist資料集中取樣本train的方法 netx_batch(100)每個批次取100張 這是minist資料集中的取圖片的內建方法
            # sess.run() tensorflow執行語句  net.output(返回的結果)多個用[列表裝起來 逗號隔開] feed_dict={net.x (例項化物件的self.x) : xs, net.y (例項化物件的self.y) : ys)}
            _loss, _ = sess.run([net.loss, net.opt], feed_dict = {net.x:xs, net.y:ys})  # 必須傳 net.opt 因為 self.opt裡面 呼叫了 tensorflow裡面的 梯度下降法的優化器 所以必須用 sess.run()方法執行一遍

第五步 寫測試集

# 建立主函式入口
if __name__ == '__main__':
    net = MLPNet()  # 例項化物件
    net.forward()   # 呼叫forward(正向傳播)方法
    net.backward()  # 呼叫backward(反向傳播)方法
    init = tf.global_Variables_initializert()  # 初始化所有tensorflow變數的命令
    with tf.Session() as sess:  # 建立一個會話
        sess.run(init)  # 呼叫執行圖 init裡的命令
        for epoch in range(100000):  # 設定訓練次數 迴圈次數
            xs, ys = mnist.train.next_batch(100)  # 從mnist資料集中取樣本train的方法 netx_batch(100)每個批次取100張 這是minist資料集中的取圖片的內建方法
            _loss, _ = sess.run([net.loss, net.opt], feed_dict = {net.x: xs, net.y: ys})
            if epoch % 100 = 0:  # 判斷迴圈 100次的時候 將測試集放入訓練後的模型 進行測試 看識別準確率
                test_xs, test_ys = mnist.test.next_batch(10000)  # 將測試集的10000張圖的資料 和 標籤取出來
                test_output = sess.run(net.output, feed_dict = {net.x: test_xs})  # 將 測試集的 資料 傳給 例項化的 net.x / self.x  然後獲取 輸出net.output
                
                test_y = np.argmax(test_ys, axis=1)  # 求 標籤集 每行的 最大值的下標 (one_hot碼) 相當於 返回 0,1,2,3,4,5,6,7,8,9 中的其中一個下標
                test_out = np.argmax(test_output, axis=1)  # 將 返回的 output 進行求 每行最大值的下標 
                print(np.mean(np.array(test_y == test_out, dtype=np.float32)))  # 將 標籤的下標 和 輸出的下標 進行對比 然後求平均值 算出準確率

全部程式碼綜合

import tensorflow as tf
import numpy as np
# 這裡使用tensorflow框架自帶的識別手寫體的資料集
import tensorflow.examples.tutorials.mnist.input_data as input_data  # 匯入下載資料集手寫體
mnist = input_data.read_data_sets('MNIST_data/', one_hot=True)       # 下載資料集

# 建立神經網路類 定義一個全連結
class MLPNet:
    def __init__(self):
        # 定義一個佔位 資料型別 tf.float32 資料形狀是 [None, 3] 列是784,行不確定 使用時傳參
        self.x = tf.placeholder(dtype=tf.float32, shape=[None, 784])  # 輸入樣本 x (圖片)
        # 定義一個佔位 資料型別 tf.float32 資料形狀是 [None, 3] 列是10,行不確定 使用時傳參
        self.y = tf.placeholder(dtype=tf.float32, shape=[None, 10])  # 輸入標籤 y (人為標註的one_hot標籤)
        # 定義一個偽隨機的輸入層變數 服從正態分佈 資料形狀是 784, 100為神經元個數視情況而定 stddev是標準偏差 一般設定為 神經元個數的 sqrt(1/神經元個數) 
        self.in_w = tf.Variable(tf.truncated_normal(shape=[784, 100], stddev=tf.sqrt(1/100)))  # 輸入 w
        # 定義一個輸入層變數 偏值 b 裡面的值為 zeros 個數為 神經元個數
        self.in_b = tf.Variable(tf.zeros([100]))
        # 定義一個輸出層的變數 w  變數的值設定為 正態分佈的隨機值 資料的形狀是 100行 ,10列 stddev是標準偏差 一般設定為 神經元個數的 sqrt(1/神經元個數)
        self.out_w = tf.Variable(tf.truncated_normal(shape=[100, 10], stddev=0.1))
        # 定義一個輸出層的變數 b  變數的值設定為 神經元個數的 zeros值
        self.out_b = tf.Variable(tf.zeros([10]))

    def forward(self):
        # tf.nn.relu(表示relu啟用函式) tf.layers.batch_normalization(對資料進行歸一化) tf.matmul(乘法表示 self.x * self.in_w)
        self.fc1 = tf.nn.relu(tf.layers.batch_normalization(tf.matmul(self.x, self.in_w)+self.in_b))  # 求 h=wx+b 中 h的值 然後歸一化 使用 tf.nn.relu 啟用函式 求出 σ(h) 得出 y冒 的 期望值
        # tf.nn.softmax(表示softmax分類器) tf.matmul(表示將self.fc1 * self.out_w相乘)
        self.output = tf.nn.softmax(tf.matmul(self.fc1, self.out_w)+self.out_b)  # 將求出的

    def backward(self):
        # 求出 損失  預測值 和 標籤值的誤差的平方的均值
        self.loss = tf.reduce_mean((self.output-self.y)**2)
        # 優化器  設定訓練速率 0.1 tf.train.GradientDescentOptimizer(0.1)(梯度下降優化器, 學習速率0.1) .minimize將損失反向傳回去 做權重調整  opt返回很多引數 例:loss 
        self.opt = tf.train.GradientDescentOptimizer(0.1).minimize(self.loss)


# 建立主函式入口
if __name__ == '__main__':
    net = MLPNet()  # 例項化物件
    net.forward()   # 呼叫forward(正向傳播)方法
    net.backward()  # 呼叫backward(反向傳播)方法
    init = tf.global_Variables_initializert()  # 初始化所有tensorflow變數的命令
    with tf.Session() as sess:  # 建立一個會話
        sess.run(init)  # 呼叫執行圖 init裡的命令
        for epoch in range(100000):  # 設定訓練次數 迴圈次數
            xs, ys = mnist.train.next_batch(100)  # 從mnist資料集中取樣本train的方法 netx_batch(100)每個批次取100張 這是minist資料集中的取圖片的內建方法
            _loss, _ = sess.run([net.loss, net.opt], feed_dict = {net.x: xs, net.y: ys})
            if epoch % 100 = 0:  # 判斷迴圈 100次的時候 將測試集放入訓練後的模型 進行測試 看識別準確率
                test_xs, test_ys = mnist.test.next_batch(10000)  # 將測試集的10000張圖的資料 和 標籤取出來
                test_output = sess.run(net.output, feed_dict = {net.x: test_xs})  # 將 測試集的 資料 傳給 例項化的 net.x / self.x  然後獲取 輸出net.output
                
                test_y = np.argmax(test_ys, axis=1)  # 求 標籤集 每行的 最大值的下標 (one_hot碼) 相當於 返回 0,1,2,3,4,5,6,7,8,9 中的其中一個下標
                test_out = np.argmax(test_output, axis=1)  # 將 返回的 output 進行求 每行最大值的下標 
                print(np.mean(np.array(test_y == test_out, dtype=np.float32)))  # 將 標籤的下標 和 輸出的下標 進行對比 然後求平均值 算出準確率