中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何通過MNIST手寫數字識別分析神經網絡搭建

發布時間:2021-12-13 10:36:20 來源:億速云 閱讀:142 作者:柒染 欄目:互聯網科技

本篇文章為大家展示了如何通過MNIST手寫數字識別分析神經網絡搭建,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

下面將通過一個經典的案例:MNIST手寫數字識別,以代碼的形式來為大家梳理一遍神經網絡的整個過程。

一 、MNIST手寫數字數據集介紹

MNIST手寫數字數據集來源于是美國國家標準與技術研究所,是著名的公開數據集之一,通常這個數據集都會被作為深度學習的入門案例。數據集中的數字圖片是由250個不同職業的人純手寫繪制,數據集獲取的網址為:http://yann.lecun.com/exdb/mnist/。(下載后需解壓)

具體來看,MNIST手寫數字數據集包含有60000張圖片作為訓練集數據,10000張圖片作為測試集數據,且每一個訓練元素都是28*28像素的手寫數字圖片,每一張圖片代表的是從0到9中的每個數字。該數據集樣例如下圖所示:

如何通過MNIST手寫數字識別分析神經網絡搭建

如果我們把每一張圖片中的像素轉換為向量,則得到長度為28*28=784的向量。因此我們可以把MNIST數據訓練集看作是一個[60000,784]的張量,第一個維度表示圖片的索引,第二個維度表示每張圖片中的像素點。而圖片里的每個像素點的值介于0-1之間。如下圖所示:

如何通過MNIST手寫數字識別分析神經網絡搭建

此外,MNIST數據集的類標是介于0-9的數字,共10個類別。通常我們要用獨熱編碼(One_Hot Encoding)的形式表示這些類標。所謂的獨熱編碼,直觀的講就是用N個維度來對N個類別進行編碼,并且對于每個類別,只有一個維度有效,記作數字1 ;其它維度均記作數字0。例如類標1表示為:([0,1,0,0,0,0,0,0,0,0]);同理標簽2表示為:([0,0,1,0,0,0,0,0,0,0])。最后我們通過softmax函數輸出的是每張圖片屬于10個類別的概率。

 、網絡結構的設計

接下來通過Tensorflow代碼,實現MINIST手寫數字識別的過程。首先,如程序1所示,我們導入程序所需要的庫函數、數據集:
程序1:

import tensorflow as tf

from tensorflow.examples.tutorials.mnist import input_data

接下來,我們讀取MNIST數據集,并指定用one_hot的編碼方式;然后定義batch_size、batch_num兩個變量,分別代表一次性傳入神經網絡進行訓練的批次大小,以及計算出訓練的次數。如程序2所示:

程序2:

mnist_data=input_data.read_data_sets("MNIST.data",one_hot=True)

batch_size=100

batch_num=mnist_data.train.num_examples//batch_size

我們需要注意的是:在執行第一句命令時,就會從默認的地方下載MNIST數據集,下載下來的數據集會以壓縮包的形式存到指定目錄,如下圖所示。這些數據分別代表了訓練集、訓練集標簽、測試集、測試集標簽。

如何通過MNIST手寫數字識別分析神經網絡搭建

接著我們定義兩個placeholder,程序如下所示:

程序3:

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

y = tf.placeholder(tf.float32,[None,10])

其中,x代表訓練數據,y代表標簽。具體來看,我們會把訓練集中的圖片以batch_size批次大小,分批傳入到第一個參數中(默認為None);X的第二個參數代表把圖片轉換為長度為784的向量;Y的第二個參數表示10個不同的類標。

接下來我們就可以開始構建一個簡單的神經網絡了,首先定義各層的權重w和偏執b。如程序4所示:

程序4:

weights = {

    'hidden_1': tf.Variable(tf.random_normal([784, 256])),

    'out': tf.Variable(tf.random_normal([256, 10]))

}

biases = {

    'b1': tf.Variable(tf.random_normal([256])),

    'out': tf.Variable(tf.random_normal([10]))

}

因為我們準備搭建一個含有一個隱藏層結構的神經網絡(當然也可以搭建兩個或是多個隱層的神經網絡),所以先要設置其每層的w和b。如上程序所示,該隱藏層含有256個神經元。接著我們就可以開始搭建每一層神經網絡了:
程序5:

def neural_network(x):

    hidden_layer_1 = tf.add(tf.matmul(x, weights['hidden_1']), biases['b1'])

    out_layer = tf.matmul(hidden_layer_1, weights['out']) + biases['out']

    return out_layer

如程序5所示,我們定義了一個含有一個隱藏層神經網絡的函數neural_network,函數的返回值是輸出層的輸出結果。

接下來我們定義損失函數、優化器以及計算準確率的方法。

程序6:

#調用神經網絡

result = neural_network(x)

#預測類別

prediction = tf.nn.softmax(result)

#平方差損失函數

loss = tf.reduce_mean(tf.square(y-prediction))

#梯度下降法

train_step = tf.train.GradientDescentOptimizer(0.2).minimize(loss)

#預測類標

correct_pred = tf.equal(tf.argmax(y,1),tf.argmax(prediction,1))

#計算準確率

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

#初始化變量

init = tf.global_variables_initializer()

如程序6所示:首先使用softmax函數對結果進行預測,然后選擇平方差損失函數計算出loss,再使用梯度下降法的優化方法對loss進行最小化(梯度下降法的學習率設置為0.2)。接著使用argmax函數返回最大的值所在的位置,再使用equal函數與正確的類標進行比較,返回一個bool值,代表預測正確或錯誤的類標;最后使用cast函數把bool類型的預測結果轉換為float類型(True轉換為1,False轉換為0),并對所有預測結果統計求平均值,算出最后的準確率。要注意:最后一定不要忘了對程序中的所有變量進行初始化。

