2018年4月13日 星期五

使用 Keras 多層感知器 MLP 辨識 Cifar-10 圖片

做完 Cifar-10 資料集測試後, 接下來我想用 MLP 來測試看看 Cifar-10 的辨識率有多少. 由於直接用 MLP 這種 DNN 網路做類別辨識須將圖片樣本拉平, 這會失去圖像的空間特徵, 辨識率可能不會很好, 測試過程紀錄如下.

本系列之前的測試紀錄參考 :

Windows 安裝深度學習框架 TensorFlow 與 Keras
使用 Keras 測試 MNIST 手寫數字辨識資料集
使用 Keras 多層感知器 MLP 辨識手寫數字 (一)
使用 Keras 多層感知器 MLP 辨識手寫數字 (二)


1. 載入 Cifar-10 資料集 :

匯入 cifar10 與 numpy 模組後呼叫 load_data() 載入 Cifar-10 資料集 :

D:\Python\test>python
Python 3.6.1 (v3.6.1:69c0db5, Mar 21 2017, 18:41:36) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from keras.datasets import cifar10     
Using TensorFlow backend.
>>> from keras.utils import np_utils        #轉換標籤為 Oonehot 用
>>> import numpy as np     
>>> np.random.seed(10) 
>>> (x_train_image, y_train_label), (x_test_image, y_test_label)=cifar10.load_data() 

函數 load_data() 會傳回兩個 tuple, 分別是訓練集與測試集的圖片與標籤陣列 :

x_train_image : 訓練集數字圖片陣列 (3 維)
y_train_label : 訓練集標籤陣列 (2 維)
x_test_image : 測試集數字圖片陣列 (3 維)
y_test_label : 測試集標籤陣列 (2 維)


2. 圖片資料預處理  :

Cifar-10 資料集包含訓練集 50000 筆, 測試集 10000 筆. 其中圖片是以三維陣列儲存的 32*32 解析度的 RGB 三原色數字影像, 索引存取方式為 [i][j][k], 第一維 i 表示圖片編號, 範圍 0~49999 共 5 萬張; 第二維 j 表示圖片的畫素列編號, 範圍 0~31 共 32 列, 第 3 維 k 代表行編號, 實際上儲存的是每一個畫素的 RGB 三原色的 1*3 行向量, 每一種顏色數值範圍 0~255.

顯示陣列之 shape 屬性 :

>>> print('x_train_image:', x_train_image.shape)   #顯示訓練集圖片之 shape
x_train_image: (50000, 32, 32, 3)     #訓練集為 5 萬筆之 32*32 RGB 彩色圖片
>>> print('y_train_label:', y_train_label.shape)       #顯示訓練集標籤之 shape
y_train_label: (50000, 1)                   #訓練集標籤為 5 萬筆 0~9 數字
>>> print('x_test_image:', x_test_image.shape)        #顯示測試集圖片之 shape
x_test_image: (10000, 32, 32, 3)      #測試集為 1 萬筆之 32*32 RGB 彩色圖片
>>> print('y_test_label:', y_test_label.shape)            #顯示測試集標籤之 shape
y_test_label: (10000, 1)                    #測試集標籤為 1 萬筆 0~9 數字

數字圖片之資料結構如下 :


例如訓練集第一張圖片之內容節略如下 :

x_train_image[0]= [
 [[ 59  62  63]       #第 1 列畫素開始 (0)
  [ 43  46  45]
  [ 50  48  43]
  ...
  [158 132 108]
  [152 125 102]
  [148 124 103]]    #第 1 列畫素結束 (31)

 [[ 16  20  20]        #第 2 列畫素開始 (0)
  [  0   0   0]
  [ 18   8   0]
  ...
  [123  88  55]
  [119  83  50]
  [122  87  57]]      #第 2 列畫素結束 (31)

......

 [[177 144 116]     #第 32 列畫素開始 (0)
  [168 129  94]
  [179 142  87]
  ...
  [216 184 140]
  [151 118  84]
  [123  92  72]]]     #第 32 列畫素結束 (0)

訓練集第一張圖片的各列開頭畫素擷取方式舉例如下 :

