tensorflow調參總結(不斷更新中)

1 批處理

tf在進行批處理時,會需要用到均值與方差數據,而在批處理中使用的均值與方差不是單純的使用當前批數據的均值與方差,而是對會根據當前批均值方差和上一批維護的均值方差進行指數衰減求一個新的均值方差,而對slim中的batch_norm,需要注意以下幾點:
slim batch_norm函數的輸入參數中有一個decay,該參數能夠衡量使用指數衰減函數更新均值方差時,更新的速度,取值通常在0.999-0.99-0.9之間,值越小,代表更新速度越快,而值太大的話,有可能會導致均值方差更新太慢,而最後變成一個常量1,而這個值會導致模型性能較低很多.另外,如果出現過擬合時,也可以考慮增加均值和方差的更新速度,也就是減小decay

updates_collections參數,該參數有一個默認值,ops.GraphKeys.UPDATE_OPS,當取默認值時,slim會在當前批訓練完成後再更新均值和方差,這樣會存在一個問題,就是當前批數據使用的均值和方差總是慢一拍,最後導致訓練出來的模型性能較差。所以,一般需要將該值設爲None,這樣slim進行批處理時,會對均值和方差進行即時更新,批處理使用的就是最新的均值和方差。

另外,不論是即使更新還是一步訓練後再對所有均值方差一起更新,對測試數據是沒有影響的,即測試數據使用的都是保存的模型中的均值方差數據,但是如果你在訓練中需要測試,而忘了將is_training這個值改成false,那麼這批測試數據將會綜合當前批數據的均值方差和訓練數據的均值方差。而這樣做應該是不正確的。

關於均值與方差的更新總結,可以參見我的另一篇博客:

http://blog.csdn.net/liyuan123zhouhui/article/details/70598726

2 fine tune

在fine tune時,loss應該經過幾個批的數據後就會達到和以前一樣,如果loss一直很大的話,就有可能是因爲樣本中噪聲樣本太多,導致無法確定梯度方向,從而無法loss一直比較大,也還有一種可能,就是fine tune時某些層是需要重新訓練,某些層是需要fine tune的,這兩者的學習率可能會相差幾十到幾百倍,如果這兩者的學習率設置不恰當,也可能會導致loss一直很大。另外,根據實際經驗,當某些層需要固定,主觀上需要調試某些層時,不建議將固定的層學習率設置爲0,可以設置成一個非常小的數,比如0.0000001,這樣收斂速度比設置爲0時要快很多。

3 learning rate

對於學習率,個人認爲最好的設置方式就是手動,初始設置一個較大的學習率,0.1以上,如果經過幾個epoch以後,loss值不降低,那麼可以考慮將loss減小,減小至1/5,或減小至1/10。有可以借鑑的:http://www.cnblogs.com/neopenx/p/4480701.html

loss值一直不降,還有一個可能的原因是數據的初始化有問題,當然,前提是修改lr也沒有用時,可以考慮是這個原因

4  激活函數
一般初次選擇relu是沒有問題的,但是還存在一些其他的激活函數:
elu(指數線性單元)激活函數,該激活函數經過驗證,收斂速度比relu更快,另外,由於relu和elu都是不帶參數的激活函數,因此,如果你用relu訓練好一個網絡後,想試試看elu激活函數,初次測試,結果應該至少會打個8折,想要在elu網絡下獲得好的結果,還需要再訓練幾次,另外,在elu的文獻中提到,使用elu時,不使用批處理能夠比使用批處理獲得更好的效果,同時elu不使用批處理的效果比relu加批處理的效果要好。

elu文獻中給出的訓練與測試error:

文章地址:https://arxiv.org/pdf/1511.07289v5.pdf


crelu(級聯relu)激活函數,該激活函數個人的只管理解就是將relu中小於0的部分取了個絕對值,然後再級聯起來,因此,crelu不像relu和elu激活函數,進來多少通道,出去多少通道,crelu一般會將進來的通道數翻倍,翻倍的就是relu激活函數中的小於0的部分取絕對值作爲一個單獨的通道,因此,crelu也是一種減少網絡參數的方式,提出該激活函數的文章中說,在使用該激活函數後,能以更小的網絡參數獲得性能提升

文章地址

https://arxiv.org/pdf/1603.05201.pdf

更全面的激活函數介紹:

https://zhuanlan.zhihu.com/p/22142013

可以借鑑的網站:

https://kanghsi.gitbooks.io/deep-learning/cnnzhong_de_diao_can_zhi_dao.html

http://www.cnblogs.com/liujshi/p/5646102.html

http://blog.csdn.net/qq_20259459/article/details/70316511

關於網絡結構的一點總結
0 在網絡深度不是很深的時候,就沒必要使用resnet,因爲深度太深會導致梯度消失,而網絡不深的時候這個問題不明顯或不是主要問題
1 最好不要在卷積的時候加上stride大於1
2 如果需要stride大於1的時候,可以放在max pooling層去做,一般在max pooling後面加上一個批處理能夠加速收斂
3 不一定每一次卷積後都要加上批處理,可以在卷積的時候不做,在max pooling的時候再做(還沒試過效果)
4 對於同一個圖像尺寸大小的通道,可以至少學習兩次,以防止學習不充分
5 caffe一般在最後一個池化層會有全局的池化,注意要加上global_pooling: true,否則即使你的池化後的大小也是1xnx1x1,也會報錯,


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