這段時間在學習TensorFlow,這些都是一些官網上的例子,在這裡和大家分享記錄一下。

本指南訓練神經網路模型,對運動鞋和襯衫等服裝影象進行分類。如果您不瞭解所有細節,這是可以的,這是一個完整的TensorFlow程式的快節奏概述,詳細解釋了我們的細節。

本指南使用tf.keras,一個高階API,用於在TensorFlow中構建和訓練模型。

一、匯入庫

主要使用的3個庫:

# TensorFlow and tf.keras
import tensorflow as tf
from tensorflow import keras

# Helper libraries
import numpy as np
import matplotlib.pyplot as plt

匯入Fashion MNIST資料集

本指南使用Fashion MNIST資料集,其中包含10個類別中的70,000個灰度影象。影象顯示了低解析度(28 x 28畫素)的單件服裝,如下所示:
圖1. Fashion-MNIST樣本(由Zalando,麻省理工學院許可證)。

Fashion-MNIST旨在作為經典MNIST資料集的直接替代品- 通常用作計算機視覺機器學習計劃的“Hello,World”。MNIST資料集包含手寫數字(0,1,2等)的影象,其格式與我們在此處使用的服裝相同。

本指南使用Fashion MNIST進行多樣化,因為它比普通的MNIST更具挑戰性。兩個資料集都相對較小,用於驗證演算法是否按預期工作。它們是測試和除錯程式碼的良好起點。

我們將使用60,000個影象來訓練網路和10,000個影象,以評估網路學習對影象進行分類的準確程度。您可以直接從TensorFlow訪問Fashion MNIST,只需匯入並載入資料:

fashion_mnist = keras.datasets.fashion_mnist
(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()

載入資料集將返回四個NumPy陣列:

  • 在train_images和train_labels陣列的訓練集模型使用學習-The資料。
    針對測試集,陣列test_images和test_labels陣列測試模型。
  • 影象是28x28 NumPy陣列,畫素值介於0到255之間。標籤是一個整數陣列,範圍從0到9.這些對應於影象所代表的服裝類別:
標籤
0 T恤衫/上衣
1 褲子
2 套衫
3 連衣裙
4 外套
5 涼鞋
6 襯衫
7 運動鞋
8 袋子
9 踝靴

每個影象都對映到一個標籤。由於類名不包含在資料集中,因此將它們儲存在此處以便在繪製圖像時使用:

class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 
               'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']

探索資料

讓我們在訓練模型之前探索資料集的格式。以下顯示訓練集中有60,000個影象,每個影象表示為28 x 28畫素:

train_images.shape

(60000,28,28)

同樣,訓練集中有60,000個標籤:

len(train_labels)

60000

每個標籤都是0到9之間的整數:

train_labels

陣列([9,0,0,...,3,0,5],dtype = uint8)

測試集中有10,000個影象。同樣,每個影象表示為28 x 28畫素:

test_images.shape

(10000,28,28)

測試集包含10,000個影象標籤:

len(test_labels)

10000

預處理資料

在訓練網路之前,必須對資料進行預處理。如果您檢查訓練集中的第一個影象,您將看到畫素值落在0到255的範圍內:

plt.figure()
plt.imshow(train_images[0])
plt.colorbar()
plt.grid(False)

在這裡插入圖片描述

在饋送到神經網路模型之前,我們將這些值縮放到0到1的範圍。為此,將影象元件的資料型別從整數轉換為float,併除以255.0。

對訓練集和測試集以同樣的方式進行預處理,這是非常重要的:

train_images = train_images / 255.0

test_images = test_images / 255.0

顯示訓練集中的前25個影象,並在每個影象下方顯示類名。驗證資料格式是否正確,我們是否已準備好構建和培訓網路。

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]])

在這裡插入圖片描述

建立模型

構建神經網路需要配置模型的層,然後編譯模型。

設定圖層

神經網路的基本構建塊是層。圖層從提供給它們的資料中提取表示。並且,希望這些表示對於手頭的問題更有意義。

