2018年3月25日 星期日

深度學習(7)--使用Tensorflow實現類VGG model 訓練Cifar10數據集


    繼上一篇我們使用Alexnet 模型來訓練Cifar10數據集,這次我們改用VGG16 模型來做訓練及預測。Cifar10的數據集可以從以下網址下載:
https://www.cs.toronto.edu/~kriz/cifar.html

     從本質上來看,VGGNet 是在更細的粒度上實現的AlexNet,他廣泛的使用非常小的卷積核架構去實現更深層次的卷積網路神經網路。在一定的程度上證實了,增加卷積神經網路的深度,增加更多的隱藏層和權重可以實現對識別的明顯改進。

    從VGGNet的結構上來說,與AlexNet並沒有太大的區別,只不過增加了更多隱藏層,VGG的參數較多調整範圍大,而最終生成的模型參數是AlexNet的3倍左右,VGGNet的模型圖如下圖所示:


<picture 1> VGGNet的模型圖 , citation: htpps://arxiv.org/pdf/1409.1556.pdf



    對於這個模型分解來看,一個完整的卷積層可能包含一層Convolution,一層Rectified Linear Units,一層max-pooling,一層Normalization。而整個網路的結構包含5層卷積層及3層全連接層,網路最前端是輸入圖片的原始像素點,最後端是圖片的分類結果。
    相對AlexNet來說,VGG有更多的輸出channel,即輸出通道,因此可以達到更高和更細粒度的準確性,可以提取出來更多的信息。

    VGGNet 和AlexNet特點如下:

相同點:
1.最後都是使用全連接層作為計算結果
2.同樣使用5層卷積層
3.每層之間使用pooling層分割

不同點:
1.VGGNet中的卷積層卷積核大小為[3,3]大小,而AlexNet中卷積核為[7,7]大小,
   VGGNet通過模擬AlexNet的結構減少了卷積核而增加了層數。
2.VGGNet有更多的Channel數  


<table1> citation: htpps://arxiv.org/pdf/1409.1556.pdf




    在這裡我們使用VGG16模型來訓練Cifar10數據集,有關Cifar10數據集可以參考前一篇
深度學習(6)--使用Tensorflow實現類AlexNet model 訓練Cifar10數據集

     由於Cifar10數據集的原始圖形像素大小為32x32x3,而VGG16原本輸入的圖形像素為224x224x3,因此為了配合Cifar10數據集,我修改了VGG16模型輸入圖形像素大小為32x32x3。而在做卷積時則維持圖形像素大小,而在做pooling時才做縮小尺寸的處理,
一樣採用五層卷積層三層全連接層,最後輸出分類為10類,符合Cifar10數據集的輸出分類。
    圖形像素大小如同下圖所示,由於32x32x3太小,故第一層的pooling也做保持大小的動作沒改變尺寸,最後一層的輸出層則為10個輸出,各個卷積層的channel深度則是與VGG16一致。

<Picture 2>


    值得注意的是各個卷積層及全連接層皆有做Batch Normalization,如下圖3,4所示:
大家可以試試如果不做這動作,在訓練上會發生什麼事?我遇到的狀況是,訓練到兩三百次之後,loss即不再下降,準確度也不再提升,感覺無法收斂,應是遇到梯度消失的問題。


<Picture3>


<Picture4>


另外在這個實驗裡,使用AdamOptimizer會比GradientDescentOptimizer訓練速度快好幾倍,大家也可以試看看。
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)
optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate).minimize(cost)

最後經過4200次疊代訓練出來的結果如下圖所示:

<Picture 5>



   訓練好後評估測試資料集,可以得到80.5%的準確率,還是有overfiting的現象。但是這結果
比起使用一樣數據集的Alexnet的0.69結果好。
<Picture 6>



     最後我從google上任意下載20張飛機的照片,想試試這個訓練好的模型泛化的能力如何?
也就是這20張飛機圖示不在Cifar10數據集裡的,結果是令人失望的,只有3張被認為是飛機。也就是泛化能力還是不佳,雖然使用了cifar10 五萬張的圖片去訓練,但用在實際生活環境上的辨認能力還是不足,這也是為什麼Deep learning需要大量的數據去訓練,越多越好。

<Picture 7>



全部代碼可以從底下連結獲取:
https://github.com/Ashing00/Tensorflow_VGG/tree/master
vgg_train.py  為主要的訓練程式
vgg_inference.py  主要定義了VGG16的模型結構
vgg_eval.py     用來評估測試的數據集
vgg_test.py      使用額外的圖片來評估泛化能力

<參考資料>
[1]書名:Tensorflow 深度學習應用實戰 作者:王曉華
[2]Very Deep Convolutional Networks for Large-Scale Image Recognition


<其他相關文章>
人工神經網路(1)--使用Python實作perceptron(感知器)
人工神經網路(2)--使用Python實作後向傳遞神經網路演算法(Backprogation artificial neature network)
深度學習(1)-如何在windows安裝Theano +Keras +Tensorflow並使用GPU加速訓練神經網路
深度學習(2)--使用Tensorflow實作卷積神經網路(Convolutional neural network,CNN)
深度學習(3)--循環神經網絡(RNN, Recurrent Neural Networks)
深度學習(4)--使用Tensorflow實現類Lenet5手寫數字辨識
深度學習(5)--使用Tensorflow實現類AlexNet手寫數字辨識
深度學習(6)--使用Tensorflow實現類AlexNet model 訓練Cifar10數據集

機器學習(1)--使用OPENCV KNN實作手寫辨識
機器學習(2)--使用OPENCV SVM實作手寫辨識
機器學習(3)--適應線性神經元與梯度下降法(Adaline neuron and Gradient descent)
機器學習(4)--資料標準常態化與隨機梯度下降法( standardization & Stochastic Gradient descent)
機器學習(5)--邏輯斯迴歸,過度適合與正規化( Logistic regression,overfitting and regularization)
機器學習(6)--主成分分析(Principal component analysis,PCA)
機器學習(7)--利用核主成分分析(Kernel PCA)處理非線性對應
機器學習(8)--實作多層感知器(Multilayer Perceptron,MLP)手寫數字辨識