使用 TensorFlow 建構電腦視覺模型

1. 事前準備

在這個程式碼研究室中,您將建立電腦視覺模型,以透過 TensorFlow 辨識衣物。

事前準備

  • Python 的穩固知識
  • 基本程式設計技巧

您將會瞭解的內容

本程式碼研究室將:

  • 訓練類神經網路來辨識衣服的文章
  • 完成一系列練習,引導您測試不同的網路層

建構項目

  • 可辨識服飾的類神經網路

軟硬體需求

若您從未使用 TensorFlow 建立電腦視覺的類神經網路,則可以使用以 Colaboratory 為基礎的環境,該環境包含所有必要依附元件。您可以找到在 Colab 中執行的其他程式碼研究室程式碼。

否則,您將用於訓練訓練模型的主要語言為 Python,因此您必須安裝這個語言。除此之外,您還需要 TensorFlow 和 NumPy 程式庫。您可以前往這個網頁,進一步瞭解及安裝 TensorFlow。在這裡安裝 NumPy。

2. 開始編寫程式碼

首先,請逐步瀏覽執行中的 Colab 筆記本

首先,請匯入 TensorFlow。

import tensorflow as tf
print(tf.__version__)

您訓練了一個類神經網路來辨識常見資料集 (名為「時尚 MNIST」),它包含 10 個不同類型的 70,000 件衣服。每件衣物都是以 28x28 的灰階圖片呈現。請看以下幾個範例:

與資料集相關聯的標籤如下:

標籤

Description

0

T 恤/上衣

1

褲子

2

靠邊停車

3

洋裝

4

外套

5

涼鞋

6

Shirt

7

運動鞋

8

包包

9

腳踝靴

時尚 MNIST 資料適用於 tf.keras.datasets API。如下所示載入:

mnist = tf.keras.datasets.fashion_mnist

對該物件呼叫 load_data 會顯示兩組清單:training 值和 testing 值,表示顯示服飾物品及其標籤的圖形。

(training_images, training_labels), (test_images, test_labels) = mnist.load_data()

這些值是什麼樣子?列印訓練圖片和訓練標籤以查看。您可以對陣列中的不同索引進行實驗。

import matplotlib.pyplot as plt
plt.imshow(training_images[0])
print(training_labels[0])
print(training_images[0])

項目 0 的資料列印方式如下:

您注意到,所有的值都是介於 0 和 255 之間的整數。訓練類神經網路時,您可以更輕鬆地處理所有值,介於 0 和 1 之間 (這個程序稱為「正規化」)。幸好,Python 可讓您輕鬆地將這類清單正規化,而不會循環播放。

training_images  = training_images / 255.0
test_images = test_images / 255.0

您可能也會想查看 42,這與索引 0 的啟動方式不同。

您或許會想知道為何提供訓練和測試兩個資料集。

提案是取得一組用於訓練的一組資料,以及一組尚未取得模型的資料,以便瞭解模型分類值的成效。完成所有事情後,你想把模型和從未見過的資料一起使用!除此之外,如果沒有獨立測試資料,您就「無法」在不影響「一般」知識的情況下,自行調整訓練資料。

3. 設計模型

現在,請設計模型。您會有三個層。逐一瀏覽各個圖層,並探索各個圖層類型及適用的參數。

model = tf.keras.models.Sequential([tf.keras.layers.Flatten(), 
                                    tf.keras.layers.Dense(128, activation=tf.nn.relu), 
                                    tf.keras.layers.Dense(10, activation=tf.nn.softmax)])
  • Sequential 可定義類神經網路中的圖層序列。
  • Flatten 將正方形轉換成單維向量。
  • Dense 加上一層神經元。
  • Activation 函式會告知各個神經元的執行方法。有很多選擇,但目前請採用以下方法:
  • Relu 有效表示,如果 X 大於 0,則傳回 0,否則傳回 0。只會將 0 以上的值傳送到網路中的下一層。
  • Softmax」採用一組值,因此可有效挑選出最大的值。例如,如果最後一個層的輸出看似像 [0.1, 0.1, 0.05, 0.1, 9.5, 0.1, 0.05, 0.05, 0.05],那後它可以避免您必須排序最大值——它返回 [0,0,0,0,1,0,0,0,0]。

4. 編譯及訓練模型

現在已經定義了模型,下一步就是建立模型。先使用 optimizerloss 函式編譯模型,然後用訓練資料和標籤進行訓練。目標是讓模型決定訓練資料與訓練標籤之間的關係。之後,您希望模型檢視的資料與訓練資料類似,然後預測這些資料的樣貌。

請注意,使用 metrics= 做為參數,讓 TensorFlow 根據預測結果 (預測標籤) 比對預測結果,來回報訓練的準確度。

model.compile(optimizer = tf.keras.optimizers.Adam(),
              loss = 'sparse_categorical_crossentropy',
              metrics=['accuracy'])

model.fit(training_images, training_labels, epochs=5)

model.fit 執行時,您會看到損失以及準確度:

Epoch 1/5
60000/60000 [=======] - 6s 101us/sample - loss: 0.4964 - acc: 0.8247
Epoch 2/5
60000/60000 [=======] - 5s 86us/sample - loss: 0.3720 - acc: 0.8656
Epoch 3/5
60000/60000 [=======] - 5s 85us/sample - loss: 0.3335 - acc: 0.8780
Epoch 4/5
60000/60000 [=======] - 6s 103us/sample - loss: 0.3134 - acc: 0.8844
Epoch 5/5
60000/60000 [=======] - 6s 94us/sample - loss: 0.2931 - acc: 0.8926

