在上個例子中,我們學會了如何建立神經網路,解決了預測房屋價格的問題。但是那個問題十分明確,房屋價格和房間房間數量之間的規則一目瞭然,並不能體現出機器學習的價值。
接下來,讓我們來看一個很難定義出來明確規則的例子,如影象識別。
在這個例子中,我們利用機器學習,識別影象的類別。
fashion-minist
這裡使用的資料集是fashion-minist,資料集包含60000條訓練資料和10000條測試資料,每條資料都是28*28的灰度影象,及對應的10種類別。
資料大概是長這個樣子的。
可以從這裡檢視詳細的資料。
編碼實現
在開始時,還是先引入tensorflow。
import tensorflow as tf
複製程式碼
fashion minist 資料可以使用tensorflow的API來讀取。
mnist = tf.keras.datasets.fashion_mnist
複製程式碼
呼叫minist.load_data函式,得到兩個資料集合,分別是訓練資料和測試資料,每個資料集合由影象資料和標籤組成。
(training_images, training_labels), (test_images, test_labels) = mnist.load_data()
複製程式碼
這個資料長的是什麼樣子呢?我們可以隨便找一個元素列印出來影象資料和標籤看下,這裡列印下第一個元素。
print("lable: ", training_labels[0])
print("image: ")
for line in training_images[0]:
s = ""
for v in line:
s = s + "%3d"%v + " "
print(s)
複製程式碼
我們注意到列印出來的值都是在0-255之間。如果我們要訓練神經網路,需要把這些值變為0-1之間,這個操作叫歸一化,把資料做歸一化會帶來很多好處。
利用python,我們很容易做歸一化操作
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(128, activation=tf.nn.relu),
tf.keras.layers.Dense(10, activation=tf.nn.softmax)])
複製程式碼
Sequential: 定義了神經網路的層序列。
Flatten:之前我們列印資料的時候,影象資料是二維的,Flatten只是將其變為一維資料。
Dense:向神經網路中新增一個層。
每一個層都需要activation function設定啟用函式,我們有很多種啟用函式可以選擇,這裡用的是Relu和Softmax。
Relu:作用相當於if (X>0) return X; else return 0;
,所以做的事情就是把0(X<=0時)或X(X>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]。它幫我們實現來選取最大值的編碼工作,能節省大量的程式碼。
現在我們已經定義好來模型,接下來就是要訓練模型了。我們先編譯模型,編譯時需指定優化函式和損失函式。然後呼叫model.fit
訓練模型,使訓練資料能夠匹配到對應的標籤,也就是找到訓練資料和對應標籤之間的關係,這樣若有新的和訓練資料相像的資料,模型就能預測這種資料的標籤了。
model.compile(optimizer = tf.train.AdamOptimizer(),
loss = 'sparse_categorical_crossentropy',
metrics=['accuracy'])
model.fit(training_images, training_labels, epochs=5)
複製程式碼
當訓練完成後,我們可以看到模型的acc,就是0.8914這個數字。這個數字的含義是,我們的模型預測訓練資料時,有89%的資料是準確的。這個指標不算好,但是考慮到我們只訓練了5個epoch,且很快完成了訓練,這個結果也是不錯的了。
但是我們的模型在未見過的資料中表現如何呢?這就是上面的測試資料的用處了。我們可以呼叫model.evalute
,把測試資料和標籤傳過去,就能看到其在測試資料上的表現了。
model.evaluate(test_images, test_labels)
複製程式碼
可以看到acc是0.8745,意味著有87%的準確率,沒有在訓練資料中的表現好,這也是符合預期的。
你後面可以嘗試用一些別的方法,來提高準確率。