最后一步,我們啟動Tensorflow默認會話,執行上述過程。代碼如下所示:

程序7:

step_num=400

with tf.Session() as sess:

    sess.run(init)

    for step in range(step_num+1):

        for batch in range(batch_num):

            batch_x,batch_y =  mnist_data.train.next_batch(batch_size)

            sess.run(train_step,feed_dict={x:batch_x,y:batch_y})

        acc = sess.run(accuracy,feed_dict={x:mnist_data.test.images,y:mnist_data.test.labels})

        print("Step " + str(step) + ",Training Accuracy "+  "{:.3f}" + str(acc))

    print("Finished!")

上述程序定義了MNIST數據集的運行階段,首先我們定義迭代的周期數,往往開始的時候準確率會隨著迭代次數快速提高,但漸漸地隨著迭代次數的增加,準確率提升的幅度會越來越小。而對于每一輪的迭代過程,我們用不同批次的圖片進行訓練,每次訓練100張圖片,每次訓練的圖片數據和對應的標簽分別保存在 batch_x、batch_y中,接著再用run方法執行這個迭代過程,并使用feed_dict的字典結構填充每次的訓練數據。循環往復上述過程,直到最后一輪的訓練結束。

最后我們利用測試集的數據檢驗訓練的準確率,feed_dict填充的數據分別是測試集的圖片數據和測試集圖片對應的標簽。輸出結果迭代次數和準確率,完成訓練過程。我們截取400次的訓練結果,如下圖所示:

如何通過MNIST手寫數字識別分析神經網絡搭建

以上我們便完成了MNIST手寫數字識別模型的訓練,接下來可以從以下幾方面對模型進行改良和優化,以提高模型的準確率。

首先,在計算損失函數時,可以選擇交叉熵損失函數來代替平方差損失函數,通常在Tensorflow深度學習中,softmax_cross_entropy_with_logits函數會和softmax函數搭配使用,是因為交叉熵在面對多分類問題時,迭代過程中權值和偏置值的調整更加合理,模型收斂的速度更加快,訓練的的效果也更加好。代碼如下所示:

程序8:

#預測類別

prediction = tf.nn.softmax(result)

#交叉熵損失函數

loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y,logits=prediction))

#梯度下降法

train_step = tf.train.GradientDescentOptimizer(0.2).minimize(loss)

#預測類標

correct_pred = tf.equal(tf.argmax(y,1),tf.argmax(prediction,1))

#計算準確率

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

如程序8所示:我們把兩個參數:類標y以及模型的預測值prediction,傳入到交叉熵損失函數softmax_cross_entropy_with_logits中,然后對函數的輸出結果求平均值,再使用梯度下降法進行優化。最終的準確率如下圖所示:

如何通過MNIST手寫數字識別分析神經網絡搭建

我們可以明顯看到,使用交叉熵損失函數對于模型準確率的提高還是顯而易見的,訓練過程迭代200次的準確率已經超過了平方差損失函數迭代400次的準確率。

除了改變損失函數,我們還可以改變優化算法。例如使用adam優化算法代替隨機梯度下降法,因為它的收斂速度要比隨機梯度下降更快,這樣也能夠使準確率有所提高。如下程序所示,我們使用學習率為0.001的AdamOptimizer作為優化算法(其它部分不變):

程序9:

#Adam優化算法

train_step = tf.train.AdamOptimizer(1e-2).minimize(loss)

此外,如果你了解了過擬合的概念,那么很容易可以聯想到測試集準確率不高的原因,可能是因為訓練過程中發生了“過擬合”的現象。所以我們可以從防止過擬合的角度出發,提高模型的準確率。我們可以采用增加數據量或是增加正則化項的方式,來緩解過擬合。這里,我們為大家介紹dropout的方式是如何緩解過擬合的。

Dropout是在每次神經網絡的訓練過程中,使得部分神經元工作而另外一部分神經元不工作。而測試的時候激活所有神經元,用所有的神經元進行測試。這樣便可以有效的緩解過擬合,提高模型的準確率。具體代碼如下所示:

程序10:

def neural_network(x):

    hidden_layer_1 = tf.add(tf.matmul(x, weights['hidden_1']), biases['b1'])

    L1 = tf.nn.tanh(hidden_layer_1)

    dropout1 = tf.nn.dropout(L1,0.5)

    out_layer = tf.matmul(dropout1, weights['out']) + biases['out']

    return out_layer

如程序10所示,我們在隱藏層后接了dropout,隨機關掉50%的神經元,最后的測試結果如下圖所示,我們發現準確率取得了顯著的提高,在神經網絡結構中沒有添加卷積層和池化層的情況下,準確率達到了92%以上。 

如何通過MNIST手寫數字識別分析神經網絡搭建

上述內容就是如何通過MNIST手寫數字識別分析神經網絡搭建,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

广德县| 岗巴县| 盐山县| 朔州市| 岚皋县| 河曲县| 二手房| 扬州市| 阜宁县| 大丰市| 冕宁县| 蕉岭县| 驻马店市| 丰原市| 临朐县| 光泽县| 包头市| 黄石市| 扎囊县| 辛集市| 曲沃县| 郑州市| 阿拉尔市| 南平市| 河西区| 和林格尔县| 南溪县| 贵州省| 汽车| 囊谦县| 普安县| 民和| 三明市| 应用必备| 沽源县| 泸定县| 邻水| 五华县| 保德县| 醴陵市| 石柱|