教你用TensorFlow實現手寫數字識別

2021-09-03 10:01:38 字數 4754 閱讀 7738

弱者用淚水安慰自己,強者用汗水磨練自己。

這段時間因為專案中有一塊需要用到影象識別,最近就一直在煉丹,寶寶心裡苦,但是寶寶不說。。。

能點開這篇文章的朋友估計也已經對tensorflow有了一定了解,至少知道這是個什麼東西,我也就不過多介紹了。

實現手寫數字識別幾乎是所有入手影象識別的入門程式了,tensorflow庫裡面也有手寫數字識別的示例程式,在這個路徑下,你可以對應自己的電腦去找一下c:\programdata\anaconda3\pkgs\tensorflow-base-1.12.0-gpu_py36h6e53903_0\lib\site-packages\tensorflow\examples\tutorials\mnist。

首先載入mnist資料集,並建立預設的interactive session

from tensorflow.examples.tutorials.mnist import input_data

import tensorflow as tf

mnist=input_data.read_data_sets("mnist/",one_hot=true)

sess=tf.interactivesession()

接下來要實現的這個卷積神經網路會有很多的權重和偏置要建立,因此我們先定義好初始化函式以便重複使用。我們需要給權重製造一些隨機的雜訊來打破完全對稱,比如截斷的正太分布雜訊,標準差為0.1。同時因為我們使用的relu啟用函式,也給偏置增加一些大於零的值來避免死亡節點。

def weight_variable(shape):

initial=tf.truncated_normal(shape,stddev=0.1)

return tf.variable(initial)

def bias_variable(shape):

inital=tf.constant(0.1,shape=shape)

return tf.variable(inital)

卷積層、池化層也是接下來要重複使用的,因此也要為他們定義方法。這裡的tf.nn.conv2d是tensorflow中的2維卷積函式,引數中x是輸入,w是卷積的引數,比如[5,5,1,32],前面兩個數字代表卷積核的尺寸,第三個數字代表通道數量,因為我們只是灰度圖,所以是1,如果是rgb彩圖那麼就應該為3,最後乙個數字代表卷積核的數量,也就是這個卷積層要提取多少類的特徵。strides代表卷積模板移動的步長,都是1代表會乙個不落的劃過每個點,padding代表邊界處理方式,這裡的same代表給邊界加上padding讓卷積的輸出和輸入保持同樣的尺寸。

tf.nn.max_pool是tensorflow中的最大池化函式,我們這裡使用2x2的最大池化,就是說把乙個2x2的畫素塊降到1x1的畫素。最大池化會保留原始畫素塊中灰度值最高的哪乙個畫素,即保留最顯著的特徵。因為希望整體上縮小尺寸,因此池化層的strides也設為橫豎兩個方向以2為步長。如果步長還是1,那麼我們會得到乙個尺寸不變的。

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')

在設計卷積神經網路之前,我們還需要定義輸入的placeholder,x是特徵,y_是真實的類別,因為卷積神經網咯會利用到哦控制項結構資訊,因此需要將1d的輸入向量轉為2d的結構,就是說從1x784變成28x28,,又因為只有乙個顏色通道,所以最終的尺寸應該是[-1,28,28,1],前面的-1代表樣本數量不固定,最後的1代表顏色通道數量。

x=tf.placeholder(tf.float32,[none,784])

y_=tf.placeholder(tf.float32,[none,10])

x_image=tf.reshape(x,[-1,28,28,1])

定義第乙個卷積層,先初始化引數,[5,5,1,32]代表卷積核的尺寸為5x5,1個顏色通道,32個不同的卷積核。然後用conv2d進行卷積操作,加上偏置,用relu啟用函式進行非線性處理。最後,使用最大池化函式max_pool_2x2對卷積的輸出結果進行池化操作。

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)

定義第二層卷積,大體上和第一層一樣,把卷積核數量改為64就ok了

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)

因為前面經歷了兩次步長為2x2的最大池化,所以邊長已經只有1/4了,尺寸從28x28變到了7x7,而第二個卷積層的卷積核數量為64,其輸出的tensor尺寸也就是7x7x64。用tf.reshape對第二個卷積層的輸出tensor進行變形,轉為1d的向量,然後連線乙個全連線層,隱藏節點為1024,使用relu啟用函式。

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=tf.placeholder(tf.float32)

h_fc1_drop=tf.nn.dropout(h_fc1,keep_prob)

將dropout層連線乙個softmax層,得到最後的概率輸出。

w_fc2=weight_variable([1024,10])

b_fc2=bias_variable([10])

y_conv=tf.nn.softmax(tf.matmul(h_fc1_drop,w_fc2)+b_fc2)

定義損失函式cross_entropy,優化器用adam,學習效率盡量往小裡設定。

cross_entropy=tf.reduce_mean(-tf.reduce_sum(y_*tf.log(y_conv),reduction_indices=[1]))

train_step=tf.train.adagradoptimizer(1e-4).minimize(cross_entropy)

定義評測準確率

correct_prediction=tf.equal(tf.argmax(y_conv,1),tf.arg_max(y_,1))

accuracy=tf.reduce_mean(tf.cast(correct_prediction,tf.float32))

接下裡就是訓練過程了。開始初始化所有引數,設定訓練時dropout層的丟棄率為0.5.使用大小為50的mini-batch訓練20000次,每100次訓練輸出一次準確率。

tf.global_variables_initializer().run()

for i in range(20000):

batch=mnist.train.next_batch(50)

if i%100==0:

train_accuracy=accuracy.eval(feed_dict=)

print("step %d,training accuracy %g"%(i,train_accuracy))

train_step.run(feed_dict=)

最後訓練完成後要輸出一次最後的測試結果

print("test accury %g"%accuracy.eval(feed_dict=))
程式到這就完事了,就開始跑吧,你大概會跑上20分鐘,你的視窗就會一直輸出準確率

step 4300,training accuracy 0.88

step 4400,training accuracy 0.92

step 4500,training accuracy 0.82

step 4600,training accuracy 0.84

step 4700,training accuracy 0.94

教你用SQL實現統計排名

前言 在某些應用場景中,我們經常會遇到一些排名的問題,比如按成績或年齡排名。排名也有多種排名方式,如直接排名 分組排名,排名有間隔或排名無間隔等等,這篇文章將總結幾種mysql中常見的排名問題。建立測試表 create table scores tb id int auto increment pr...

教你用Ruby算命!

本文又名 看看我的破機器能算多少個梅森數出來 如下,mersennes def is prime?n 這裡是用了費馬小定理,很慢很慢!2.n 1 each end 1.13 each do n m 2 n 1 mersennes 上面這個寫法,2 x要計算兩次,寫法好看,但效能很低 p mersen...

手把手教你用Ucos

ucos作業系統的學習 實時作業系統 任務切換,排程 分式作業系統 不可剝奪型核心 ucosii嵌入式實時作業系統的源 分為三部分 與硬體無關的核心 與處理器有關的移植 和使用者配置檔案。ucos最多支援64個任務,優先順序分別對應0 63,其中0為最高優先順序,系統保留4個最高優先順序的任務,和4...