基於keras的CNN圖片分類模型的搭建以及參數調試

基於keras的CNN圖片分類模型的搭建與調參


更新一下這篇博客,因爲最近在CNN調參方面取得了一些進展,順便做一下總結。


我的項目目標是搭建一個可以分五類的卷積神經網絡,然後我找了一些資料看了一些博客,發現keras搭建CNN,還是比較簡單快捷的,模塊化,易擴展,極簡,讓我最終選擇了keras。本質上keras相對於python,就相當於python相對於c/c++。就是一個封裝的一個關係。

然後講講我的模型吧。我的模型是由兩層卷積層,兩層池化層,兩層全連接層組成。這個結構 應該算是最簡單的卷積神經網絡了。可調的參數也並不多。整個分類系統代碼組成也很簡單,主要就三部分,一個是數據讀取處理部分,一個是模型訓練部分,一個是模型測試部分。我分類的數據集是通過熱成像儀拍攝得到的熱成像圖,然後經過簡單處理之後得到的灰度圖。原本這個模型是一個人臉識別系統,把其中攝像頭拍攝部分去掉了。只保留圖像分類部分的代碼,就做成了我的系統了。基本思想還是很簡單的。

但是在接觸了代碼之後,還是發現了很多坑。經過掉坑,爬坑的洗禮之後,寫下這篇博客,記載下一些有價值的知識。

1. 數據讀取

這裏寫圖片描述

這部分代碼開始我就沒讀懂 ,reshape函數不是將圖片的大小改變的嘛?咋改成了四維的?
查了好多博客,都沒說出個所以然。後來我想起手上還有三本TensorFlow的電子書,通過書終於發現了問題所在。
這裏寫圖片描述
這段代碼(來自《TensorFlow技術解析與實戰》)表示keras分別以theano和TensorFlow爲backend實現圖像大小重置與存取的區別。同時我還明白了這個代碼裏面各個參數代表的意思。就比如TensorFlow的吧。

x_test=x_test.reshape(x_test.shape[0],img_rows,img_cols,1)

這個x_test.shape[0]表示總共有多少個照片,因爲當時讀進照片數據的時候,照片都被放在了list裏面了,然後他的大小就是整個list就是照片的數目。然後img_rows,img_cols就是每張照片的大小。
.

2. 調參數

由於優化器和批歸一化,對最終的結果產生了很大的影響,我將在下面的內容詳細地解釋一下這兩者的優化原理。


要將一個模型的性能達到一個比較高的水準,必定需要調節相關的參數。作爲一名小白。一開始我是一臉悶逼的。不知道該調哪些參數,不知道應該調到多大的數值纔算合適。雖然現在的分類準確率還是沒達到一個令人滿意的程度,但是相較於開始已經提升了很多。先記下來一些吧。
我主要調整了兩個部分。

  • (一)輸入圖像的大小。這個是我在數據讀取部分改的。我將讀入的圖片長寬調整的更加接近。
  • (二)增加了dropout函數,dropout函數說白了就是在訓練時將部分神經元暫停工作,提升模型的抗過擬合能力。我在每一層都加入了dropout函數,開始的兩層都是比較小的概率(0.15),後面到了全連接層比較大(0.5)
  • (三)將模型的優化器由原來的Adagrad,改爲adadelta。這一篇文章裏面給出了比較詳細的優化方法的總結:深度學習最全優化方法總結比較(SGD,Adagrad,Adadelta,Adam,Adamax,Nadam)這個地方,還有一個值得挖掘的地方就是模型的優化器,optimizor對最終結果影響原來這麼大。我在代碼中用到的優化器依次是Adagrad,adadelta,Adam,效果依次上升。

Adagrad:

Adagrad
nt=nt1+gt2
Δθt=ηnt+ϵgt
gt1tregularizer,Δθt=1r=1t(gr)2+ϵ,ϵ,0
特點:
前期gtregularizer
前期gtregularizer
適合處理稀疏梯度

Adadelta:

AdadeltaAdagradAdagradAdadelta
nt=vnt1+(1v)gt2
Δθt=ηnt+ϵgt
此處Adadelta
E|g2|t=ρE|g2|t1+(1ρ)gt2
Δxt=r=1t1ΔxrE|g2|t+ϵ
EAdadelta
特點:
訓練初中期,加速效果不錯,很快
訓練後期,反覆在局部最小值附近抖動

Adam:

Adam(AdaptiveMomentEstimation)RMSprop調Adam使
mt=μmt1+(1μ)gt
nt=vnt1+(1v)gt2
m^t=mt1μt
n^t=nt1vt
Δθt=m^tn^t+ϵη
mt,ntE|gt|,E|gt2|m^t,n^tmt,nt
調m^tn^t+ϵ
特點:
結合了AdagradRMSprop



  • (四)Batch_normalization(批歸一化處理)開始我沒注意到有這個優化手段。後來看了些別人博客,於是我想着嘗試一下這個BN,我在看的視頻裏面,也多次提及這個優化手段。但是在使用的時候,我就犯難了,到底應該把代碼加在哪兒呢?各種百度不得其解,後來百度了一下終於明白了。CNN with BatchNormalization in Keras 94% 這個代碼應用的也是keras實現的CNN,簡潔明瞭,適合小白。

我在這再講解一下批歸一化的原理和作用。
批歸一化也叫做批標準化,通俗來說就是對每一層神經網絡進行標準化,輸入數據進行標準化能讓機器學習更加有效地學習。除此之外batchnormalization 還能有效控制壞的參數初始化,比如說Relu 這種激勵函數最怕所有值都落在附屬區間。


但是現在遇到的一個問題是訓練的準確率還可以能夠達到90%+,但是測試準確率只有70%+,因此下一步準備將這個過擬合問題解決。等我將各方面問題解決好,我就會將代碼上傳到我的GitHub上,供大家學習借鑑。

對了,這一篇知乎專欄是我看到寫的比較好的調參博客《如何一步一步提高圖像分類準確率?》-曹榮禹,推薦一下

寫在最後關於CNN的學習,我開始了大約五六個月,當然這裏面是有間斷的,關於CNN的認識,現在好多還是停留在紙面上。沒法真正完美地解決工程問題。還需要繼續努力。以後有新技巧習得,再更!

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