關於tensorflow2.0的注意事項以及使用cnn完成Fashion MNIST分類的demo

引言

提到tensorflow2.0,我不知道讀者最先想到的是什麼,我最先想到的是——”版本“,沒錯,就是版本,tensorflow2.0相比1.x版本有非常大的變化,加上python是一個版本並不兼容的環境(即使是3.5和3.7,也會有部分不兼容),這給許多初學者和環境搭建以及mnist的cnn測試造成了很多困難,這裏我想和大家有一個直觀的解釋。

tensorflow2.0

開始之前,我必須提前與讀者說明,也是希望初學者應該牢牢記住的幾點:

(1)程序報錯的時候不要急着去問,先看看紅色報錯英文的意思,在調試顯得越來越重要的時代,編譯器給出的error解釋其實是非常詳細的。

(2)當你遇到幾下一個surprise的時候(我憑記憶寫的,可能不是很相符,但大概意思差不多)
AttributeError: module ‘tensorflow’ has no attribute ‘Session’

ImportError:can not find moudle six/numpy

RuntimeError: implement_array_function method already has a docstring
如果你確實安裝了但是還是有以上之類的錯誤,不要懷疑,一定是版本問題。版本與代碼的不匹配,不同包之間版本的不匹配,python與不同庫的不匹配是最直接的原因。

(3)最好的各種測試代碼一定是tensorflow官網上的測試代碼,學會看官方文檔,這,很重要。

(4)不要一直嘗試綠色的三角符號,有時候terminal終端調試其實更簡潔,也更高效。

(5)當網上最新版的代碼很少很難運行成功時,嘗試安裝低版本的tensorflow和Python是一個不錯的解決方法,

(6)pip install之類的命令有問題時,學會從鏡像源,具體包在硬盤中的存儲位置看錯誤問題,記住常用的終端命令,另外,不要懷疑編譯器會出錯,一定是自己的配置問題。

(7)實在不行時,與其從網上查找各種雜七亂八的問題解決方法,重啓,刪除,重裝是更有效率的方式。因爲,很多時候,每臺計算機的問題都是不同的,你並不一定能從csdn找到解決方法。

Fashion MNIST

FashionMNIST 是一個替代 MNIST 手寫數字集的圖像數據集。它是由 Zalando(一家德國的時尚科技公司)旗下的研究部門提供。其涵蓋了來自 10 種類別的共 7 萬個不同商品的正面圖片。其中包含 60000 個訓練樣本和 10000 個測試樣本,其中的樣本都來自日常穿着的衣褲鞋包,每個都是 28×28 的灰度圖像,每張圖像都有各自的標籤。
在這裏插入圖片描述
關於這個數據集的介紹網上有很多,這裏也不過多敘述

CNN Fashion MNIST demo

注:這其實是tensorflow上的一個官方示例:
https://tensorflow.google.cn/tutorials/keras/classification/

使用tensorflow.keras(高級API)在TensorFlow中構建和訓練模型。
(1)搭建tensorflow+keras框架,這裏不再介紹,網上有很多不錯的教程,但一定要記住:大道至簡,最好的教程一定不是最複雜的,搭建完成後,通過如下代碼進行測試:

import tensorflow as tf
from tensorflow import keras

import numpy as np
import matplotlib.pyplot as plt

print(tf.version)
得到輸出結果2.0.0,可以看到框架搭建完成(這裏要特別注意版本和代碼的匹配問題)
(2)導入Fashion MNIST數據集
數據集可以從地址中下載成文件,也可以在tensorflow的dataset數據包中導入:
fashion_mnist = keras.datasets.fashion_mnist

