天天看點

cnn調優總結

cnn調優總結

針對cnn優化的總結

使用沒有 batchnorm 的 elu 非線性或者有 batchnorm 的 relu。

用類似1*1的網絡結構預訓練rgb資料,能得到更好的效果。

使用線性學習率衰退政策。

使用平均和最大池化層的和。

使用大約 128(0.005) 到 256 (0.01)的 mini-batch 大小。如果這對你的 gpu 而言太大,将學習率按比例降到這個大小就行。

使用卷積層代替之前的mlp中的線性層,并用平均池化層預測。

當研究增加訓練集大小的時候,需要确定資料集對性能提升的平衡點。

資料的品質要比資料大小更重要。

如果你不能增加輸入圖像的大小,在随後的層上減少步幅(stride),這樣做有同樣的效果。

如果你的網絡有複雜和高度優化的架構,像是 googlenet,那修改一定要謹慎。

其他可以詳細看看論文,作者很辛苦的對比了各種超參數對cnn模型性能的影響,非常值得一看。

cnn調優總結

有助于充分利用 dnn 的小技巧

記得要 shuffle。不要讓你的網絡通過完全相同的 minibatch,如果架構允許,在每個 epoch 都 shuffle 一次。

擴充資料集。dnn 需要大量的資料,而且模型在小的資料集上很容易過拟合。我強烈建議你要擴充原始的資料集。如果你的是一個視覺任務,可以增加噪點、增白,減少像素,旋轉或色移,模糊,等等可以擴充的一切。有一點不好的是,假如你擴充得太大,可能訓練的資料大多數是相同的。我建立了一個應用随機變換的層來解決這個問題,這樣就不會有相同的樣本。若果你用的是語音資料,可以進行移位和失真處理。

在整個資料集上訓練之前,先在非常小的子資料集上訓練進行過拟合,這樣你會知道你的網絡可以收斂。這個 tip 來自 karpathy。

始終使用 dropout 将過拟合的幾率最小化。在大小 > 256 (完全連接配接層或卷積層)之後就應該使用 dropout。關于這一點有一篇很好的論文:dropout as a bayesian approximation: representing model uncertainty in deep learning [gal yarin & zoubin ghahramani,2015].

避免 lrn 池化,max 池化會更快。

避免 sigmoid/tanh 的門,它們代價昂貴,容易飽和,而且可能會停止反向傳播。實際上,你的網絡越深,就越應該避免使用 sigmoid 和 tanh。可以使用更便宜而且更有效的 relu 和 prelu 的門,正如在 yoshua bengio 等人的論文 deep sparse rectifier neural networks 中所提到的,這兩者能夠促進稀疏性,而且它們的反向傳播更加魯棒。

在最大池化之前不要使用 relu 或 prelu ,而是在儲存計算之後使用它。

 不要使用 relu ,它們太舊了。雖然他們是非常有用的非線性函數,可以解決很多問題。但是,你可以試試用它微調一個新模型,由于 relu 阻礙反向傳播,初始化不好,你沒法得到任何微調效果。但是你應該用 prelu 以及一個非常小的乘數,通常是0.1。使用 prelu 的話收斂更快,而且不會像 relu 那樣在初始階段被卡住。elu 也很好,但成本高。

經常使用批标準化。參考論文:batch normalization: accelerating deep network training by reducing internal covariate shift [sergey ioffe & christian szegedy,2015]。這會很有效。批标準化允許更快的收斂(非常快)以及更小的資料集。這樣你能夠節省時間和資源。

雖然大多數人喜歡删除平均值,不過我不喜歡。我喜歡壓縮輸入資料為[-1,+1]。這可以說是訓練和部署方面的技巧,而不是針對提升性能的技巧。

要能适用更小的模型。假如你是像我這樣部署深度學習模型,你很快就會體會到把千兆位元組規模的模型推給使用者或地球另一端的伺服器的痛苦。哪怕要犧牲一些準确度,也應該小型化。

假如你使用比較小的模型,可以試試 ensemble。通常 ensemble 5個網絡能夠提升準确度約3%。

