日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Tensorflow解决MNIST手写体数字识别

發布時間:2024/9/20 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Tensorflow解决MNIST手写体数字识别 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這里給出的代碼是來自《Tensorflow實戰Google深度學習框架》,以供參考和學習。

首先這個示例應用了幾個基本的方法:

  • 使用隨機梯度下降(batch)
  • 使用Relu激活函數去線性化
  • 使用正則化避免過擬合
  • 使用帶指數衰減的學習率
  • 使用滑動平均模型來使模型更健壯
  • 使用交叉熵損失函數來刻畫預測值和真實值之間的差距的損失函數
import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data""" 設置輸入和輸出節點的個數,配置神經網絡的參數 """# MNIST數據集相關的常數 INPUT_NODE = 784 # 輸入節點個數,因為28x28=784 OUTPUT_NODE = 10 # 輸出節點個數,因為(0-9)10個數字# 配置神經網絡的參數:這里是3層的網絡層,一層的隱藏層 LAYER1_NODE = 500 # 這里使用隱藏層數只有一個的網絡結構,而節點有500個 BATCH_SIZE = 100 # 每次batch打包的樣本個數,個數越小訓練過程越接近隨機梯度下降,數字越大,訓練越接近梯度下降# 模型相關的參數 LEARNING_RATE_BASE = 0.8 # 基礎的學習率 LEARNING_RATE_DECAY = 0.99 # 學習率的衰減率 REGULARAZTION_RATE = 0.0001 # 描述模型復雜度的正則化在損失函數中的系數 TRAINING_STEPS = 5000 # 訓練輪數 MOVING_AVERAGE_DECAY = 0.99 # 滑動平均衰減率""" 定義輔助函數來計算前向傳播結果,使用ReLU做為激活函數 """# 輔助函數給定神經網絡的輸入和所有參數,計算前向傳播結果。在這里是一個三層的全連接神經網絡,RELU函數可以去線性化,同時也可以傳入用于計算平均值的類, # 這樣方便在測試時使用滑動平均模型 def inference(input_tensor, avg_class, weights1, biases1, weights2, biases2):# 不使用滑動平均類時,直接使用參數當前的取值if avg_class == None:# 計算隱藏層的前向傳播結果,這里使用RELU激活函數layer1 = tf.nn.relu(tf.matmul(input_tensor, weights1) + biases1)return tf.matmul(layer1, weights2) + biases2else:# 使用滑動平均類:首先使用avg_class.average函數來計算得出變量的滑動平均值,然后再計算相應的前向傳播結果layer1 = tf.nn.relu(tf.matmul(input_tensor, avg_class.average(weights1)) + avg_class.average(biases1))return tf.matmul(layer1, avg_class.average(weights2)) + avg_class.average(biases2) """ 定義訓練過程 """def train(mnist):x = tf.placeholder(tf.float32, [None, INPUT_NODE], name='x-input')y_ = tf.placeholder(tf.float32, [None, OUTPUT_NODE], name='y-input')# 生成隱藏層的參數。weights1 = tf.Variable(tf.truncated_normal([INPUT_NODE, LAYER1_NODE], stddev=0.1)) # 這里是784個輸入節點,500個隱層接點,也就是784x500的矩陣biases1 = tf.Variable(tf.constant(0.1, shape=[LAYER1_NODE])) # 偏置是根據隱層的節點數而定的# 生成輸出層的參數。weights2 = tf.Variable(tf.truncated_normal([LAYER1_NODE, OUTPUT_NODE], stddev=0.1)) # 同上biases2 = tf.Variable(tf.constant(0.1, shape=[OUTPUT_NODE])) # 輸出層的節點的參數# 計算不含滑動平均類的前向傳播結果,因為這里的avg_class=NONE,所以函數不會使用參數的滑動平均值y = inference(x, None, weights1, biases1, weights2, biases2)# 定義存儲訓練輪數的變量,這個變量不需要計算滑動平均值,所以這里指定這個變量為不可訓練的變量(trainable=false),在tensorflow訓練神經網絡中# 一般會將代表訓練輪數的變量指定為不可訓練的參數 global_step = tf.Variable(0, trainable=False)# 給定滑動平均衰減率和訓練輪數的變量,初始化滑動平均類。這里知道給定訓練輪數的變量可以加快訓練早期變量的更新速度。 variable_averages = tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY, global_step) # 在所有代表神經網絡參數的變量上使用滑動平均,而其他的輔助變量就不需要了。tf.trainable_variables()返回的就是圖上集合GraphKes.TRAINABLE_VARIABLES# 中的元素,這個集合的元素就是所有沒有指定trainable=false的參數variables_averages_op = variable_averages.apply(tf.trainable_variables())# 計算使用了滑動平均之后的前向傳播結果。但滑動平均不會改變變量本身的值,而是會維護一個影子變量來記錄其滑動平均值。所以需要使用滑動平均值時# 就需要明確調用average函數average_y = inference(x, variable_averages, weights1, biases1, weights2, biases2)# 計算交叉熵及其平均值:其中交叉熵作為刻畫預測值和真實值之間差距的損失函數。這里使用了tensorflow提供的tf.nn.sparse_softmax_cross_entropy_with_logits# 來計算交叉熵。當分類問題只有一個正確答案時,可以使用該函數加速計算。第一個參數是神經網絡不包括softmax層的前向傳播結果,第二個是給定的訓練數據的正確答案。# 因為標準lable是一個長度為10的一位數組,而函數argmax得到的是相應標簽對應的類別編號cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y, labels=tf.argmax(y_, 1)) cross_entropy_mean = tf.reduce_mean(cross_entropy) # 計算在當前batch中 所有樣例的交叉熵平均值# 計算L2正則化損失函數regularizer = tf.contrib.layers.l2_regularizer(REGULARAZTION_RATE) # 計算模型的正則化損失函數。一般只計算神經網絡邊上權重的正則化損失,而不使用偏置項regularaztion = regularizer(weights1) + regularizer(weights2)# 總損失等于交叉熵損失和正則化損失的和loss = cross_entropy_mean + regularaztion# 設置指數衰減的學習率。learning_rate = tf.train.exponential_decay(LEARNING_RATE_BASE, # 基礎的學習率,隨著迭代的進行,更新變量時使用的學習率在這個基礎上遞減global_step, # 當前迭代的輪數,初始值為0mnist.train.num_examples / BATCH_SIZE, # 跑完所有的訓練數據需要的迭代次數LEARNING_RATE_DECAY, # 學習率衰減速度staircase=True) # 決定衰減學習率的曲線圖是何種形式,這里是階梯衰減# 優化損失函數:這里使用tf.train.GradientDescentOptimizer優化算法來優化損失函數,注意這里的損失函數包括了交叉熵函數和L2正則化損失train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss, global_step=global_step)# 反向傳播更新參數和更新每一個參數的滑動平均值# 在訓練神經網絡時,每過一遍數據既需要通過反向傳播更新神經網絡的參數,又需要更新每一個參數的滑動平均值,為了一次完成多個操作,# tensorflow提供了 tf.control_dependencies和tf.group兩種機制。with tf.control_dependencies([train_step, variables_averages_op]): # 等同于train_op = tf.group(train_step, variables_averages_op)train_op = tf.no_op(name='train')# 計算正確率:# 檢查使用了滑動平均模型的神經網絡前向傳播結果是否正確:# tf.argmax(average_y, 1)計算每一個樣例的預測答案。其中average_y是一個batch*10的二維數組,每一行表示一個樣例的前向傳播結果。# 第二個參數1表示選取最大值的操作僅在第一個維度中進行(也就是說只在每一行中選取最大值的下標)。于是得到的結果是一個長度為batch的一維數組,# 這個一維數組中的值就表示了每一個樣例對應的數字識別結果。tf.equal判斷兩個張量的每一維是否相等,如果相等則返回TRUE,否則返回Falsecorrect_prediction = tf.equal(tf.argmax(average_y, 1), tf.argmax(y_, 1)) # 簡單來說就是判斷預測結果和真實結果是否相同# 這里首先將布爾值轉換為實數型,然后再計算平均值。這個平均值就是模型在這一維數據上的正確率accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))# 初始化會話,并開始訓練過程。with tf.Session() as sess:tf.global_variables_initializer().run()# 準備驗證數據。一般在神經網絡的訓練過程中會通過驗證數據來大致判斷停止的條件和評判訓練的效果validate_feed = {x: mnist.validation.images, y_: mnist.validation.labels}# 準備測試數據。在真實的應用中,這部分數據在訓練的時候是不可見的,這個數據只是作為模型優劣的最后評判標準test_feed = {x: mnist.test.images, y_: mnist.test.labels} # 迭代的訓練神經網絡。for i in range(TRAINING_STEPS+1):if i % 1000 == 0: # 每1000輪輸出一次在驗證數據集上的測試結果# 計算滑動平均模型在驗證數據上的結果。這里由于MNIST數據集比較小,所以一次可以處理所有的驗證數據。但如果是太大的數據集不化分為小的# batch會導致計算時間過長甚至發生內存溢出validate_acc = sess.run(accuracy, feed_dict=validate_feed)print("After %d training step(s), validation accuracy using average model is %g " % (i, validate_acc))# mnist.train.next_batch可以讀取一小部分作為訓練batchxs,ys=mnist.train.next_batch(BATCH_SIZE)# 把數據喂給定義好的模型sess.run(train_op,feed_dict={x:xs,y_:ys})# 在訓練結束之后,在測試數據集上檢測神經網絡模型的最終正確率test_acc=sess.run(accuracy,feed_dict=test_feed)print('...................................................')print(("After %d training step(s), test accuracy using average model is %g" %(TRAINING_STEPS, test_acc)))summary_writer = tf.summary.FileWriter("log_mnist", sess.graph)summary_writer.close()""" 主程序入口,這里設定模型訓練次數為5000次"""def main(argv=None):# 聲明處理MNIST數據集的類,這個類在初始化時會自動下載(當然要聯網),但這里我使用已經下載好的數據集# 因為首先會檢查指定目錄下有沒有下載好,沒有的話tensorflow會自動下載MNIST_data_folder="Mnist/"# input_data.read_data_sets會將數據分成訓練集、驗證集、測試集mnist = input_data.read_data_sets(MNIST_data_folder, one_hot=True)print('...................................................')print ("Training data size: ", mnist.train.num_examples)# 打印訓練數據集大小print ("Validating data size: ", mnist.validation.num_examples) # 打印驗證數據集的大小print ("Testing data size: ", mnist.test.num_examples) # 打印測試數據集的大小train(mnist)if __name__=='__main__':main()

運行結果:

Extracting Mnist/train-images-idx3-ubyte.gz Extracting Mnist/train-labels-idx1-ubyte.gz Extracting Mnist/t10k-images-idx3-ubyte.gz Extracting Mnist/t10k-labels-idx1-ubyte.gz ................................................... Training data size: 55000 Validating data size: 5000 Testing data size: 10000 After 0 training step(s), validation accuracy using average model is 0.075 After 1000 training step(s), validation accuracy using average model is 0.9758 After 2000 training step(s), validation accuracy using average model is 0.9818 After 3000 training step(s), validation accuracy using average model is 0.9834 After 4000 training step(s), validation accuracy using average model is 0.9828 After 5000 training step(s), validation accuracy using average model is 0.9838 ................................................... After 5000 training step(s), test accuracy using average model is 0.9835

代碼中有每一行的詳細解釋,從運行結果可以看出tensorflow隨著訓練的進行模型在驗證集上的表現越來越好,最后是在測試集上的運行效果。

本代碼有很多地方可以改進:可以參考Tensorflow 改進的MNIST手寫體數字識別

總結

以上是生活随笔為你收集整理的Tensorflow解决MNIST手写体数字识别的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。