入門| Tensorflow實戰講解神經網絡搭建詳細過程

2020-12-05 IT168

  【IT168 技術】之前我們講了神經網絡的起源、單層神經網絡、多層神經網絡的搭建過程、搭建時要注意到的具體問題、以及解決這些問題的具體方法。本文將通過一個經典的案例:MNIST手寫數字識別,以代碼的形式來為大家梳理一遍神經網絡的整個過程。

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

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

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

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

  此外,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數據集,下載下來的數據集會以壓縮包的形式存到指定目錄,如下圖所示。這些數據分別代表了訓練集、訓練集標籤、測試集、測試集標籤。

  接著我們定義兩個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手寫數字識別模型的訓練,接下來可以從以下幾方面對模型進行改良和優化,以提高模型的準確率。

  首先,在計算損失函數時,可以選擇交叉熵損失函數來代替平方差損失函數,通常在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中,然後對函數的輸出結果求平均值,再使用梯度下降法進行優化。最終的準確率如下圖所示:

  我們可以明顯看到,使用交叉熵損失函數對於模型準確率的提高還是顯而易見的,訓練過程迭代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%以上。

相關焦點

  • 深度學習筆記8:利用Tensorflow搭建神經網絡
    作者:魯偉 一個數據科學踐行者的學習日記。
  • Tensorflow 全網最全學習資料匯總之Tensorflow 的入門與安裝【2】
    值得一提的是,以上第二和第三篇分別來自兩個系列文章,這兩個系列也都是關於 TensorFlow 入門和實踐的優秀博客。第二篇的後續文章講述了卷積神經網絡(CNN)模型構建,以及利用 TensorFlow 生成詞向量 (Word Embedding) 的具體過程。
  • 最熱門的深度學習框架TensorFlow入門必備書籍
    眾多研究表明,Tensorflow 是研究深度學習的首選平臺。於是,很多開發者就問了,TensorFlow如此受歡迎,如果想入門學習它,要選擇哪本書呢?今天就和大家推薦一本TensorFlow入門書籍之《Tensorflow:實戰Google深度學習框架》在了解這本書之前,不妨先來了解一下什麼是TensorFlow,TensorFlow 是谷歌的第二代機器學習系統, 是一個採用數據流圖,用於數值計算的開源軟體庫
  • 【強化學習實戰】基於gym和tensorflow的強化學習算法實現
    1新智元推薦【新智元導讀】知乎專欄強化學習大講堂作者郭憲博士開講《強化學習從入門到進階》,我們為您節選了其中的第二節《基於gym和tensorflow的強化學習算法實現》,希望對您有所幫助。同時,由郭憲博士等擔任授課教師的深度強化學習國慶集訓營也將於 10 月 2 日— 6 日在北京舉辦。
  • 機器之心GitHub項目:從零開始用TensorFlow搭建卷積神經網絡
    機器之心基於 Ahmet Taspinar 的博文使用 TensorFlow 手動搭建卷積神經網絡,並提供所有代碼和注釋的 Jupyter Notebook 文檔。 機器之心項目地址:https://github.com/jiqizhixin/ML-Tutorial-Experiment 本文的重點是實現,並不會從理論和概念上詳細解釋深度神經網絡、卷積神經網絡、最優化方法等基本內容。
  • TensorFlow極速入門
    最後給出了在 tensorflow 中建立一個機器學習模型步驟,並用一個手寫數字識別的例子進行演示。1、tensorflow是什麼?tensorflow 是 google 開源的機器學習工具,在2015年11月其實現正式開源,開源協議Apache 2.0。
  • 作為TensorFlow的底層語言,你會用C++構建深度神經網絡嗎?
    隨著 C++ API 的完善,直接使用 C++來搭建神經網絡已經成為可能,本文將向你介紹一種簡單的實現方法。很多人都知道 TensorFlow 的核心是構建在 C++之上的,但是這種深度學習框架的大多數功能只在 Python API 上才方便使用。
  • TensorFlow 中文資源全集,學習路徑推薦
    入門教程,簡單的模型學習和運行。實戰項目,根據自己的需求進行開發。Mac:https://tensorflow.google.cn/install/install_macWindows:https://tensorflow.google.cn/install/install_windowsLinux:https://tensorflow.google.cn/install/install_linux入門教程官方入門教程
  • Keras入門系列教程:兩分鐘構建你的第一個神經網絡模型
    要開始使用tf.keras, 請將其作為TensorFlow程序的一部分導入:import tensorflow as tffrom tensorflow import kerastf.keras 可以運行任何與Keras兼容的代碼
  • 從框架優缺點說起,這是一份TensorFlow入門極簡教程
    谷歌今日上線基於 TensorFlow 的機器學習速成課程(中文版)機器之心 GitHub 項目:從零開始用 TensorFlow 搭建卷積神經網絡教程 | 從零開始:TensorFlow 機器學習模型快速部署指南分布式 TensorFlow 入坑指南:從實例到代碼帶你玩轉多機器深度學習三天速成!
  • Keras結合Keras後端搭建個性化神經網絡模型(不用原生Tensorflow)
    Keras是基於Tensorflow等底層張量處理庫的高級API庫。它幫我們實現了一系列經典的神經網絡層(全連接層、卷積層、循環層等),以及簡潔的迭代模型的接口,讓我們能在模型層面寫代碼,從而不用仔細考慮模型各層張量之間的數據流動。
  • 深度解讀TensorFlow,了解它的最新發展!
    TensorFlow.js 不僅可以提供低級的機器學習構建模塊,還可以提供高級的類似 Keras 的 API 來構建神經網絡。  TensorFlow其他應用  研發者還可以在TensorFlow上構建其他機器學習算法,例如決策樹或k-Nearest Neighbors。
  • TensorFlow官方推薦 國內首本教程:《TensorFlow實戰》預售(免費送書)
    代碼基於TensorFlow 1.0版API深度剖析如何用TensorFlow實現主流神經網絡:詳述TensorBoard、多GPU並行、分布式並行等組件的使用方法TF.Learn從入門到精通,TF.Contrib詳解Google近日發布了TensorFlow 1.0候選版,這第一個穩定版將是深度學習框架發展中的裡程碑的一步。
  • 初學AI神經網絡應該選擇Keras或是Pytorch框架?
    keras是神經網絡的一個模型計算框架,嚴格來說不是神經網絡框架。本身沒有重量級計算,它使用其他AI框架作為計算後臺,傻瓜式的使用。它的計算後臺還支持 Theano、CNTK(微軟的一個AI計算後臺)等,也就是說keras是多個計算後臺的門面。官方設計哲學為Simple. Flexible.
  • TensorFlow 2入門指南,初學者必備!
    Tensorflow v1難以使用和理解,因為它的Pythonic較少,但是隨著Keras發行的v2現在與Tensorflow.keras完全同步,它易於使用,易學且易於理解。如果要查看此數據集的詳細信息,可以使用  iris[ ['DESCR']。現在,我們必須導入其他重要的庫,這將有助於我們創建神經網絡。
  • 基於TensorFlow2.0的中文深度學習開源書來了!GitHub趨勢日榜第一
    主要介紹神經網絡的核心理論和共性知識,助於理解深度學習的本質。第四部分是10-15章。主要介紹常見的算法與模型。除此之外,每個章節裡的內容編排也是理論與實戰相結合。TensorFlow 2.0 實戰案例項目作者還介紹了TensorFlow 2.0的實戰案例。這個repo也是PoweredByTF 2.0 Challenge的獲勝項目。
  • TensorFlow 資源大全中文版
    ,請點擊 → 這裡了解詳情jtoy 發起整理的 TensorFlow 資源,包含一些很棒的 TensorFlow 工程、庫、項目等。TensorFlow實現神經圖靈機 – TensorFlow實現神經圖靈機基於物體搜索和過濾視頻 – 使用卷積神經網絡基於視頻中的物品、地點等來搜索、過濾和描述視頻使用TensorFlow來轉換莎士比亞作品和現代版本的英語 – 實現莎士比亞作品和現代版本的英語的單語轉換聊天機器人 – 一個基於深度學習的聊天機器人colornet – 使用神經網絡給灰度圖像著色
  • python應用之基於tensorflow的數據擬合:深度學習之預測入門篇
    實驗目的:1、了解python在深度學習領域的應用2、學習安裝python第三方依賴庫實驗環境:已正確安裝python3.5以及依賴庫tensorflow、matplotlib預測過程展示:1、應用領域python是一種高級面向對象的動態類型語言,具有開發高效,學習簡單的特點,主要應用於大數據、深度學習、
  • TensorFlow入門簡介,新手請看這裡!
    Tensor(張量)意味著N維數組,Flow(流)意味著基於數據流圖的計算,TensorFlow為張量從流圖的一端流動到另一端的計算過程。TensorFlow將複雜的數據結構傳輸至人工智慧神經網絡進行分析和處理。  2017年2月,TensorFlow 1.0版正式發布,其當年的提交數目就已超過2.1萬,其中還有部分外部貢獻者。
  • 谷歌開放GNMT教程:如何使用TensorFlow構建自己的神經機器翻譯系統
    第二部分將更進一步詳細地解釋如何構建帶注意力機制的強大神經機器翻譯模型。然後我們會討論構建更好神經機器翻譯模型(翻譯速度和質量)可能的技巧,例如 TensorFlow 最好的實踐方法(batching, bucketing)、雙向循環神經網絡和集束搜索等。基礎關於神經機器翻譯以詞組為基礎的傳統翻譯系統將源語言句子拆分成多個詞塊,然後進行詞對詞的翻譯。