模型訓練完成後,您會在最後訓練週期結束時看到準確率值。看起來像是 0.8926 之類的。如此一來,您的類神經網路分類資料時,準確度約可達到 89%。換句話說,它會找出圖片與 89% 時間的標籤一致,不好,但這只是不行,因為這款應用程式只經過五次訓練和快速完成。

5. 測試模型

模型在未偵測到的資料上會有什麼變化?這就是為什麼您擁有測試集的原因。您呼叫了 model.evaluate 並傳入兩組,因此會回報每組的損失。試試看:

model.evaluate(test_images, test_labels)

以下是輸出內容:

10000/10000 [=====] - 1s 56us/sample - loss: 0.3365 - acc: 0.8789
[0.33648381242752073, 0.8789]

這個範例傳回的準確率為 0.8789,亦即約為 88%。(您的值可能略有不同)。

與預期結果相比,模型跟不明資料相比不準確,因此模型的訓練結果不如預期!深入瞭解 TensorFlow 之後,你也會發現改善方法。

如要進行探索,請進行下一個步驟的練習。

6. 探索練習

運動 1

第一次練習時,請執行下列指令:

classifications = model.predict(test_images)
print(classifications[0])

系統會為每個測試圖片建立一組分類,然後列印分類中的第一個項目。執行之後的輸出結果為數字清單。原因為何?這些數字代表的意義為何?

請嘗試執行 print(test_labels[0]),即可獲得 9 分。這有助您瞭解清單的外觀。

模型的輸出結果為 10 個數字的清單。這些數字是指分類值為對應的標籤。例如,清單中的第一個值是服飾類別為 0 的機率,下一個值為 1。請注意,除了這兩者之外,這些因素都非常低。此外,由於 Softmax,清單中的所有機率加總為 1.0。

列表和標籤基於 0,因此具有標籤 9 的腳軸靴意味於它是 10 類中的第 10 個。清單中列出的第 10 個元素,表示類神經網路預測該分類的項目很可能是腳踝靴。

運動 2

查看模型中的圖層。使用 512 種神經元來測試密集層的不同值。

損失和訓練時間分別有什麼不同?原因為何?

例如,如果您增加到 1,024 個神經元,您必須執行更多計算,減慢進程。但在這個情況下,由於模型的準確度較高,因此能夠產生良好的影響。這並不代表多變了。您能迅速處理退貨的法律。

運動 3

移除 Flatten() 圖層會有什麼影響。原因為何?

您將收到有關資料形狀的錯誤。目前錯誤的詳細資訊可能並不明確,但這項規定可強化您網路中第一層的形狀,與資料相同。現在,您的數據是 28x28 的圖像,28 層 28 個神經元是不可行的,因此把 28,28 平整到 784x1 是更有意義的。

與其加入所有程式碼,請改為在開頭加入 Flatten() 層。稍後,當陣列載入陣列時,陣列就會自動縮小。

運動 4

請思考最後一個 (輸出) 層。為什麼會有 10 種?要是您的付款金額不同於 10,會有什麼影響?

試著使用 5 網路進行訓練。如果發現非預期的值,就會立即發生錯誤。原則上,最後一個圖層中的神經元數量應與您要分類的類別數量相符。在上面的情況下,它是 0 到 9 的數字,因此其中有 10 個,因此您最後一個層中應為 10 個神經元。

運動 5

請仔細考慮網路中其他圖層的影響。如果在 512 的另一層和 10 的最後一個層之間添加另一層呢?

由於資料相當簡單,因此影響力不大。對於較為複雜的資料,通常需要額外的圖層。

運動 6

在訓練之前,您將數據化正常化,從 0 到 255 的值到 0 到 1 的值。移除網址會造成什麼影響?這裡是完整的程式碼,值得試試 (注意,為資料正規化的兩行加上註解)。

你為什麼覺得結果不同?你在 Stack Overflow 上有一個很棒的答案。

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/255.0
#test_images=test_images/255.0
model = tf.keras.models.Sequential([
  tf.keras.layers.Flatten(),
  tf.keras.layers.Dense(512, activation=tf.nn.relu),
  tf.keras.layers.Dense(10, activation=tf.nn.softmax)
])
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy')
model.fit(training_images, training_labels, epochs=5)
model.evaluate(test_images, test_labels)
classifications = model.predict(test_images)
print(classifications[0])
print(test_labels[0])

7. 探索回呼

您之前,當您訓練其他訓練週期時,您的問題可能會遺失。您可能需要等待一段時間等待訓練完成,而且您可能認為如果在達到所需的值時停止訓練,例如 95% 的準確率,這將會是很好的事情。如果您在 3 個訓練週期後達到這個目標,為何必須等待它完成更多訓練週期呢?

和任何其他計畫一樣,您有回呼!瞭解實際運作方式:

import tensorflow as tf

class myCallback(tf.keras.callbacks.Callback):
  def on_epoch_end(self, epoch, logs={}):
    if(logs.get('accuracy')>0.95):
      print("\nReached 95% accuracy so cancelling training!")
      self.model.stop_training = True

callbacks = myCallback()
mnist = tf.keras.datasets.fashion_mnist
(training_images, training_labels), (test_images, test_labels) = mnist.load_data()
training_images=training_images/255.0
test_images=test_images/255.0
model = tf.keras.models.Sequential([
  tf.keras.layers.Flatten(),
  tf.keras.layers.Dense(512, activation=tf.nn.relu),
  tf.keras.layers.Dense(10, activation=tf.nn.softmax)
])
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.fit(training_images, training_labels, epochs=5, callbacks=[callbacks])

8. 恭喜

您已建立第一個電腦視覺模型!想瞭解如何強化電腦視覺模型,請參閱建立卷積和執行集區