盡可能使用 xavier 初始化。你可以隻在大的完全連接配接層上使用它,然後避免在 cnn 層上使用。有關這點的解釋可以閱讀這篇文章:an explanation of xavier initialization(by andy jones)

如果你的輸入資料有空間參數,可以試試端到端的 cnn。可以閱讀這篇論文:squeezenet: alexnet-level accuracy with 50x fewer parameters and <0.5mb model size [forrest n. iandola et. al. 2016],它介紹了一種新的方法,而且性能非常好,你可以嘗試應用上面提到的tips。

修改你的模型,隻要可能就使用 1x1 的 cnn 層,它的位置對提高性能很有幫助。

假如沒有高端的 gpu,就不要嘗試訓練任何東西了。

假如你要利用模型或你自己的層來制作模闆,記得把所有東西參數化,否則你得重建所有二進制檔案。

最後,要明白你在做什麼。深度學習就像是機器學習裡的中子彈,它不是任何任務、任何時候都有效的。了解你正在使用的結構以及你試圖達成的目的,才不至于盲目地複制模型。

提升算法性能思路

這個清單裡提到的思路并完全,但是一個好的開始。

我的目的是給出很多可以嘗試的思路,希望其中的一或兩個你之前沒有想到。你經常隻需要一個好的想法就能得到性能提升。

如果你能從其中一個思路中得到結果,請在評論區告訴我。我很高興能得知這些好消息。

如果你有更多的想法,或者是所列思路的拓展,也請告訴我,我和其他讀者都将受益!有時候僅僅是一個想法或許就能使他人得到突破。

我将此博文分為四個部分: 

通常來講,随着清單自上而下,性能的提升也将變小。例如,對問題進行新的架構或者擷取更多的資料,通常比調整最優算法的參數能帶來更好的效果。雖然并不總是這樣,但是通常來講是的。

我已經把相應的連結加入了部落格的教程中,相應網站的問題中,以及經典的neural net faq中。

部分思路隻适用于人工神經網絡,但是大部分是通用的。通用到足夠你用來配合其他技術來碰撞出提升模型性能的方法。

ok,現在讓我們開始吧。

1. 通過資料提升性能

對你的訓練資料和問題定義進行适當改變,你能得到很大的性能提升。或許是最大的性能提升。

以下是我将要提到的思路:

擷取更多資料

創造更多資料

重放縮你的資料

轉換你的資料

特征選取

重架構你的問題

你能擷取更多訓練資料嗎? 

你的模型的品質通常受到你的訓練資料品質的限制。為了得到最好的模型,你首先應該想辦法獲得最好的資料。你也想盡可能多的獲得那些最好的資料。

有更多的資料,深度學習和其他現代的非線性機器學習技術有更全的學習源,能學得更好,深度學習尤為如此。這也是機器學習對大家充滿吸引力的很大一個原因(世界到處都是資料)。

更多的資料并不是總是有用,但是确實有幫助。于我而言,如果可以,我會選擇擷取更多的資料。

可以參見以下相關閱讀: · datasets over algorithms(www.edge.org/response-detail/26587)

2) 創造更多資料

上一小節說到了有了更多資料,深度學習算法通常會變的更好。有些時候你可能無法合理地擷取更多資料,那你可以試試創造更多資料。

如果你的資料是數值型向量,可以随機構造已有向量的修改版本。

如果你的資料是圖檔,可以随機構造已有圖檔的修改版本(平移、截取、旋轉等)。

如果你的資料是文本,類似的操作……

這通常被稱作資料擴增(data augmentation)或者資料生成(data generation)。

你可以利用一個生成模型。你也可以用一些簡單的技巧。例如,針對圖檔資料,你可以通過随機地平移或旋轉已有圖檔擷取性能的提升。如果新資料中包含了這種轉換,則提升了模型的泛化能力。

這也與增加噪聲是相關的,我們習慣稱之為增加擾動。它起到了與正則化方法類似的作用,即抑制訓練資料的過拟合。

以下是相關閱讀:

