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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Tensorflow解决MNIST手写体数字识别

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

這里給出的代碼是來自《Tensorflow實(shí)戰(zhàn)Google深度學(xué)習(xí)框架》,以供參考和學(xué)習(xí)。

首先這個(gè)示例應(yīng)用了幾個(gè)基本的方法:

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

運(yùn)行結(jié)果:

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

代碼中有每一行的詳細(xì)解釋,從運(yùn)行結(jié)果可以看出tensorflow隨著訓(xùn)練的進(jìn)行模型在驗(yàn)證集上的表現(xiàn)越來越好,最后是在測試集上的運(yùn)行效果。

本代碼有很多地方可以改進(jìn):可以參考Tensorflow 改進(jìn)的MNIST手寫體數(shù)字識別

總結(jié)

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

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。