TensorFlow 基礎 - 3 卷積神經網絡



這種技術文檔,花的時間是最多的,但是看的人是最少的。反而那些標題黨和心靈雞湯的是最多的,浮躁,不瞞你說,看來我們是一路人,迷茫、浮躁。


卷積神經網絡

抓住它的核心思路,即通過卷積操作縮小了圖像的內容,將模型注意力集中在圖像特定的、明顯的特徵上。

max pooling - 增強特徵,減少數據

實現

在下面的代碼中模型在訓練數據上的精度可能上升到93%左右,在驗證數據上可能上升到91%。

這是朝着正確方向取得的顯著進步!

試着運行更多的epochs--比如20個epochs,然後觀察結果! 雖然結果可能看起來非常好,但實際上驗證結果可能會下降,這是因爲"過擬合"造成的,後面將會討論。

(簡而言之,'過擬合'發生在網絡模型從訓練集中學習到的結果非常好,但它太狹隘了,只能識別訓練數據,而在看到其他數據時效果不佳。舉個例子,如果我們一輩子只看到紅色的鞋子,那麼當我們看到一雙藍色的麂皮鞋可能會感到迷惑......再舉一例,應試教育往往使得學生只對做過的題目有很好的正確率,但對真實的問題卻錯誤率很高)

import tensorflow as tf
print(tf.__version__)
mnist = tf.keras.datasets.fashion_mnist
(training_images, training_labels), (test_images, test_labels) = mnist.load_data()
training_images=training_images.reshape(6000028281)
training_images=training_images / 255.0
test_images = test_images.reshape(1000028281)
test_images=test_images/255.0
model = tf.keras.models.Sequential([
  tf.keras.layers.Conv2D(64, (3,3), activation='relu', input_shape=(28281)),
  tf.keras.layers.MaxPooling2D(22),
  tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
  tf.keras.layers.MaxPooling2D(2,2),
  tf.keras.layers.Flatten(),
  tf.keras.layers.Dense(128, activation='relu'),
  tf.keras.layers.Dense(10, activation='softmax')
])
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.summary()
model.fit(training_images, training_labels, epochs=5)
test_loss = model.evaluate(test_images, test_labels)

卷積模型是如何建立的

第一步是收集數據。我們會注意到,這裏和之前有一點變化,訓練數據需要改變維度(shape)。這是因爲第一次卷積期望一個包含所有數據的單一張量,所以要把訓練數據設置爲60000x28x28x1的一個4D列表,測試圖像也是如此處理。如果不這樣做,會在訓練時得到一個錯誤,因爲卷積操作將不能識別數據形狀。

接下來是定義模型。首先要添加一個卷積層。參數是

  • 我們想要生成的卷積數( 過濾器數量)。這個數值是任意的, 但最好是從32開始的倍數
  • 卷積的大小( 過濾器的大小),在本例中爲3x3網格。這是最常用的尺寸。
  • 要使用的激活函數 -- 在本例中,我們將使用relu,我們可能還記得它相當於當x>0時返回x,否則返回0。
  • 在第一層,設定輸入數據的形狀

在卷積層之後加上一個MaxPooling層,用來壓縮圖像,同時保持卷積所強調的特徵內容。通過爲MaxPooling指定(2,2),效果是將圖像的大小縮小四分之一。它的想法是創建一個2x2的像素數組,然後選取最大的一個,從而將4個像素變成1個,在整個圖像中重複這樣做,這樣做的結果是將水平像素的數量減半,垂直像素的數量減半,有效地將圖像縮小25%

再增加一個卷積層和MaxPooling2D。

現在對輸出進行扁平化處理。在這之後,你將擁有與非卷積版本相同的DNN結構,即全連接神經元網絡。

含有128個神經元的全連接層,以及10個神經元的輸出層。

現在編譯模型,調用model.fit方法做訓練,接着用測試集評估損失和準確率。

網絡結構

看看可否只使用單個卷積層和單個MaxPooling 2D將MNIST(手寫數字)識別率提高到99.8%或更高的準確率。一旦準確率超過這個數值,應該停止訓練。Epochs不應超過20個。如果epochs達到20但精度未達到要求,那麼就需要重新設計層結構。當達到99.8%的準確率時,你應該打印出 "達到99.8%準確率,所以取消訓練!"的字符串。

import tensorflow as tf
from tensorflow import keras

## overwrite callback

class Callbacks(tf.keras.callbacks.Callback):
  def on_epoch_end(self, epoch, logs={}):
    if(logs.get('accuracy')>=0.998):
      print("達到99.8%準確率,所以取消訓練!")
      self.model.stop_training = True

callbacks = Callbacks()

## 準備數據
mnist = tf.keras.datasets.mnist
(training_images, training_labels), (test_images, test_labels) = mnist.load_data()

## 歸一化
training_images = training_images.reshape(6000028281)
training_images = training_images / 255.0

test_images = test_images.reshape(1000028281)
test_images  = test_images / 255.0

## 建立模型
model = tf.keras.models.Sequential([
   tf.keras.layers.Conv2D(64, (3,3), activation='relu', input_shape=(28281)),
   tf.keras.layers.MaxPooling2D(22),
  #  tf.keras.layers.Conv2D(62, (3, 3), activation='relu'),
  #  tf.keras.layers.MaxPooling2D(2,2),

   tf.keras.layers.Flatten(), ##扁平化
   tf.keras.layers.Dense(128, activation='relu'),
   tf.keras.layers.Dense(10, activation='softmax')
])


## 訓練
model.compile(optimizer=tf.keras.optimizers.Adam(), 
              loss=tf.keras.losses.SparseCategoricalCrossentropy(),
              metrics=['accuracy'])
model.summary()
model.fit(training_images, training_labels, epochs=4, callbacks=[callbacks])

## 預測和評估

test_loss = model.evaluate(test_images, test_labels)

結果


本文分享自微信公衆號 - 程序員匯聚地(chasays)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章