image augmentation for deep learning with keras(http://machinelearningmastery.com/image-augmentation-deep-learning-keras/)

what is jitter? (training with noise)(ftp://ftp.sas.com/pub/neural/faq3.html#a_jitter)

這是一個快速獲得性能提升的方法。 當應用神經網絡時,一個傳統的經驗法則是:重縮放(rescale)你的資料至激活函數的邊界。

如果你在使用sigmoid激活函數,重縮放你的資料到0和1的區間裡。如果你在使用雙曲正切(tanh)激活函數,重縮放資料到-1和1的區間裡。

這種方法可以被應用到輸入資料(x)和輸出資料(y)。例如,如果你在輸出層使用sigmoid函數去預測二進制分類的結果,應當标準化y值,使之成為二進制的。如果你在使用softmax函數,你依舊可以通過标準化y值來獲益。

這依舊是一個好的經驗法則,但是我想更深入一點。我建議你可以參考下述方法來創造一些訓練資料的不同的版本:

歸一化到0和1的區間。

重放縮到-1和1的區間

标準化(譯者注:标準化資料使之成為零均值,機關标準差)

然後對每一種方法,評估你的模型的性能,選取最好的進行使用。如果你改變了你的激活函數,重複這一過程。

在神經網絡中,大的數值累積效應(疊加疊乘)并不是好事,除上述方法之外,還有其他的方法來控制你的神經網絡中資料的數值大小,譬如歸一化激活函數和權重,我們會在以後讨論這些技術。

以下為相關閱讀:

should i standardize the input variables (column vectors)?(ftp://ftp.sas.com/pub/neural/faq2.html#a_std)

how to prepare your data for machine learning in python with scikit-learn(http://machinelearningmastery.com/prepare-data-machine-learning-python-scikit-learn/)

這裡的資料變換與上述的重縮放方法類似,但需要更多工作。 你必須非常熟悉你的資料。通過可視化來考察離群點。

猜測每一列資料的單變量分布。

列資料看起來像偏斜的高斯分布嗎?考慮用box-cox變換調整偏态。

列資料看起來像指數分布嗎?考慮用對數變換。

列資料看起來有一些特征,但是它們被一些明顯的東西遮蓋了,嘗試取平方或者開平方根來轉換資料

你能離散化一個特征或者以某種方式組合特征,來更好地突出一些特征嗎?

依靠你的直覺,嘗試以下方法。

你能利用類似pca的投影方法來預處理資料嗎?

你能綜合多元特征至一個單一數值(特征)嗎?

你能用一個新的布爾标簽去發現問題中存在一些有趣的方面嗎?

你能用其他方法探索出目前場景下的其他特殊結構嗎?

神經網層擅長特征學習(feature engineering)。它(自己)可以做到這件事。但是如果你能更好的發現問題到網絡中的結構,神經網層會學習地更快。你可以對你的資料就不同的轉換方式進行抽樣調查,或者嘗試特定的性質,來看哪些有用,哪些沒用。

how to define your machine learning problem(http://machinelearningmastery.com/how-to-define-your-machine-learning-problem/)

discover feature engineering, how to engineer features and how to get good at it(http://machinelearningmastery.com/discover-feature-engineering-how-to-engineer-features-and-how-to-get-good-at-it/)

一般說來,神經網絡對不相關的特征是具有魯棒的(校對注:即不相關的特征不會很大影響神經網絡的訓練和效果)。它們會用近似于0的權重來弱化那些沒有預測能力的特征的貢獻。

盡管如此,這些無關的資料特征,在訓練周期依舊要耗費大量的資源。是以你能去除資料裡的一些特征嗎?

有許多特征選擇的方法和特征重要性的方法,這些方法能夠給你提供思路,哪些特征該保留,哪些特征該剔除。最簡單的方式就是對比所有特征和部分特征的效果。同樣的,如果你有時間,我建議在同一個網絡中嘗試選擇不同的視角來看待你的問題,評估它們,來看看分别有怎樣的性能。

或許你利用更少的特征就能達到同等甚至更好的性能。而且,這将使模型變得更快!

或許所有的特征選擇方法都剔除了同樣的特征子集。很好,這些方法在沒用的特征上達成了一緻。

或許篩選過後的特征子集,能帶給特征工程的新思路。

an introduction to feature selection(http://machinelearningmastery.com/an-introduction-to-feature-selection/)

feature selection for machine learning in python(http://machinelearningmastery.com/feature-selection-machine-learning-python/)

有時候要試試從你目前定義的問題中跳出來,想想你所收集到的觀察值是定義你問題的唯一方式嗎?或許存在其他方法。或許其他建構問題的方式能夠更好地揭示待學習問題的結構。

我真的很喜歡這個嘗試,因為它迫使你打開自己的思路。這确實很難,尤其是當你已經對目前的方法投入了大量的時間和金錢時。

但是咱們這麼想想,即使你列出了3-5個可供替代的建構方案,而且最終還是放棄了它們,但這至少說明你對目前的方案更加自信了。

看看能夠在一個時間窗(時間周期)内對已有的特征/資料做一個合并。

或許你的分類問題可以成為一個回歸問題(有時候是回歸到分類)。

或許你的二進制輸出可以變成softmax輸出?

或許你可以轉而對子問題進行模組化。

仔細思考你的問題,最好在你標明工具之前就考慮用不同方法建構你的問題,因為此時你對解決方案并沒有花費太多的投入。除此之外,如果你在某個問題上卡住了,這樣一個簡單的嘗試能釋放更多新的想法。

而且,這并不代表你之前的工作白幹了,關于這點你可以看看後續的模型嵌套部分。

通過算法提升性能

機器學習當然是用算法解決問題。

所有的理論和數學都是描繪了應用不同的方法從資料中學習一個決策過程(如果我們這裡隻讨論預測模型)。

你已經選擇了深度學習來解釋你的問題。但是這真的是最好的選擇嗎?在這一節中,我們會在深入到如何最大地發掘你所選擇的深度學習方法之前,接觸一些算法選擇上的思路。

下面是一個簡要清單:

對算法進行抽樣調查

借鑒已有文獻

重采樣方法

下面我解釋下上面提到的幾個方法。

其實你事先無法知道,針對你的問題哪個算法是最優的。如果你知道,你可能就不需要機器學習了。那有沒有什麼資料(辦法)可以證明你選擇的方法是正确的?

讓我們來解決這個難題。當從所有可能的問題中平均來看各算法的性能時,沒有哪個算法能夠永遠勝過其他算法。所有的算法都是平等的,下面是在no free lunch theorem中的一個總結。

或許你選擇的算法不是針對你的問題最優的那個

我們不是在嘗試解決所有問題,算法世界中有很多新熱的方法,可是它們可能并不是針對你資料集的最優算法。

我的建議是收集(證據)資料名額。接受更好的算法或許存在這一觀點,并且給予其他算法在解決你的問題上“公平競争”的機會。

抽樣調查一系列可行的方法,來看看哪些還不錯,哪些不理想。

首先嘗試評估一些線性方法,例如邏輯回歸(logistic regression)和線性判别分析(linear discriminate analysis)。

評估一些樹類模型,例如cart, 随機森林(random forest)和gradient boosting。

評估一些執行個體方法,例如支援向量機(svm)和k-近鄰(knn)。

評估一些其他的神經網絡方法,例如lvq, mlp, cnn, lstm, hybrids等

選取性能最好的算法,然後通過進一步的調參和資料準備來提升。尤其注意對比一下深度學習和其他正常機器學習方法,對上述結果進行排名,比較他們的優劣。

很多時候你會發現在你的問題上可以不用深度學習,而是使用一些更簡單,訓練速度更快,甚至是更容易了解的算法。

a data-driven approach to machine learning(http://machinelearningmastery.com/a-data-driven-approach-to-machine-learning/)

why you should be spot-checking algorithms on your machine learning problems(http://machinelearningmastery.com/why-you-should-be-spot-checking-algorithms-on-your-machine-learning-problems/)

spot-check classification machine learning algorithms in python with scikit-learn(http://machinelearningmastery.com/spot-check-classification-machine-learning-algorithms-python-scikit-learn/)

方法選擇的一個捷徑是借鑒已有的文獻資料。可能有人已經研究過與你的問題相關的問題,你可以看看他們用的什麼方法。

你可以閱讀論文,書籍,部落格,問答網站,教程,以及任何能在谷歌搜尋到的東西。

寫下所有的想法,然後用你的方式把他們研究一遍。

這不是複制别人的研究,而是啟發你想出新的想法,一些你從沒想到但是卻有可能帶來性能提升的想法。

發表的研究通常都是非常贊的。世界上有非常多聰明的人,寫了很多有趣的東西。你應當好好挖掘這個“圖書館”,找到你想要的東西。

how to research a machine learning algorithm(http://machinelearningmastery.com/how-to-research-a-machine-learning-algorithm/)

google scholar(http://scholar.google.com/)

你必須知道你的模型效果如何。你對模型性能的估計可靠嗎?

深度學習模型在訓練階段非常緩慢。這通常意味着,我們無法用一些常用的方法,例如k層交叉驗證,去估計模型的性能。

或許你在使用一個簡單的訓練集/測試集分割,這是正常套路。如果是這樣,你需要確定這種分割針對你的問題具有代表性。單變量統計和可視化是一個好的開始。

或許你能利用硬體來加速估計的過程。例如,如果你有叢集或者aws雲端服務(amazon web services)賬号,你可以并行地訓練n個模型,然後擷取結果的均值和标準差來得到更魯棒的估計。

或許你可以利用hold-out驗證方法來了解模型在訓練後的性能(這在早停法(early stopping)中很有用,後面會講到)。

或許你可以先隐藏一個完全沒用過的驗證集,等到你已經完成模型選擇之後再使用它。

而有時候另外的方式,或許你能夠讓資料集變得更小,以及使用更強的重采樣方法。

有些情況下你會發現在訓練集的一部分樣本上訓練得到的模型的性能,和在整個資料集上訓練得到的模型的性能有很強的相關性。也許你可以先在小資料集上完成模型選擇和參數調優,然後再将最終的方法擴充到全部資料集上。

或許你可以用某些方式限制資料集,隻取一部分樣本,然後用它進行全部的模組化過程。

evaluate the performance of deep learning models in keras(http://machinelearningmastery.com/evaluate-performance-deep-learning-models-keras/)

evaluate the performance of machine learning algorithms in python using resampling(http://machinelearningmastery.com/evaluate-performance-machine-learning-algorithms-python-using-resampling/)

通過算法調參提升性能

這通常是工作的關鍵所在。你經常可以通過抽樣調查快速地發現一個或兩個性能優秀的算法。但是如果想得到最優的算法可能需要幾天,幾周,甚至幾個月。

為了獲得更優的模型,以下是對神經網絡算法進行參數調優的幾點思路:

診斷(diagnostics)

權重初始化(weight initialization)

學習速率(learning rate)

激活函數

網絡拓撲(network topology)

批次和周期(batches and epochs)

正則化

優化和損失

早停法

你可能需要訓練一個給定“參數配置”的神經網絡模型很多次(3-10次甚至更多),才能得到一個估計性能不錯的參數配置。這一點幾乎适用于這一節中你能夠調參的所有方面。

關于超參數優化請參閱博文:

how to grid search hyperparameters for deep learning models in python with keras(http://machinelearningmastery.com/grid-search-hyperparameters-deep-learning-models-python-keras/)

如果你能知道為什麼你的模型性能不再提高了,你就能獲得擁有更好性能的模型。

你的模型是過拟合還是欠拟合?永遠牢記這個問題。永遠。

模型總是會遇到過拟合或者欠拟合,隻是程度不同罷了。一個快速了解模型學習行為的方法是,在每個周期,評估模型在訓練集和驗證集上的表現,并作出圖表。

如果訓練集上的模型總是優于驗證集上的模型,你可能遇到了過拟合,你可以使用諸如正則化的方法。

如果訓練集和驗證集上的模型都很差,你可能遇到了欠拟合,你可以提升網絡的容量,以及訓練更多或者更久。

如果有一個拐點存在,在那之後訓練集上的模型開始優于驗證集上的模型,你可能需要使用早停法。

經常畫一畫這些圖表,學習它們來了解不同的方法,你能夠提升模型的性能。這些圖表可能是你能創造的最有價值的(模型狀态)診斷資訊。

另一個有用的診斷是網絡模型判定對和判定錯的觀察值。

對于難以訓練的樣本,或許你需要更多的資料。

或許你應該剔除訓練集中易于模組化的多餘的樣本。

也許可以嘗試對訓練集劃分不同的區域,在特定區域中用更專長的模型。

display deep learning model training history in keras(http://machinelearningmastery.com/display-deep-learning-model-training-history-in-keras/)

overfitting and underfitting with machine learning algorithms(http://machinelearningmastery.com/overfitting-and-underfitting-with-machine-learning-algorithms/)

經驗法則通常是:用小的随機數進行初始化。

在實踐中,這可能依舊效果不錯,但是對于你的網絡來說是最佳的嗎?對于不同的激活函數也有一些啟發式的初始化方法,但是在實踐應用中并沒有太多不同。

固定你的網絡,然後嘗試多種初始化方式。

記住,權重是你的模型真正的參數,你需要找到他們。有很多組權重都能有不錯的性能表現,但我們要盡量找到最好的。

嘗試所有不同的初始化方法,考察是否有一種方法在其他情況不變的情況下(效果)更優。

嘗試用無監督的方法,例如自動編碼(autoencoder),來進行預先學習。

嘗試使用一個已經存在的模型,隻是針對你的問題重新訓練輸入層和輸出層(遷移學習(transfer learning))

需要提醒的一點是,改變權重初始化方法和激活函數,甚至優化函數/損失函數緊密相關。

initialization of deep networks(http://deepdish.io/2015/02/24/network-initialization/)

調整學習率很多時候也是行之有效的時段。

以下是可供探索的一些想法:

實驗很大和很小的學習率

格點搜尋文獻裡常見的學習速率值,考察你能學習多深的網絡。

嘗試随周期遞減的學習率

嘗試經過固定周期數後按比例減小的學習率。

嘗試增加一個動量項(momentum term),然後對學習速率和動量同時進行格點搜尋。

越大的網絡需要越多的訓練,反之亦然。如果你添加了太多的神經元和層數,适當提升你的學習速率。同時學習率需要和訓練周期,batch size大小以及優化方法聯系在一起考慮。

using learning rate schedules for deep learning models in python with keras(http://machinelearningmastery.com/using-learning-rate-schedules-deep-learning-models-python-keras/)

what learning rate should be used for backprop?(ftp://ftp.sas.com/pub/neural/faq2.html#a_learn_rate)

你或許應該使用修正激活函數(rectifier activation functions)。他們也許能提供更好的性能。

在這之前,最早的激活函數是sigmoid和tanh,之後是softmax, 線性激活函數,或者輸出層上的sigmoid函數。我不建議嘗試更多的激活函數,除非你知道你自己在幹什麼。

嘗試全部三種激活函數,并且重縮放你的資料以滿足激活函數的邊界。

顯然,你想要為輸出的形式選擇正确的傳遞函數,但是可以考慮一下探索不同表示。例如,把在二進制分類問題上使用的sigmoid函數切換到回歸問題上使用的線性函數,然後後置處理你的輸出。這可能需要改變損失函數使之更合适。詳情參閱資料轉換那一節。

why use activation functions?(ftp://ftp.sas.com/pub/neural/faq2.html#a_act)

網絡結構的改變能帶來好處。

你需要多少層以及多少個神經元?抱歉沒有人知道。不要問這種問題…

那怎麼找到适用你的問題的配置呢?去實驗吧。

嘗試一個隐藏層和許多神經元(廣度模型)。

嘗試一個深的網絡,但是每層隻有很少的神經元(深度模型)。

嘗試上述兩種方法的組合。

借鑒研究問題與你的類似的論文裡面的結構。

嘗試拓撲模式(扇出(fan out)然後扇入(fan in))和書籍論文裡的經驗法則(下有連結)

選擇總是很困難的。通常說來越大的網絡有越強的代表能力,或許你需要它。越多的層數可以提供更強的從資料中學到的抽象特征的能力。或許需要它。

深層的神經網絡需要更多的訓練,無論是訓練周期還是學習率,都應該相應地進行調整。

以下為相關閱讀: 這些連結會給你很多啟發該嘗試哪些事情,至少對我來說是的。

how many hidden layers should i use?(ftp://ftp.sas.com/pub/neural/faq3.html#a_hl)

how many hidden units should i use?(ftp://ftp.sas.com/pub/neural/faq3.html#a_hu)

batch size大小會決定最後的梯度,以及更新權重的頻度。一個周期(epoch)指的是神經網絡看一遍全部訓練資料的過程。

你是否已經試驗了不同的批次batch size和周期數?之前,我們已經讨論了學習率,網絡大小和周期之間的關系。

在很深的網絡結構裡你會經常看到:小的batch size配以大的訓練周期。

下面這些或許能有助于你的問題,也或許不能。你要在自己的資料上嘗試和觀察。

嘗試選取與訓練資料同大小的batch size,但注意一下記憶體(批次學習(batch learning))

嘗試選取1作為batch size(線上學習(online learning))

嘗試用格點搜尋不同的小的batch size(8,16,32,…)

分别嘗試訓練少量周期和大量周期。

考慮一個接近無窮的周期值(持續訓練),去記錄到目前為止能得到的最佳的模型。

一些網絡結構對batch size更敏感。我知道多層感覺器(multilayer perceptrons)通常對batch size是魯棒的,而lstm和cnns比較敏感,但是這隻是一個說法(僅供參考)。

what are batch, incremental, on-line … learning?(ftp://ftp.sas.com/pub/neural/faq2.html#a_styles)

intuitively, how does mini-batch size affect the performance of (stochastic) gradient descent?(https://www.quora.com/intuitively-how-does-mini-batch-size-affect-the-performance-of-stochastic-gradient-descent)

正則化是一個避免模型在訓練集上過拟合的好方法。

神經網絡裡最新最熱的正則化技術是dropout方法,你是否試過?dropout方法在訓練階段随機地跳過一些神經元,驅動這一層其他的神經元去捕捉松弛。簡單而有效。你可以從dropout方法開始。

格點搜尋不同的丢失比例。

分别在輸入,隐藏層和輸出層中試驗dropout方法

dropout方法也有一些拓展,比如你也可以嘗試drop connect方法。

也可以嘗試其他更傳統的神經網絡正則化方法,例如:

權重衰減(weight decay)去懲罰大的權重

激活限制(activation constraint)去懲罰大的激活值

你也可以試驗懲罰不同的方面,或者使用不同種類的懲罰/正則化(l1, l2, 或者二者同時)

dropout regularization in deep learning models with keras(http://machinelearningmastery.com/dropout-regularization-deep-learning-models-keras/)

what is weight decay?(ftp://ftp.sas.com/pub/neural/faq3.html#a_decay)

最常見是應用随機梯度下降法(stochastic gradient descent),但是現在有非常多的優化器。你試驗過不同的優化(方法)過程嗎?随機梯度下降法是預設的選擇。先好好利用它,配以不同的學習率和動量。

許多更進階的優化方法有更多的參數,更複雜,也有更快的收斂速度。好與壞,是不是需要用,取決于你的問題。

為了更好的利用好一個給定的(優化)方法,你真的需要弄明白每個參數的意義,然後針對你的問題通過格點搜尋不同的的取值。困難,消耗時間,但是值得。

我發現了一些更新更流行的方法,它們可以收斂的更快,并且針對一個給定網絡的容量提供了一個快速了解的方式,例如:

adam

rmsprop

你還可以探索其他優化算法,例如,更傳統的(levenberg-marquardt)和不那麼傳統的(genetic algorithms)。其他方法能夠為随機梯度下降法和其他類似方法提供好的出發點去改進。

要被優化的損失函數與你要解決的問題高度相關。然而,你通常還是有一些餘地(可以做一些微調,例如回歸問題中的均方誤(mse)和平均絕對誤差(mae)等),有時候變換損失函數還有可能獲得小的性能提升,這取決于你輸出資料的規模和使用的激活函數。

an overview of gradient descent optimization algorithms(http://sebastianruder.com/optimizing-gradient-descent/)

what are conjugate gradients, levenberg-marquardt, etc.?(ftp://ftp.sas.com/pub/neural/faq2.html#a_numanal)

on optimization methods for deep learning, 2011 pdf(http://ai.stanford.edu/~ang/papers/icml11-optimizationfordeeplearning.pdf)

一旦訓練過程中出現(驗證集)性能開始下降,你可以停止訓練與學習。這可以節省很多時間,而且甚至可以讓你使用更詳盡的重采樣方法來評估你的模型的性能。

早停法是一種用來避免模型在訓練資料上的過拟合的正則化方式,它需要你監測模型在訓練集以及驗證集上每一輪的效果。一旦驗證集上的模型性能開始下降,訓練就可以停止。

如果某個條件滿足(衡量準确率的損失),你還可以設定檢查點(checkpointing)來儲存模型,使得模型能夠繼續學習。檢查點使你能夠早停而非真正的停止訓練,是以在最後,你将有一些模型可供選擇。

how to check-point deep learning models in keras(http://machinelearningmastery.com/check-point-deep-learning-models-keras/)

what is early stopping?(ftp://ftp.sas.com/pub/neural/faq3.html#a_stop)

通過嵌套模型提升性能

你可以組合多個模型的預測能力。剛才提到了算法調參可以提高最後的性能,調參之後這是下一個可以提升的大領域。

事實上,你可以經常通過組合多個“足夠好的”模型來得到優秀的預測能力,而不是通過組合多個高度調參的(脆弱的)模型。

你可以考慮以下三個方面的嵌套方式:

組合模型

組合視角

堆疊(stacking)

有時候我們幹脆不做模型選擇,而是直接組合它們。

如果你有多個不同的深度學習模型,在你的研究問題上每一個都表現的還不錯,你可以通過取它們預測的平均值來進行組合。

模型差異越大,最終效果越好。例如,你可以應用非常不同的網絡拓撲或者不同的技術。

如果每個模型都效果不錯但是不同的方法/方式,嵌套後的預測能力将更加魯棒。

每一次你訓練網絡,你初始化不同的權重,然後它會收斂到不同的最終權重。你可以多次重複這一過程去得到很多網絡,然後把這些網絡的預測值組合在一起。

它們的預測将會高度相關,但是在那些難以預測的特征上,它會給你一個意外的小提升。

ensemble machine learning algorithms in python with scikit-learn(http://machinelearningmastery.com/ensemble-machine-learning-algorithms-python-scikit-learn/)

how to improve machine learning results(http://machinelearningmastery.com/how-to-improve-machine-learning-results/)

同上述類似,但是從不同視角重構你的問題,訓練你的模型。

同樣,目标得到的是效果不錯但是不同的模型(例如,不相關的預測)。得到不同的模型的方法,你可以依賴我們在資料那一小節中羅列的那些非常不同的放縮和轉換方法。

你用來訓練模型的轉換方法越不同,你建構問題的方式越不同,你的結果被提升的程度就越高。

簡單使用預測的均值将會是一個好的開始。

你還可以學習如何最佳地組合多個模型的預測。這稱作堆疊泛化(stacked generalization),或者簡短來說就叫堆疊。

通常上,你使用簡單線性回歸方法就可以得到比取預測平均更好的結果,像正則化的回歸(regularized regression),就會學習如何給不同的預測模型賦權重。基線模型是通過取子模型的預測均值得到的,但是應用學習了權重的模型會提升性能。

stacked generalization (stacking)(http://machine-learning.martinsewell.com/ensembles/stacking/)

别的地方有很多很好的資源,但是幾乎沒有能将所有想法串聯在一起的。如果你想深入研究,我列出了如下資源和相應的部落格,你能發現很多有趣的東西。

neural network faq(ftp://ftp.sas.com/pub/neural/faq.html)

must know tips/tricks in deep neural networks(http://lamda.nju.edu.cn/weixs/project/cnntricks/cnntricks.html)

how to increase validation accuracy with deep neural net?(http://stackoverflow.com/questions/37020754/how-to-increase-validation-accuracy-with-deep-neural-net)