開(kāi)始使用tensorflow
原文地址
訓(xùn)練首個(gè)神經(jīng)網(wǎng)絡(luò):基本分類(lèi)
對(duì)于初學(xué)者,即使不了細(xì)節(jié)也沒(méi)關(guān)系,本次教程只是簡(jiǎn)要介紹一個(gè)完整的Tensorflow程序,而且后續(xù)我們會(huì)詳細(xì)介紹。
本次使用的是tf.eras,它是一種用于在Tensorflow中構(gòu)建和訓(xùn)練模型的高階API
#Tensorflow and tf.keras
import tensorflow as tf
from tensorflow import keras
#相關(guān)庫(kù)
import numpy as np
import matplotlib.pyplot as plt
print(tf.__version__)
輸出:
1.12.0-rc1
導(dǎo)入Fashion MNIST 數(shù)據(jù)集
本次指南使用 Fashion MNIST

其中包含 70000 張灰度圖像,涵蓋 10 個(gè)類(lèi)別。我們將使用 60000 張圖像訓(xùn)練網(wǎng)絡(luò),并使用 10000 張圖像評(píng)估經(jīng)過(guò)學(xué)習(xí)的網(wǎng)絡(luò)分類(lèi)圖像的準(zhǔn)確率。您可以從 TensorFlow 直接訪問(wèn) Fashion MNIST,只需導(dǎo)入和加載數(shù)據(jù)即可:
fashion_mnist = keras.datasets.fashion_mnist
(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
加載數(shù)據(jù)集會(huì)返回 4 個(gè) NumPy 數(shù)組:
- train_images 和 train_labels 數(shù)組是訓(xùn)練集,即模型用于學(xué)習(xí)的數(shù)據(jù)。
- 測(cè)試集 test_images 和 test_labels 數(shù)組用于測(cè)試模型。
圖像為 28x28 的 NumPy 數(shù)組,像素值介于 0 到 255 之間。標(biāo)簽是整數(shù)數(shù)組,介于 0 到 9 之間。這些標(biāo)簽對(duì)應(yīng)于圖像代表的服飾所屬的類(lèi)別:

每張圖像都映射到一個(gè)標(biāo)簽。由于數(shù)據(jù)集中不包含類(lèi)別名稱(chēng),因此將它們存儲(chǔ)在此處,以便稍后在繪制圖像表時(shí)使用:
class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat','Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
預(yù)處理數(shù)據(jù)
必須先對(duì)數(shù)據(jù)進(jìn)行預(yù)處理,然后再訓(xùn)練網(wǎng)絡(luò)。如果您檢查訓(xùn)練集中的第一張圖像,就會(huì)發(fā)現(xiàn)像素值介于 0 到 255 之間:
plt.figure()
plt.imshow(train_images[0])
plt.colorbar()
plt.grid(False)

我們將這些值縮小到 0 到 1 之間,然后將其饋送到神經(jīng)網(wǎng)絡(luò)模型。為此,將圖像組件的數(shù)據(jù)類(lèi)型從整數(shù)轉(zhuǎn)換為浮點(diǎn)數(shù),然后除以 255。以下是預(yù)處理圖像的函數(shù),
務(wù)必要以相同的方式對(duì)訓(xùn)練集和測(cè)試集進(jìn)行預(yù)處理:
train_images = train_images / 255.0
test_images = test_images / 255.0
顯示訓(xùn)練集中的前 25 張圖像,并在每張圖像下顯示類(lèi)別名稱(chēng)。驗(yàn)證確保數(shù)據(jù)格式正確無(wú)誤,然后我們就可以開(kāi)始構(gòu)建和訓(xùn)練網(wǎng)絡(luò)了。
plt.figure(figsize=(10,10))
for i in range(25):
plt.subplot(5,5,i+1)
plt.xticks([])
plt.yticks([])
plt.grid(False)
plt.imshow(train_images[i], cmap=plt.cm.binary)
plt.xlabel(class_names[train_labels[i]])

構(gòu)建模型
構(gòu)建神經(jīng)網(wǎng)絡(luò)需要先配置模型的層,然后再編譯模型。
設(shè)置層
神經(jīng)網(wǎng)絡(luò)的基本構(gòu)造塊是層。層從饋送到其中的數(shù)據(jù)中提取表示結(jié)果。希望這些表示結(jié)果有助于解決手頭問(wèn)題。
大部分深度學(xué)習(xí)都會(huì)把簡(jiǎn)單的層連在一起。大部分層(例如 tf.keras.layers.Dense)都具有在訓(xùn)練期間要學(xué)習(xí)的參數(shù)。
model = keras.Sequential([
keras.layers.Flatten(input_shape=(28, 28)),
keras.layers.Dense(128, activation=tf.nn.relu),
keras.layers.Dense(10, activation=tf.nn.softmax)
])
該網(wǎng)絡(luò)中的第一層 tf.keras.layers.Flatten 將圖像格式從二維數(shù)組(28x28 像素)轉(zhuǎn)換成一維數(shù)組(28 * 28 = 784 像素)??梢詫⒃搶右暈閳D像中像素未堆疊的行,并排列這些行。該層沒(méi)有要學(xué)習(xí)的參數(shù);它只改動(dòng)數(shù)據(jù)的格式。
在扁平化像素之后,該網(wǎng)絡(luò)包含兩個(gè) tf.keras.layers.Dense 層的序列。這些層是密集連接或全連接神經(jīng)層。第一個(gè) Dense 層具有 128 個(gè)節(jié)點(diǎn)(或神經(jīng)元)。第二個(gè)(也是最后一個(gè))層是具有 10 個(gè)節(jié)點(diǎn)的 softmax 層,該層會(huì)返回一個(gè)具有 10 個(gè)概率得分的數(shù)組,這些得分的總和為 1。每個(gè)節(jié)點(diǎn)包含一個(gè)得分,表示當(dāng)前圖像屬于 10 個(gè)類(lèi)別中某一個(gè)的概率。
編譯模型
模型還需要再進(jìn)行幾項(xiàng)設(shè)置才可以開(kāi)始訓(xùn)練。這些設(shè)置會(huì)添加到模型的編譯步驟:
損失函數(shù) - 衡量模型在訓(xùn)練期間的準(zhǔn)確率。我們希望盡可能縮小該函數(shù),以“引導(dǎo)”模型朝著正確的方向優(yōu)化。
優(yōu)化器 - 根據(jù)模型看到的數(shù)據(jù)及其損失函數(shù)更新模型的方式。
指標(biāo) - 用于監(jiān)控訓(xùn)練和測(cè)試步驟。以下示例使用準(zhǔn)確率,即圖像被正確分類(lèi)的比例。
model.compile(optimizer=tf.train.AdamOptimizer(),
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
訓(xùn)練模型
訓(xùn)練神經(jīng)網(wǎng)絡(luò)模型需要執(zhí)行以下步驟:
1.將訓(xùn)練數(shù)據(jù)饋送到模型中,在本示例中為 train_images 和 train_labels 數(shù)組。
2.模型學(xué)習(xí)將圖像與標(biāo)簽相關(guān)聯(lián)。
3.我們要求模型對(duì)測(cè)試集進(jìn)行預(yù)測(cè),在本示例中為 test_images 數(shù)組。我們會(huì)驗(yàn)證預(yù)測(cè)結(jié)果是否與 test_labels 數(shù)組中的標(biāo)簽一致。
要開(kāi)始訓(xùn)練,請(qǐng)調(diào)用 model.fit 方法,使模型與訓(xùn)練數(shù)據(jù)“擬合”:
model.fit(train_images, train_labels, epochs=5)
Epoch 1/5
60000/60000 [==============================] - 5s 87us/step - loss: 0.5033 - acc: 0.8242
Epoch 2/5
60000/60000 [==============================] - 5s 80us/step - loss: 0.3803 - acc: 0.8643
Epoch 3/5
60000/60000 [==============================] - 5s 85us/step - loss: 0.3399 - acc: 0.8758
Epoch 4/5
60000/60000 [==============================] - 5s 87us/step - loss: 0.3141 - acc: 0.8855
Epoch 5/5
60000/60000 [==============================] - 5s 88us/step - loss: 0.2941 - acc: 0.8917
在模型訓(xùn)練期間,系統(tǒng)會(huì)顯示損失和準(zhǔn)確率指標(biāo)。該模型在訓(xùn)練數(shù)據(jù)上的準(zhǔn)確率達(dá)到 0.88(即 88%)。
評(píng)估準(zhǔn)確率
test_loss, test_acc = model.evaluate(test_images, test_labels)
print('Test accuracy:', test_acc)
10000/10000 [==============================] - 1s 50us/step
Test accuracy: 0.8734
結(jié)果表明,模型在測(cè)試數(shù)據(jù)集上的準(zhǔn)確率略低于在訓(xùn)練數(shù)據(jù)集上的準(zhǔn)確率。訓(xùn)練準(zhǔn)確率和測(cè)試準(zhǔn)確率之間的這種差異表示出現(xiàn)過(guò)擬合。如果機(jī)器學(xué)習(xí)模型在新數(shù)據(jù)上的表現(xiàn)不如在訓(xùn)練數(shù)據(jù)上的表現(xiàn),就表示出現(xiàn)過(guò)擬合。
做出預(yù)測(cè)
模型經(jīng)過(guò)訓(xùn)練后,我們可以使用它對(duì)一些圖像進(jìn)行預(yù)測(cè)。
predictions = model.predict(test_images)
在本示例中,模型已經(jīng)預(yù)測(cè)了測(cè)試集中每張圖像的標(biāo)簽。我們來(lái)看看第一個(gè)預(yù)測(cè):
predictions[0]
array([4.2577299e-06, 7.2840301e-08, 2.3979945e-08, 2.0671453e-06,
9.1094840e-08, 1.2096325e-01, 1.5182156e-06, 1.9717012e-01,
1.2066002e-05, 6.8184656e-01], dtype=float32)
預(yù)測(cè)結(jié)果是一個(gè)具有 10 個(gè)數(shù)字的數(shù)組。這些數(shù)字說(shuō)明模型對(duì)于圖像對(duì)應(yīng)于 10 種不同服飾中每一個(gè)服飾的“置信度”。我們可以看到哪個(gè)標(biāo)簽的置信度值最大:
np.argmax(predictions[0])
9
因此,模型非常確信這張圖像是踝靴或?qū)儆?class_names[9]。我們可以檢查測(cè)試標(biāo)簽以查看該預(yù)測(cè)是否正確:
test_labels[0]
9
我們可以將該預(yù)測(cè)繪制成圖來(lái)查看全部 10 個(gè)通道
def plot_image(i, predictions_array, true_label, img):
predictions_array, true_label, img = predictions_array[i], true_label[i], img[i]
plt.grid(False)
plt.xticks([])
plt.yticks([])
plt.imshow(img, cmap=plt.cm.binary)
predicted_label = np.argmax(predictions_array)
if predicted_label == true_label:
color = 'blue'
else:
color = 'red'
plt.xlabel("{} {:2.0f}% ({})".format(class_names[predicted_label],
100*np.max(predictions_array),
class_names[true_label]),
color=color)
def plot_value_array(i, predictions_array, true_label):
predictions_array, true_label = predictions_array[i], true_label[i]
plt.grid(False)
plt.xticks([])
plt.yticks([])
thisplot = plt.bar(range(10), predictions_array, color="#777777")
plt.ylim([0, 1])
predicted_label = np.argmax(predictions_array)
thisplot[predicted_label].set_color('red')
thisplot[true_label].set_color('blue')
我們來(lái)看看第 0 張圖像、預(yù)測(cè)和預(yù)測(cè)數(shù)組。
i = 0
plt.figure(figsize=(6,3))
plt.subplot(1,2,1)
plot_image(i, predictions, test_labels, test_images)
plt.subplot(1,2,2)
plot_value_array(i, predictions, test_labels)

i = 12
plt.figure(figsize=(6,3))
plt.subplot(1,2,1)
plot_image(i, predictions, test_labels, test_images)
plt.subplot(1,2,2)
plot_value_array(i, predictions, test_labels)

我們用它們的預(yù)測(cè)繪制幾張圖像。正確的預(yù)測(cè)標(biāo)簽為藍(lán)色,錯(cuò)誤的預(yù)測(cè)標(biāo)簽為紅色。數(shù)字表示預(yù)測(cè)標(biāo)簽的百分比(總計(jì)為 100)。請(qǐng)注意,即使置信度非常高,也有可能預(yù)測(cè)錯(cuò)誤。
# Plot the first X test images, their predicted label, and the true label
# Color correct predictions in blue, incorrect predictions in red
num_rows = 5
num_cols = 3
num_images = num_rows*num_cols
plt.figure(figsize=(2*2*num_cols, 2*num_rows))
for i in range(num_images):
plt.subplot(num_rows, 2*num_cols, 2*i+1)
plot_image(i, predictions, test_labels, test_images)
plt.subplot(num_rows, 2*num_cols, 2*i+2)
plot_value_array(i, predictions, test_labels)

最后,使用經(jīng)過(guò)訓(xùn)練的模型對(duì)單個(gè)圖像進(jìn)行預(yù)測(cè)。
# Grab an image from the test dataset
img = test_images[0]
print(img.shape)
(28,28)
tf.keras 模型已經(jīng)過(guò)優(yōu)化,可以一次性對(duì)樣本批次或樣本集進(jìn)行預(yù)測(cè)。因此,即使我們使用單個(gè)圖像,仍需要將其添加到列表中:
# Add the image to a batch where it's the only member.
img = (np.expand_dims(img,0))
print(img.shape)
(1, 28, 28)
現(xiàn)在,預(yù)測(cè)這張圖像:
predictions_single = model.predict(img)
print(predictions_single)
[[4.25773487e-06 7.28401730e-08 2.39799487e-08 2.06714572e-06
9.10946838e-08 1.20963275e-01 1.51821587e-06 1.97170004e-01
1.20659797e-05 6.81846678e-01]]
plot_value_array(0, predictions_single, test_labels)
_ = plt.xticks(range(10), class_names, rotation=45)

model.predict 返回一組列表,每個(gè)列表對(duì)應(yīng)批次數(shù)據(jù)中的每張圖像。(僅)獲取批次數(shù)據(jù)中相應(yīng)圖像的預(yù)測(cè)結(jié)果:
np.argmax(predictions_single[0])
9
和剛才一樣,模型預(yù)測(cè)的標(biāo)簽為 9。