>>> print('x_train_image[0][0][0]=', x_train_image[0][0][0])   #第 1 列第 1 個畫素
x_train_image[0][0][0]= [59 62 63]
>>> print('x_train_image[0][1][0]=', x_train_image[0][1][0])   #第 2 列第 1 個畫素
x_train_image[0][1][0]= [16 20 20]
>>> print('x_train_image[0][31][0]=', x_train_image[0][31][0]  #第 32 列第 1 個畫素
x_train_image[0][31][0]= [177 144 116]

這些以三維陣列表示的圖片在送入 MLP 做訓練或預測之前必須拉平展開為一維向量, 一張 32*32 解析度具有 RGB 三色版的圖片總共有 32*32*3=3072 個數字, 拉平後會變成 1*3072 的行向量, 呼叫陣列的 reshape() 函數即可將 5 萬筆訓練集與 1 萬筆測試集的圖片平坦化 (flatten), 接著將數值型態由整數轉成浮點數, 後面正規化要用到 :

>>> x_train=x_train_image.reshape(50000,3072).astype('float32')
>>> x_test=x_test_image.reshape(10000,3072).astype('float32') 
>>> x_train 
array([[ 59.,  62.,  63., ..., 123.,  92.,  72.],
       [154., 177., 187., ..., 143., 133., 144.],
       [255., 255., 255., ...,  80.,  86.,  84.],
       ...,
       [ 35., 178., 235., ...,  12.,  31.,  50.],
       [189., 211., 240., ..., 195., 190., 171.],
       [229., 229., 239., ..., 163., 163., 161.]], dtype=float32)
>>> x_train.ndim      #顯示訓練集陣列維度 (2 維)
2
>>> x_test.ndim        #顯示測試集陣列維度 (2 維)
2
>>> x_train.size        #訓練集全部畫素數目
153600000
>>> x_test.size          #測試集全部畫素數目
30720000
>>> x_train[0]          #訓練集第一張圖片
array([ 59.,  62.,  63., ..., 123.,  92.,  72.], dtype=float32)
>>> x_train[0].size   #訓練集第一張圖片之大小 (3072 個畫素)
3072
>>> x_test[0]             #測試集第一張圖片
array([158., 112.,  49., ...,  21.,  67., 110.], dtype=float32)
>>> x_test[0].size      #測試集第一張圖片之大小 (3072 個畫素)
3072

由 ndim 屬性可知, 平坦化後的數字圖片都從 3 維變成 2 維, 第 1 維是圖片索引; 第 2 維是每個圖片的 3072 個畫素之索引. 由 size 屬性可知訓練集全部畫素數目為 50000*3072=15360000 個; 而測試集全部畫素數目為 10000*3072=30720000 個.

平坦化後接著是正規化, 仍然採用除以最大值 255 予以正規化的方法 :

>>> x_train_normalize=x_train/255     #訓練集正規化
>>> x_test_normalize=x_test/255         #測試集正規化
>>> x_train_normalize[0]                     #正規化之訓練集第一張圖片
array([0.23137255, 0.24313726, 0.24705882, ..., 0.48235294, 0.36078432,
       0.28235295], dtype=float32)

這樣數字圖片的預處理就完成了.


3. 標籤資料預處理  :

標籤本身為 2 維陣列, 可利用陣列之 shape, ndime, size 等屬性查詢其結構與元素個數 :

>>> y_train_label                #訓練集標籤
array([[6],
       [9],
       [9],
       ...,
       [9],
       [1],
       [1]], dtype=uint8)
>>> y_train_label[0]           #訓練集第 1 個標籤
array([6], dtype=uint8)
>>> y_train_label.shape     #訓練集標籤為 50000 個 1 維向量
(50000, 1)
>>> y_train_label.ndim      #2 維陣列
2
>>> y_train_label.size         #訓練集標籤大小 50000
50000
>>> y_test_label                   #測試集標籤 
array([[3],
       [8],
       [8],
       ...,
       [5],
       [1],
       [7]])
>>> y_test_label[0]             #測試集第 1 個標籤
array([3])
>>> y_test_label.shape       #測試集標籤為 10000 個 1 維向量
(10000, 1)
>>> y_test_label.ndim        #2 維陣列
2
>>> y_test_label.size           #測試集標籤大小 10000
10000

標籤的預處理對於類別型變數而言其實就是進行 Onehot (獨熱) 編碼, 例如將原本之標籤 6 轉換為 0000001000, 亦即對於 0~9 這 10 種類別只有一個位元會輸出 1 (One hot). 這要利用 keras.util.to_categorical() 函數來達成 :

>>> y_train_onehot=np_utils.to_categorical(y_train_label)    #訓練集標籤
>>> y_test_onehot=np_utils.to_categorical(y_test_label)         #測試集標籤
>>> y_train_label[0]
array([6], dtype=uint8)
>>> y_train_onehot[0] 
array([0., 0., 0., 0., 0., 0., 1., 0., 0., 0.])

這樣就完成標籤資料的預處理了.


4. 建立 MLP 模型 :

針對 Cifar-10 的全連接 MLP 模型結構為 3 層的人工神經網路 (但參數只有 2 層) 如下所示, 輸入層具有 3072 個神經元用來接取每張圖片的 32*32*3=3072 個畫素; 隱藏層具有 256 個神經元, 輸出層有 10 個神經元, 分別對應 Cifar-10 的 10 種圖片分類 :




利用 Keras 的線性堆疊 (Sequential) 來建立 MLP 模型, 將兩層的 Dense 神經網路層以 add() 方法一層一層疊起來, 每一個 Dense 層都採用線性 + 非線性激活結構, 其中 Dense 1 層使用 ReLu 激活函數; 而 Dense 2 則使用 SoftMax 函數, 上面網路的內部結構如下所示 :




其數學運算式如下 :

輸入層至隱藏層 (dense_1) : h1=relu(X*W1+b1)
隱藏層至輸出層 (dense_2) : y=softmax(h1*W2+b2)

其中括號內為線性運算, 括號外的 relu() 與 softmax() 為非線性運算.

依上述架構用 Keras 來建立 MLP 網路並顯示模型之摘要 :

>>> from keras.models import Sequential 
>>> from keras.layers import Dense 
>>> model=Sequential() 
>>> model.add(Dense(units=256, input_dim=3072, kernel_initializer='normal', activation='relu'))   
>>> model.add(Dense(units=10, kernel_initializer='normal', activation='softmax')) 
>>> model.summary()   
_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
dense_1 (Dense)              (None, 256)               786688
_________________________________________________________________
dense_2 (Dense)              (None, 10)                2570
=================================================================
Total params: 789,258
Trainable params: 789,258
Non-trainable params: 0
_________________________________________________________________

此處 Dense_1 層的參數有 786688 個=3072*256 + 256 (offset), 而 Dense_2 層參數有 2570 個=256*10 + 10, 全部參數合計 786688 + 2570=789258 個.


5. 編譯與訓練 MLP 模型 :

建好 MLP 模型後須先呼叫 compile() 函數, 需指定損失函數, 最佳化方法, 以及評估訓練的方式等進行模型編譯, 然後呼叫 fit() 函數使用 Cifar-10 的訓練集資料 (正規化圖片與 Onehot 編碼之標籤) 來訓練 MLP 網路 :

>>> model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])   
>>> train_history=model.fit(x=x_train_normalize, y=y_train_onehot, validation_split=0.2, epochs=10, batch_size=200, verbose=2)   
Train on 40000 samples, validate on 10000 samples
Epoch 1/10
 - 9s - loss: 1.9405 - acc: 0.3059 - val_loss: 1.8187 - val_acc: 0.3533