大多數深度學習包括將簡單層連結在一起。大多數圖層tf.keras.layers.Dense都具有在訓練期間學習的引數。

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)
])
  • 該網路中的第一層tf.keras.layers.Flatten將影象的格式從2d陣列(28乘28畫素)轉換為28 * 28 = 784畫素的1d陣列。可以將此圖層視為影象中未堆疊的畫素行並將其排列。該層沒有要學習的引數; 它只重新格式化資料。

  • 在畫素被展平之後,網路由tf.keras.layers.Dense兩層序列組成。這些是密​​集連線或完全連線的神經層。第一Dense層有128個節點(或神經元)。第二(和最後)層是10節點softmax層 - 這返回10個概率分數的陣列,其總和為1.每個節點包含指示當前影象屬於10個類之一的概率的分數。

編譯模型

在模型準備好進行培訓之前,它需要更多設定。這些是在模型的編譯步驟中新增的:

  • 損失函式 - 這可以衡量模型在訓練過程中的準確程度。我們希望最小化此功能,以便在正確的方向上“引導”模型。
  • 優化器 - 這是基於它看到的資料及其損失函式更新模型的方式。
  • 度量標準 - 用於監控培訓和測試步驟。以下示例使用精度,即正確分類的影象的分數。
model.compile(optimizer=tf.train.AdamOptimizer(), 
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

訓練模型

訓練神經網路模型需要以下步驟:

  1. 將訓練資料提供給模型 - 在此示例中為train_images和train_labels陣列。
  2. 該模型學會了關聯影象和標籤。
  3. 我們要求模型對測試集進行預測 - 在這個例子中,test_images陣列。我們驗證預測是否與test_labels陣列中的標籤匹配。

要開始訓練,請呼叫model.fit方法 - 模型“適合”訓練資料:

model.fit(train_images, train_labels, epochs=5)

輸出:

Epoch 1/5
60000/60000 [==============================] - 6s 98us/step - loss: 0.4998 - acc: 0.8244
Epoch 2/5
60000/60000 [==============================] - 5s 90us/step - loss: 0.3767 - acc: 0.8643
Epoch 3/5
60000/60000 [==============================] - 8s 136us/step - loss: 0.3384 - acc: 0.8768
Epoch 4/5
60000/60000 [==============================] - 7s 122us/step - loss: 0.3129 - acc: 0.8852
Epoch 5/5
60000/60000 [==============================] - 5s 83us/step - loss: 0.2957 - acc: 0.8915
10000/10000 [==============================] - 0s 44us/step
Test accuracy: 0.8696

隨著模型訓練,顯示損失和準確度指標。該模型在訓練資料上達到約0.88(或88%)的準確度。

評估準確性

接下來,比較模型在測試資料集上的執行情況:

test_loss, test_acc = model.evaluate(test_images, test_labels)

print('Test accuracy:', test_acc)

輸出:

Test accuracy: 0.8696

事實證明,測試資料集的準確性略低於訓練資料集的準確性。訓練精度和測試精度之間的差距是過度擬合的一個例子。過度擬合是指機器學習模型在新資料上的表現比在訓練資料上表現更差。

作出預測

通過訓練模型,我們可以使用它來預測某些影象。

predictions = model.predict(test_images)

這裡,模型已經預測了測試集中每個影象的標籤。我們來看看第一個預測:

predictions[0]
陣列([1.9905892e-06,1.2566167e-08,6.98845036e-08,1.0045448e-08,
       1.8485264e-07,7.5045829e-03,6.9550931e-07,4.9028788e-02,
       4.0079590e-07,9.4346321e-01],dtype = float32)

預測是10個數字的陣列。這些描述了模型的“信心”,即影象對應於10種不同服裝中的每一種。我們可以看到哪個標籤具有最高的置信度值:

np.argmax(predictions[0])

9

因此,該模型最有信心這個影象是踝靴,或class_names[9]。我們可以檢查測試標籤,看看這是否正確:

test_labels[0]

9

我們可以用圖表來檢視全部的10個類別:

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')

看看測試資料的第0個影象,預測和預測陣列。

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)

