最近幾個月為了寫小論文,題目是關於用深度學習做人臉檢索的,所以需要選擇一款合適的深度學習架構,caffe我學完以後感覺使用不是很方便,之後有人向我推薦了Keras,其簡單的風格吸引了我,之後的四個月我都一直在使用Keras架構,由於我用的時候,tensorflow的相關教程還不是很多,所以後端我使用theano。這次的心得主要分成兩篇,第一篇是聊聊開始使用keras容易遇到的坑,第二篇會在我論文發了之後,連同代碼和一些更細節的東西一起發出來,我也會在結尾放出一些自己收集的CNN和tensorflow的相關教程,就這樣。
先放上Keras官方中文文檔的連結:http://keras-cn.readthedocs.io/en/latest/
還有Keras的QQ群號:119427073
本文由淺入深聊一聊我在這個過程中遇到的一些問題: 1、Keras輸出的loss,val這些值如何儲存到文本中去:
Keras中的fit函數會返回一個History對象,它的History.history屬性會把之前的那些值全儲存在裡面,如果有驗證集的話,也包含了驗證集的這些指標變化情況,具體寫法:
hist=model.fit(train_set_x,train_set_y,batch_size=256,shuffle=True,nb_epoch=nb_epoch,validation_split=0.1)with open('log_sgd_big_32.txt','w') as f: f.write(str(hist.history))
我覺得儲存之前的loss,val這些值還是比較重要的,在之後的調參過程中有時候還是需要之前loss的結果作為參考的,特別是你自己添加了一些自己的loss的情況下,但是這樣的寫法會使整個文本的取名比較亂,所以其實可以考慮使用Aetros的外掛程式,Aetros網址,這是一個基於Keras的一個管理工具,可以可視化你的網路結構,中間卷積結果的可視化,以及儲存你以往跑的所有結果,還是很方便的,就是有些不穩定,有時候會崩。。。 2、關於訓練集,驗證集和測試集:
其實一開始我也沒搞清楚這個問題,拿著測試集當驗證集用,其實驗證集是從訓練集中抽取出來用於調參的,而測試集是和訓練集無交集的,用於測試所選參數用於該模型的效果的,這個還是不要弄錯了。。。在Keras中,驗證集的劃分只要在fit函數裡設定validation_split的值就好了,這個對應了取訓練集中百分之幾的資料出來當做驗證集。但由於shuffle是在validation _split之後執行的,所以如果一開始訓練集沒有shuffle的話,有可能使驗證集全是負樣本。測試集的使用只要在evaluate函數裡設定就好了。
print model.evaluate(test_set_x,test_set_y ,batch_size=256)
這裡注意evaluate和fit函數的預設batch_size都是32,自己記得修改。 3、關於最佳化方法使用的問題:
開始總會糾結哪個最佳化方法好用,但是最好的辦法就是試,無數次嘗試後不難發現,Sgd的這種學習率非自適應的最佳化方法,調整學習率和初始化的方法會使它的結果有很大不同,但是由於收斂確實不快,總感覺不是很方便,我覺得之前一直使用Sgd的原因一方面是因為最佳化方法不多,其次是用Sgd都能有這麼好的結果,說明你網路該有多好啊。其他的Adam,Adade,RMSprop結果都差不多,Nadam因為是adam的動量添加的版本,在收斂效果上會更出色。所以如果對結果不滿意的話,就把這些方法換著來一遍吧。
有很多初學者人會好奇怎麼使sgd的學習率動態變化,其實Keras裡有個反饋函數叫LearningRateScheduler,具體使用如下:
def step_decay(epoch): initial_lrate = 0.01 drop = 0.5 epochs_drop = 10.0 lrate = initial_lrate * math.pow(drop,math.floor((1+epoch)/epochs_drop)) return lratelrate = LearningRateScheduler(step_decay)sgd = SGD(lr=0.0, momentum=0.9, decay=0.0, nesterov=False)model.fit(train_set_x, train_set_y, validation_split=0.1, nb_epoch=200, batch_size=256, callbacks=[lrate])
上面代碼是使學習率指數下降,具體如下圖:
當然也可以直接在sgd聲明函數中修改參數來直接修改學習率,學習率變化如下圖:
sgd = SGD(lr=learning_rate, decay=learning_rate/nb_epoch, momentum=0.9, nesterov=True)
具體可以參考這篇文章Using Learning Rate Schedules for Deep Learning Models in Python with Keras 4、關於過擬合問題的討論:
我現在所知道的解決方案大致只有兩種,第一種就是添加dropout層,dropout的原理我就不多說了,主要說一些它的用法,dropout可以放在很多類層的後面,用來抑制過擬合現象,常見的可以直接放在Dense層後面,對於在Convolutional和Maxpooling層中dropout應該放置在Convolutional和Maxpooling之間,還是Maxpooling後面的說法,我的建議是試。這兩种放置方法我都見過,但是孰優孰劣我也不好說,但是大部分見到的都是放在Convolutional和Maxpooling之間。關於Dropout參數的選擇,這也是只能不斷去試,但是我發現一個問題,在Dropout設定0.5以上時,會有驗證集精度普遍高於訓練集精度的現象發生,但是對驗證集精度並沒有太大影響,相反結果卻不錯,我的解釋是Dropout相當於Ensemble,dropout過大相當於多個模型的結合,一些差模型會拉低訓練集的精度。當然,這也只是我的猜測,大家有好的解釋,不妨留言討論一下。
當然還有第二種就是使用參數正則化,也就是在一些層的聲明中加入L1或L2正則化係數,正則化的原理什麼的我就不細說了,具體看代碼:
C1 = Convolution2D(20, 4, 4, border_mode='valid', init='he_uniform', activation='relu',W_regularizer=l2(regularizer_params))
其中W_regularizer=l2(regularizer_params)就是用於設定正則化的係數,這個對於過擬合有著不錯的效果,在一定程度上提升了模型的泛化能力。 5、Batchnormalization層的放置問題:
BN層是真的吊,簡直神器,除了會使網路搭建的時間和每個epoch的時間延長一點之外,但是關於這個問題我看到了無數的說法,對於卷積和池化層的放法,又說放中間的,也有說池化層後面的,對於dropout層,有說放在它後面的,也有說放在它前面的,對於這個問題我的說法還是試。雖然麻煩。。。但是DL本來不就是一個偏工程性的學科嗎。。。還有一點是需要注意的,就是BN層的參數問題,我一開始也沒有注意到,仔細看BN層的參數:
keras.layers.normalization.BatchNormalization(epsilon=1e-06, mode=0, axis=-1, momentum=0.9, weights=None, beta_init='zero', gamma_init='one')
mode:整數,指定正常化的模式,取0或1
0:按特徵正常化,輸入的各個特徵圖將獨立被正常化。正常化的軸由參數axis指定。注意,如果輸入是形如(samples,channels,rows,cols)的4D映像張量,則應設定正常化的軸為1,即沿著通道軸正常化。輸入格式是‘tf’同理。
1:按樣本正常化,該模式預設輸入為2D
我們大都使用的都是mode=0也就是按特徵正常化,對於放置在卷積和池化之間或之後的4D張量,需要設定axis=1,而Dense層之後的BN層則直接使用預設值就好了。
總結
這次暫時先寫這麼多,這次寫的比較淺,還有很多拓展的東西都下次再寫了,下面給大家附上一些不錯的資料吧~
CNN基礎:
【1】你真的瞭解CNN網路嗎。
【2】CNN近期發展和實用技巧(上)
【3】深度 | 從入門到精通:卷積神經網路初學者指南(附論文)
【4】Convolutional Neural Networks (CNNs): An Illustrated Explanation
【5】Convolutional Neural Networks backpropagation: from intuition to derivation
【6】賀完結。CS231n官方筆記授權翻譯總集篇發布
DL和Keras相關:
【1】深度學習中的啟用函數導引
【2】深度網路的過擬合問題討論
【3】How To Improve Deep Learning Performance
【4】深度學習最全最佳化方法總結比較(SGD,Adagrad,Adadelta,Adam,Adamax,Nadam)
【5】Keras/Python深度學習中的網格搜尋超參數調優(附源碼)
【6】Yoshua Bengio等大神傳授:26條深度學習經驗
【7】leriomaggio/deep-learning-keras-euroscipy2016
Tensorflow相關:
【1】TensorFlow深度學習,一篇文章就夠了
【2】alrojo/tensorflow-tutorial
【3】莫煩 tensorflow 神經網路 教程