Epoch 2/10
 - 9s - loss: 1.7431 - acc: 0.3832 - val_loss: 1.7223 - val_acc: 0.3923
Epoch 3/10
 - 9s - loss: 1.6760 - acc: 0.4062 - val_loss: 1.6724 - val_acc: 0.4136
Epoch 4/10
 - 9s - loss: 1.6216 - acc: 0.4271 - val_loss: 1.6379 - val_acc: 0.4261
Epoch 5/10
 - 9s - loss: 1.5843 - acc: 0.4390 - val_loss: 1.6030 - val_acc: 0.4382
Epoch 6/10
 - 9s - loss: 1.5581 - acc: 0.4503 - val_loss: 1.5694 - val_acc: 0.4487
Epoch 7/10
 - 9s - loss: 1.5298 - acc: 0.4600 - val_loss: 1.5572 - val_acc: 0.4498
Epoch 8/10
 - 9s - loss: 1.5141 - acc: 0.4649 - val_loss: 1.5846 - val_acc: 0.4436
Epoch 9/10
 - 9s - loss: 1.4816 - acc: 0.4773 - val_loss: 1.5673 - val_acc: 0.4457
Epoch 10/10
 - 9s - loss: 1.4686 - acc: 0.4810 - val_loss: 1.5680 - val_acc: 0.4478

可見隨著訓練週期增加, 預測準確率逐步提升至 0.4843. 如前所述, 由於平坦化喪失了圖片的空間特徵, 因此預測準確率不到一半. 這裡仍然使用 20% 的訓練集資料 (10000 筆) 做驗證, 亦即實際使用 80% (40000 筆) 分批做訓練, 每批 200 筆, 全部資料反覆做 10 遍訓練, 結果 (準確度與誤差) 儲存在陣列中傳回, 可用 acc, loss 取得 40000 筆的訓練結果, 用 val_acc 與 val_loss 取得 10000 筆之驗證結果 :  