在這裡插入圖片描述
讓我們用它的預測繪製幾個影象。正確的預測標籤是藍色的,不正確的預測標籤是紅色的。該數字給出了預測標籤的百分比(滿分100)。請注意,即使非常自信,也可能出錯。

# 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)

在這裡插入圖片描述

最後,使用訓練的模型對單個影象進行預測。

img = test_images[0]
print(img.shape)

#(28,28)

tf.keras模型優化,使在預測批一次,或收集的一個例子。因此,即使我們使用單個影象,我們也需要將其新增到列表中:

img = (np.expand_dims(img,0))
print(img.shape)
#(1,28,28)

現在預測影象:

predictions_single = model.predict(img)
print(predictions_single)

輸出:

[[1.9905854e-06 1.2566143e-08 6.9844901e-08 1.0045391e-08 1.8485194e-07
      7.5045791e-03 6.9566664e-07 4.9028799e-02 4.0079516e-07 9.4346321e-01]]

影象:

    plot_value_array(0, predictions_single, test_labels)
    _ = plt.xticks(range(10), class_names, rotation=45)

在這裡插入圖片描述

model.predict返回列表列表,每個列表對應一批資料中的每個影象。抓取批次中我們(僅)影象的預測:

np.argmax(predictions_single[0])
# 9

而且,和以前一樣,模型預測標籤為9。

附上完整程式碼:

# -*- coding: utf-8 -*-
"""
Created on Tue Sep 18 09:42:55 2018

@author: chenyang
"""

# TensorFlow and tf.keras
import tensorflow as tf
from tensorflow import keras

# Helper libraries
import numpy as np
import matplotlib.pyplot as plt

print(tf.__version__)

#繪製測試資料的圖片
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')
  
if __name__ == '__main__':
    fashion_mnist = keras.datasets.fashion_mnist

    #載入資料
    (train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
    
    #每個分類對應名稱
    class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 
                   'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
    
    #特徵縮放
    train_images = train_images / 255.0
    test_images = test_images / 255.0
    
    #print(np.shape(train_images[1]))
    #顯示訓練集的錢25個影象
    #plt.figure()
    #plt.imshow(train_images[0])
    #plt.colorbar()
    #plt.grid(False)
    plt.figure(figsize=(10,10))
    for i in range(16):
        plt.subplot(4,4,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]])
    
    #設定圖層
    #第一層tf.keras.layers.Flatten將影象的格式從2d陣列(28乘28畫素)轉換為28 * 28 = 784畫素的1d陣列
    #第一Dense層有128個節點(或神經元)。
    #第二(和最後)層是10節點softmax層 - 這返回10個概率分數的陣列,其總和為1.
    #每個節點包含指示當前影象屬於10個類之一的概率的分數。
    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)
    ])
    
    #引數設定
    #損失函式 - 這可以衡量模型在訓練過程中的準確程度。我們希望最小化此功能,以便在正確的方向上“引導”模型。
    #優化器 - 這是基於它看到的資料及其損失函式更新模型的方式。
    #度量標準 - 用於監控培訓和測試步驟。以下示例使用精度,即正確分類的影象的分數
    model.compile(optimizer=tf.train.AdamOptimizer(), 
                  loss='sparse_categorical_crossentropy',
                  metrics=['accuracy'])
    
    #訓練資料
    model.fit(train_images, train_labels, epochs=5)
    
    #評估準確性
    test_loss, test_acc = model.evaluate(test_images, test_labels)
    print('Test accuracy:', test_acc)
    
    #預測,結果為一個10個數字的陣列
#    predictions = model.predict(test_images)
    
    #獲取10個分類中的分數最高的一個
#    np.argmax(predictions[0])
    
#    繪製圖像
#    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)
    
#    預測一個數據
    img = test_images[0]
    print(img.shape)
    
    img = (np.expand_dims(img,0))
    print(img.shape)
    
    predictions_single = model.predict(img)
    print(predictions_single)
    
    plot_value_array(0, predictions_single, test_labels)
#    _ = plt.xticks(range(10), class_names, rotation=45)
    
    print(np.argmax(predictions_single[0]))
      
      
      
      
      
.