程式碼研究室簡介
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. 編譯及訓練模型
現在已經定義了模型,下一步就是建立模型。先使用 optimizer
和 loss
函式編譯模型,然後用訓練資料和標籤進行訓練。目標是讓模型決定訓練資料與訓練標籤之間的關係。之後,您希望模型檢視的資料與訓練資料類似,然後預測這些資料的樣貌。
請注意,使用 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])