>>> train_history.history["loss"]
[1.9404615819454194, 1.7430958902835847, 1.6760325831174852, 1.6215702134370804, 1.5842689234018326, 1.558070672750473, 1.529754489660263, 1.5140713691711425, 1.4815812402963637, 1.4686381608247756]
>>> train_history.history["acc"]
[0.3058749999850988, 0.38319999903440477, 0.4062249992787838, 0.4270999994874001, 0.4390000009536743, 0.4502999997138977, 0.46004999950528147, 0.46487499997019766, 0.47727499932050704, 0.4810249993205071]
>>> train_history.history["val_loss"]
[1.8187400770187379, 1.7222569155693055, 1.6723521327972413, 1.6378972125053406, 1.6029685401916505, 1.5694254302978516, 1.557159855365753, 1.5845503187179566, 1.5673147130012512, 1.5679782795906068]
>>> train_history.history["val_acc"]
[0.35330000162124636, 0.3922999995946884, 0.4135999995470047, 0.42610000014305116, 0.43820000052452085, 0.4486999982595444, 0.4498000007867813, 0.4435999995470047, 0.44569999814033506, 0.44779999732971193]

訓練結果可用 matplotlib 繪製圖形 :

>>> import matplotlib.pyplot as plt     
>>> def show_train_history(train_history):    
...     fig=plt.gcf()    
...     fig.set_size_inches(16, 6)    
...     plt.subplot(121)    
...     plt.plot(train_history.history["acc"])    
...     plt.plot(train_history.history["val_acc"])    
...     plt.title("Train History")    
...     plt.xlabel("Epoch")    
...     plt.ylabel("Accuracy")    
...     plt.legend(["train", "validation"], loc="upper left")   
...     plt.subplot(122)    
...     plt.plot(train_history.history["loss"])    
...     plt.plot(train_history.history["val_loss"])   
...     plt.title("Train History")   
...     plt.xlabel("Epoch")   
...     plt.ylabel("Loss")   
...     plt.legend(["train", "validation"], loc="upper left")   
...     plt.show()   
...
>>> show_train_history(train_history)   





6. 以測試樣本評估訓練後的 MLP 模型準確率 :

完成 MLP 模型訓練後, 可呼叫 evaluate() 來評估此模型之參數對測試集資料之準確率 :

>>> scores=model.evaluate(x_test_normalize, y_test_onehot) 
10000/10000 [==============================] - 1s 124us/step
>>> print("Accuracy=", scores[1])   
Accuracy= 0.4526

此準確率 0.4526 一定會比最後一周訓練結果的 (0.4810) 低.


7. 以測試樣本進行預測 :

呼叫 predict_classes() 即可對測試集的 10000 張數字圖片進行預測, 結果將以二維陣列傳回, 每個預測值以 1*1 陣列表示 :

>>> prediction=model.predict_classes(x_test_normalize)   
>>> print(prediction) 
[5 8 0 ... 3 4 7]
>>> print(prediction[:10]) 
[5 8 0 0 4 6 5 4 5 1]
>>> print(y_test_label[:10]) 
[[3]
 [8]
 [8]
 [0]
 [6]
 [6]
 [1]
 [6]
 [3]
 [1]]

我將標籤攤平以利比較 :

標籤 : 5 8 0 0 4 6 5 4 5 1
預測 : 3 8 8 0 6 6 1 6 3 1

前十張圖片只有四張預測結果正確, 正確率真的只有 40% 左右呢.

我將上面的指令寫成如下程式以便在命令列中執行 :

#show_cifar10_mlp_prediction.py
from keras.datasets import cifar10
from keras.models import Sequential
from keras.layers import Dense
from keras.utils import np_utils
import matplotlib.pyplot as plt
import numpy as np
import time

def show_train_history(train_history):
    fig=plt.gcf()
    fig.set_size_inches(16, 6)
    plt.subplot(121)
    plt.plot(train_history.history["acc"])
    plt.plot(train_history.history["val_acc"])
    plt.title("Train History")
    plt.xlabel("Epoch")
    plt.ylabel("Accuracy")
    plt.legend(["train", "validation"], loc="upper left")
    plt.subplot(122)
    plt.plot(train_history.history["loss"])
    plt.plot(train_history.history["val_loss"])
    plt.title("Train History")
    plt.xlabel("Epoch")
    plt.ylabel("Loss")
    plt.legend(["train", "validation"], loc="upper left")
    plt.show()

