TensorFlow初識(MNIST資料集識別手寫體)
阿新 • • 發佈:2018-11-12
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))) # 將 標籤的下標 和 輸出的下標 進行對比 然後求平均值 算出準確率