Tensorflow學習筆記No.4.2

使用CNN卷積神經網絡(2)

使用Tensorflow搭建簡單的CNN卷積神經網絡對fashion_mnist數據集進行分類html

不瞭解是那麼是CNN卷積神經網絡的小夥伴能夠參考上一篇博客(Tensorflow學習筆記No.4.1)網絡

2.Tensorflow卷積神經網絡相關API簡介

2.1.keras.layers.Conv2D()二維卷積層ide

例如:函數

model.add(keras.layers.Conv2D(128, (3, 3), activation = 'relu', padding = 'same')

  向model中添加一個二維卷積層,第一個參數是filter,也就是卷積核的個數,決定了這層卷積層輸出的數據有多少個通道。第二個參數是卷積核的大小,這裏使用的是3×3的卷積核。activation是激活函數,再也不贅述。學習

  padding則是卷積層的填充模式。簡單來講,設卷積核的尺寸爲k×k,輸入數據的尺寸爲size×size,若填充模式爲‘same’,則卷積層輸出的尺寸與輸入時相同,爲size×size,若爲默認模式‘valid’,則輸出的尺寸爲(size-(k-1))×(size-(k-1))。  測試

  strides參數(示例中沒有出現),它是卷積核每次移動的跨度,默認爲(1, 1),分別是在x和y軸上移動的跨度,若調整爲(2, 2)則卷積層的輸出尺寸會將變爲原來的1/2,即(size/2)×(size/2),同理,若爲(k, k)則輸出尺寸變爲(size/k)×(size/k),使用這個參數會嚴重減小輸出信息,雖然能明顯減小網絡容量,可是容易形成關鍵特徵的丟失,慎重使用!優化

 

2.2.keras.layers.MaxPool2D()二維卷積的池化層spa

例如:code

1 model.add(keras.layers.MaxPool2D())
2 model.add(keras.layers.AveragePooling2D())
3 model.add(keras.layers.GlobalAveragePooling2D())

  向model中添加二維池化層。htm

  池化層默認尺寸pool_size參數爲2×2,會把數據的尺寸縮小至原來的1/2,而且不改變深度。

  示例中的三種池化層分別爲最大值池化,均值池化與全局均值池化。

  最大值池化,選擇pool_size×pool_size範圍內的最大值做爲當前位置的值,每次移動pool_size個單位,若size沒法被整除則自動填充。均值池化同理,計算範圍內的均值做爲當前位置的值。全局池化有所不一樣,它是將所有數據進行池化壓縮,將數據的尺寸size×size縮小爲1×1,不改變深度,一般放在全鏈接層以前。

3.使用Tensorflow搭建簡單的卷積神經網絡模型

使用tensorflow創建一個簡單的CNN網絡模型,對fashion_mnist數據集進行分類,是一個較爲簡單的10分類問題。

首先導入須要用到的模塊

1 from tensorflow import keras
2 import matplotlib.pyplot as plt
3 import numpy as np
4 import pandas as pd

3.1加載並處理數據

  加載fashion_mnist數據集,並分爲訓練集和測試集。

fashion_mnist = keras.datasets.fashion_mnist
(train_image, train_label), (test_image, test_label) = fashion_mnist.load_data()

  此時的train_image與test_image的尺寸分別爲(6000, 28, 28), (1000, 28, 28),分別對應圖片數,圖片的長和寬。

  可是卷積神經網絡的輸入時圖片,圖片應該有三個維度,長寬以及通道數(channel),fashion_mnist數據集中均爲灰度圖像,因此只有一個通道,咱們給測試集和訓練集分別加上這一維度以便做爲神經網絡的輸入。

1  train_image = np.expand_dims(train_image, -1)
2  test_image = np.expand_dims(test_image, -1)

  這裏使用了numpy的.expand_dims()方法擴展了數據集的通道,數據尺寸的最後方加入了一個維度。

  如今數據的尺寸變爲(num, 28, 28, 1),即num個28×28的單通道灰度圖像。

3.2創建網絡模型

  使用keras.Sequential()方法創建一個Sequential模型。

1 model = keras.Sequential()

  首先向其中添加輸入層,咱們要儘可能保留數據的特徵,因此第一層就直接選用處理圖像效果較好的Conv2D卷積層,儘量的獲取圖像特徵。

1 model.add(keras.layers.Conv2D(32, (3, 3), 
2           input_shape = (28, 28, 1),
3           activation = 'relu',
4           padding = 'same'
5          ))

  Conv2D()中的主要參數在2.1中均有說起,這裏再也不贅述。

  input_shape參數與以前創建的Sequential模型相似,表示輸入數據的尺寸,這裏爲28×28的單通道灰度圖像,因此input_shape應該爲(28, 28, 1)。

  隨後向網絡中添加池化層,提取主要特徵並縮小數據規模。

  規模縮小到過程也是擴大感覺野的過程,隨着特徵規模的縮小,單個卷積核單次所能覆蓋的圖像特徵範圍逐漸擴大,這是一個逐漸從提取局部特徵轉變爲提取全局特徵的過程。

1 model.add(keras.layers.MaxPool2D())

  繼續添加捲積層與池化層,最後添加全鏈接層輸出分類結果,最終的模型爲:

 1 model = keras.Sequential()
 2 model.add(keras.layers.Conv2D(32, (3, 3), 
 3           input_shape = (28, 28, 1),
 4           activation = 'relu',
 5           padding = 'same'
 6          ))
 7 #32個卷積核,每一個卷積核大小爲3*3,輸入規格,激活函數,填充爲使輸出與原尺寸相同,默認(valid)爲不填充
 8 model.add(keras.layers.MaxPool2D())
 9 #默認爲2*2池化層
10 model.add(keras.layers.Conv2D(64, (3, 3), activation = 'relu'))
11 model.add(keras.layers.GlobalAveragePooling2D())
12 #全局平均池化
13 model.add(keras.layers.Dense(10, activation = 'softmax'))
14 #輸出層,10分類

   這樣就搭建好了一個簡單的卷積神經網絡。

3.3使用.compile()方法與.fit()方法訓練模型

  這裏與以前的訓練方式相同,不熟悉的小夥伴能夠翻翻以前的博客(Tensorflow學習筆記No.1)進行查看,代碼以下:

1 model.compile(optimizer = 'adam',
2               loss = 'sparse_categorical_crossentropy',
3               metrics = ['acc']
4              )
5 
6 history = model.fit(train_image, train_label, epochs = 30, validation_data = (test_image, test_label))

   訓練過程

  若是你使用的是notebook類的環境,訓練完成後插入如下代碼(Tensorflow學習筆記No.0中有相關介紹)便可查看訓練的正確率圖像:

1 %matplotlib inline
2 plt.plot(history.epoch, history.history.get('acc'), label = 'acc')
3 plt.plot(history.epoch, history.history.get('val_acc'), label = 'val_acc')
4 plt.legend()

  圖像以下圖所示:

  

4.優化已有網絡模型

   如下內容是由本人通過屢次試驗和驗證獲得的:

  從剛剛訓練的網絡模型的訓練圖像中能夠看出:

  訓練集的正確率僅有92.5%,說明模型的擬合性不夠測試集與訓練集正確率相差較大,說明在後續訓練中可能出現過擬合問題

  (注:過擬合是指在訓練集達到很是好的正確率而在測試集上的正確率並不理想,這裏出現的狀況是訓練集和測試集上的正確率均不理想,因此不能稱之爲過擬合,但經過圖像不難看出,咱們的模型繼續訓練下去極有可能出現過擬合現象。)

  因此咱們的優化方式從這兩個角度出發,首先,增長隱藏單元(卷積核)數量,加深模型深度,以增長模型的擬合度。而後,爲了抑制可能出現的過擬合現象,在適當位置加入Dropout層抑制過擬合

  改進後的模型以下:

 

 1 model_ = keras.Sequential()
 2 model_.add(keras.layers.Conv2D(64, (3, 3), 
 3           input_shape = (28, 28, 1),
 4           activation = 'relu',
 5           padding = 'same'
 6          ))
 7 model_.add(keras.layers.Conv2D(64, (3, 3), activation = 'relu', padding = 'same'))
 8 #添加兩層Conv2D以提升擬合能力
 9 model_.add(keras.layers.MaxPool2D())
10 model_.add(keras.layers.Dropout(0.25))
11 #添加Dropout抑制過擬合
12 model_.add(keras.layers.Conv2D(128, (3, 3), activation = 'relu', padding = 'same'))
13 model_.add(keras.layers.Conv2D(128, (3, 3), activation = 'relu', padding = 'same'))
14 model_.add(keras.layers.MaxPool2D())
15 model_.add(keras.layers.Dropout(0.25))
16 model_.add(keras.layers.Conv2D(256, (3, 3), activation = 'relu', padding = 'same'))
17 model_.add(keras.layers.Conv2D(256, (3, 3), activation = 'relu', padding = 'same'))
18 model_.add(keras.layers.Dropout(0.25))
19 model_.add(keras.layers.GlobalAveragePooling2D())
20 model_.add(keras.layers.Dense(256, activation = 'relu'))
21 #添加Dense層進行過渡
22 model_.add(keras.layers.Dense(10, activation = 'softmax'))

 

  通過調整後的模型獲得以下結果:

 

  模型的正確率圖像以下:

 

 

 

  通過調整後的模型,擬合度有了較爲明顯的提升,在測試集上能夠達到接近95%的正確率,在測試集上也能達到較爲滿意的效果,正確率約92.5%。

後續將會對模型進行改進,爭取達到更高的準確率!

相關文章
相關標籤/搜索