#pre-processing
start=time.time()
np.random.seed(10)
(x_train_image, y_train_label), (x_test_image, y_test_label)=cifar10.load_data()
x_train=x_train_image.reshape(50000,3072).astype('float32')
x_test=x_test_image.reshape(10000,3072).astype('float32')
x_train_normalize=x_train/255
x_test_normalize=x_test/255
y_train_onehot=np_utils.to_categorical(y_train_label)
y_test_onehot=np_utils.to_categorical(y_test_label)

#create model
model=Sequential()
model.add(Dense(units=256, input_dim=3072, kernel_initializer='normal', activation='relu'))
model.add(Dense(units=10, kernel_initializer='normal', activation='softmax'))
model.summary()

#train model
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
train_history=model.fit(x=x_train_normalize, y=y_train_onehot, validation_split=0.2, epochs=10, batch_size=200, verbose=2)
end=time.time()
elapsed=end-start
print("Training time=" + str(elapsed) + " seconds")
show_train_history(train_history)

#evaluate and predict the test data
scores=model.evaluate(x_test_normalize, y_test_onehot)
print("Accuracy=", scores[1])
prediction=model.predict_classes(x_test_normalize)
print(prediction)


8. 增加隱藏層神經元以提高準確率

上面以 256 個神經元建構的隱藏層預測效果不佳, 如果增加隱藏層神經元應該會提升準確率. 我將上面的程式改為如下可以透過命令列參數改變隱藏層神經元數目的版本, 看看若提升隱藏層神經元數目為 512 與 1024, 是否準確率顯著提升?

#show_cifar10_mlp_prediction2.py
import sys
import time
from keras.datasets import cifar10
from keras.models import Sequential
from keras.layers import Dense
from keras.utils import np_utils
import matplotlib.pyplot as plt
import numpy as np

def show_train_history(train_history):
    fig=plt.gcf()
    fig.set_size_inches(16, 6)
    plt.subplot(121)
    plt.plot(train_history.history["acc"])
    plt.plot(train_history.history["val_acc"])
    plt.title("Train History")
    plt.xlabel("Epoch")
    plt.ylabel("Accuracy")
    plt.legend(["train", "validation"], loc="upper left")
    plt.subplot(122)
    plt.plot(train_history.history["loss"])
    plt.plot(train_history.history["val_loss"])
    plt.title("Train History")
    plt.xlabel("Epoch")
    plt.ylabel("Loss")
    plt.legend(["train", "validation"], loc="upper left")
    plt.show()

#pre-processing
start=time.time()
np.random.seed(10)
(x_train_image, y_train_label), (x_test_image, y_test_label)=cifar10.load_data()
x_train=x_train_image.reshape(50000,3072).astype('float32')
x_test=x_test_image.reshape(10000,3072).astype('float32')
x_train_normalize=x_train/255
x_test_normalize=x_test/255
y_train_onehot=np_utils.to_categorical(y_train_label)
y_test_onehot=np_utils.to_categorical(y_test_label)

#create model
h=int(sys.argv[1])
model=Sequential()
model.add(Dense(units=h, input_dim=3072, kernel_initializer='normal', activation='relu'))
model.add(Dense(units=10, kernel_initializer='normal', activation='softmax'))
model.summary()

#train model
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
train_history=model.fit(x=x_train_normalize, y=y_train_onehot, validation_split=0.2, epochs=10, batch_size=200, verbose=2)
elapsed=time.time()-start
print("Training time=" + str(elapsed) + " Seconds")
show_train_history(train_history)

#evaluate and predict the test data
scores=model.evaluate(x_test_normalize, y_test_onehot)
print("Accuracy=", scores[1])
prediction=model.predict_classes(x_test_normalize)
print(prediction)

512 個隱藏層神經元的訓練與預測結果如下 :

D:\Python\test>show_cifar10_mlp_prediction2.py 512 
Using TensorFlow backend.
_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
dense_1 (Dense)              (None, 512)               1573376
_________________________________________________________________
dense_2 (Dense)              (None, 10)                5130
=================================================================
Total params: 1,578,506
Trainable params: 1,578,506
Non-trainable params: 0
_________________________________________________________________
Train on 40000 samples, validate on 10000 samples
Epoch 1/10
 - 15s - loss: 2.1757 - acc: 0.2925 - val_loss: 1.8484 - val_acc: 0.3424