(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
可以從運行框中看到數據從地址中進行加載,最後返回四個NumPy數組
train_images,train_labels,test_images,test_labels
每個圖像都映射到一個標籤。由於類名不包含在數據集中,因此將它們存儲在此處以供以後在繪製圖像時使用:
class_names = [‘T-shirt/top’, ‘Trouser’, ‘Pullover’, ‘Dress’, ‘Coat’,
‘Sandal’, ‘Shirt’, ‘Sneaker’, ‘Bag’, ‘Ankle boot’]
(3)檢查四個NumPy數組,並觀察數據集的一些性質:
在這裏插入圖片描述顯示了訓練集中有60,000張圖像,每張圖像表示爲28 x 28像素:
在這裏插入圖片描述訓練集中有60,000個標籤
在這裏插入圖片描述每個標籤都是0到9之間的整數
測試集也是相同情況,這裏不再贅述。
(4)預處理數據
在訓練網絡之前,必須對數據進行預處理。如果檢查訓練集中的第一張圖像,您將看到像素值落在0到255的範圍內,在將它們輸入神經網絡模型之前,將這些值縮放到0到1的範圍。爲此,將值除以255。以相同的方式預處理訓練集和測試集非常重要。
train_images = train_images / 255.0

test_images = test_images / 255.0
處理後再看圖像,可以看到圖像變成了灰度圖像:
在這裏插入圖片描述(5) 建立模型
 設置圖層
神經網絡的基本組成部分是層。圖層從輸入到其中的數據中提取表示。希望這些表示對於當前的問題有意義。
深度學習的大部分內容是將簡單的層鏈接在一起。大多數層(利潤tf.keras.layers.Dense)具有在訓練期間學習的參數。
model = keras.Sequential([
keras.layers.Flatten(input_shape=(28, 28)),
keras.layers.Dense(128, activation=‘relu’),
keras.layers.Dense(10, activation=‘softmax’)
])
該網絡的第一層tf.keras.layers.Flatten將圖像的格式從二維數組(28 x 28像素)轉換爲一維數組(28 * 28 = 784像素)。可以將這一層看作是堆疊圖像中的像素行並對齊它們。該層沒有學習參數。它只會重新格式化數據。

像素變平後,網絡由tf.keras.layers.Dense兩層序列組成。這些是緊密連接或完全連接的神經層。第一Dense層有128個節點(或神經元)。第二層(也是最後一層)是一個10節點的softmax層,該層返回10個總和爲1的概率分數的數組。每個節點都包含一個分數,該分數指示當前圖像屬於10個類別之一的概率。
 編譯模型
在準備訓練模型之前,需要進行一些其他設置。這些是在模型的編譯步驟中添加的:
損失函數 -衡量訓練期間模型的準確性。您希望最小化此功能,以在正確的方向上“引導”模型。
優化器 -這是基於模型看到的數據及其損失函數來更新模型的方式。
指標 -用於監視培訓和測試步驟。以下示例使用precision,即正確分類的圖像比例。
model.compile(optimizer=‘adam’,
loss=‘sparse_categorical_crossentropy’,
metrics=[‘accuracy’])
(6) 訓練模型
要開始訓練,請調用該model.fit方法,之所以這麼稱呼是因爲該方法使模型“適合”訓練數據:
model.fit(train_images, train_labels, epochs=10)
可以在運行區中顯示的損失函數和準確性指標:
剛開始訓練時可以看到準確率逐漸升高:
在這裏插入圖片描述趨於穩定後,可以看到有一個不錯的準確率:
在這裏插入圖片描述(7) 評估準確性
接下來,比較模型在測試數據集上的表現:
test_loss, test_acc = model.evaluate(test_images, test_labels, verbose=2)

print(’\nTest accuracy:’, test_acc)
在這裏插入圖片描述事實證明,測試數據集的準確性略低於訓練數據集的準確性。訓練準確性和測試準確性之間的差距代表過度擬合。過度擬合是指機器學習模型在新的,以前看不見的輸入上的表現比訓練數據上的表現差的情況。
(8) 可視化
我們以圖形方式查看完整的10個類預測。
首先讓我們看一下第1張圖片,預測和預測數組。正確的預測標籤爲藍色,錯誤的預測標籤爲紅色。該數字給出了預測標籤的百分比(滿分爲100)。
在這裏插入圖片描述全部的預測正確率如下:
在這裏插入圖片描述可見大部分還是以非常高的預測準確率出現,只有一個的預測效果比較差。

附:完整代碼:

from __future__ import absolute_import, division, print_function, unicode_literals

# 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__)
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']

plt.figure()
plt.imshow(train_images[0])
plt.colorbar()
plt.grid(False)
plt.show()
train_images = train_images / 255.0

test_images = test_images / 255.0
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]])
plt.show()
model = keras.Sequential([
    keras.layers.Flatten(input_shape=(28, 28)),
    keras.layers.Dense(128, activation='relu'),
    keras.layers.Dense(10, activation='softmax')
])
model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])
model.fit(train_images, train_labels, epochs=10)
test_loss, test_acc = model.evaluate(test_images,  test_labels, verbose=2)

print('\nTest accuracy:', test_acc)
predictions = model.predict(test_images)
def plot_image(i, predictions_array, true_label, img):
  predictions_array, true_label, img = predictions_array, 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, true_label[i]
  plt.grid(False)
  plt.xticks(range(10))
  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')

# Plot the first X test images, their predicted labels, and the true labels.
# Color correct predictions in blue and 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[i], test_labels, test_images)
  plt.subplot(num_rows, 2*num_cols, 2*i+2)
  plot_value_array(i, predictions[i], test_labels)
plt.tight_layout()
plt.show()

看完上面這麼多,我想你能看到這份代碼中最核心的部分,也是對結果影響最大的部分,就是神經網絡層的搭建和選擇每一層的內容:

model = keras.Sequential([
    keras.layers.Flatten(input_shape=(28, 28)),
    keras.layers.Dense(128, activation='relu'),
    keras.layers.Dense(10, activation='softmax')
])

我們可以嘗試一個最簡單的改變:

model = keras.Sequential([
    keras.layers.Flatten(input_shape=(28, 28)),
    keras.layers.Dense(256, activation='relu'),  # 隱藏層2
    keras.layers.Dense(128, activation='relu'),
    keras.layers.Dense(64, activation='relu'),
    keras.layers.Dense(32, activation='relu'),
    keras.layers.Dense(10, activation='softmax')
])

再次運行,我們可以看到一個略顯提高的準確率:
10000/1 - 1s - loss: 0.2667 - accuracy: 0.8894
Test accuracy: 0.8894

當然,如果你對神經網絡有一個更加深入的瞭解,可以自己修改模型每層的參數,自己增刪網絡,可能得到一個更好的準確率的結果。

未完待續!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章