Epoch 2/10
 - 15s - loss: 1.7530 - acc: 0.3792 - val_loss: 1.7572 - val_acc: 0.3874
Epoch 3/10
 - 17s - loss: 1.6737 - acc: 0.4080 - val_loss: 1.6924 - val_acc: 0.3993
Epoch 4/10
 - 15s - loss: 1.6178 - acc: 0.4320 - val_loss: 1.6377 - val_acc: 0.4261
Epoch 5/10
 - 17s - loss: 1.5797 - acc: 0.4439 - val_loss: 1.6295 - val_acc: 0.4192
Epoch 6/10
 - 14s - loss: 1.5479 - acc: 0.4559 - val_loss: 1.5920 - val_acc: 0.4462
Epoch 7/10
 - 14s - loss: 1.5198 - acc: 0.4647 - val_loss: 1.5590 - val_acc: 0.4541
Epoch 8/10
 - 15s - loss: 1.4961 - acc: 0.4738 - val_loss: 1.5816 - val_acc: 0.4496
Epoch 9/10
 - 16s - loss: 1.4715 - acc: 0.4835 - val_loss: 1.5654 - val_acc: 0.4498
Epoch 10/10
 - 15s - loss: 1.4505 - acc: 0.4885 - val_loss: 1.5466 - val_acc: 0.4516
Training time=155.61666822433472 Seconds
10000/10000 [==============================] - 2s 201us/step
Accuracy= 0.4564
[3 9 0 ... 5 4 2]

與 256 個神經元結果比起來, 準確度有提升一些. 訓練結果圖如下 :




隱藏層神經元增加為 1024 的訓練與預測結果如下 :

D:\Python\test>show_cifar10_mlp_prediction2.py 1024
Using TensorFlow backend.
_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
dense_1 (Dense)              (None, 1024)              3146752
_________________________________________________________________
dense_2 (Dense)              (None, 10)                10250
=================================================================
Total params: 3,157,002
Trainable params: 3,157,002
Non-trainable params: 0
_________________________________________________________________
Train on 40000 samples, validate on 10000 samples
Epoch 1/10
 - 29s - loss: 6.3627 - acc: 0.2266 - val_loss: 6.0748 - val_acc: 0.2522
Epoch 2/10
 - 29s - loss: 3.4349 - acc: 0.3037 - val_loss: 1.7876 - val_acc: 0.3688
Epoch 3/10
 - 28s - loss: 1.7216 - acc: 0.3904 - val_loss: 1.7223 - val_acc: 0.3940
Epoch 4/10
 - 28s - loss: 1.6453 - acc: 0.4212 - val_loss: 1.6823 - val_acc: 0.4084
Epoch 5/10
 - 28s - loss: 1.5977 - acc: 0.4381 - val_loss: 1.6285 - val_acc: 0.4328
Epoch 6/10
 - 27s - loss: 1.5622 - acc: 0.4492 - val_loss: 1.6211 - val_acc: 0.4273
Epoch 7/10
 - 27s - loss: 1.5284 - acc: 0.4610 - val_loss: 1.5811 - val_acc: 0.4424
Epoch 8/10
 - 27s - loss: 1.5040 - acc: 0.4700 - val_loss: 1.5773 - val_acc: 0.4487
Epoch 9/10
 - 28s - loss: 1.4814 - acc: 0.4756 - val_loss: 1.5819 - val_acc: 0.4403
Epoch 10/10
 - 28s - loss: 1.4498 - acc: 0.4880 - val_loss: 1.5422 - val_acc: 0.4462
Training time=281.99816966056824 Seconds
10000/10000 [==============================] - 3s 330us/step
Accuracy= 0.4502
[3 8 8 ... 5 4 7]

我把上面三種隱藏層神經元之訓練與預測準確率整理如下表 :


 hidden  acc (10th train)  val_acc (10th train) acc (predict)
 256 0.4810 0.4478 0.4526
 512 0.4885 0.4516 0.4564 (+0.84%)
 1024 0.4880 0.4462 0.4502 (-1.36%)


訓練結果圖形比較如下 :


隱藏層神經元數=256

隱藏層神經元數=512

隱藏層神經元數=1024


可見即使隱藏層神經元數目倍增, 準確率並未顯著提升, 甚至增至 1024 個隱藏層神經元時準確率竟然倒退.

參考 :

How to give CIFAR-10 as an input to MLP
# Numpy Quickstart tutorial

沒有留言 :