深度學習模型訓練過程
一.數據准備
1. 基本原則:
1)數據標注前的標簽體系設定要合理
2)用於標注的數據集需要無偏、全面、盡可能均衡
3)標注過程要審核
2. 整理數據集
1)將各個標簽的數據放於不同的文件夾中,並統計各個標簽的數目
2)樣本均衡,樣本不會絕對均衡,差不多就行了
3)切分樣本集
如:90%用於訓練,10%留着測試,比例自己定。訓練集合,對於弱勢類要重采樣,最后的圖片列表要shuffle;測試集合就不用重采樣了。
訓練中要保證樣本均衡,學習到弱勢類的特征,測試過程要反應真實的數據集分布。
4)按需要的格式生成tfrecord
按照train.list和validation.list生成需要的格式。生成和解析tfrecord的代碼要根據具體情況編寫。
二.基本步驟
1. 定義算法公式,也就是神經網絡的前向算法。我們一般使用現成的網絡,如inceptionV4,mobilenet等。
2. 定義loss,選擇優化器,來讓loss最小
3. 對數據進行迭代訓練,使loss到達最小
4. 在測試集或者驗證集上對准確率進行評估
三.訓練
1. 預處理,根據自己的喜好,編寫預處理策略。
preprocessing的方法,變換方案諸如:隨機裁剪、隨機變換框、添加光照飽和度、修改壓縮系數、各種縮放方案、多尺度等。進而,減均值除方差或歸一化到[-1,1],將float類型的Tensor送入網絡。
這一步的目的是:讓網絡接受的訓練樣本盡可能多樣,不要最后出現原圖沒問題,改改分辨率或寬高比就跪了的情況。
2. 網絡設計,基礎網絡的選擇和Loss的設計。
基礎網絡的選擇和問題的復雜程度息息相關,用ResNet18可以解決的沒必要用101;還有一些SE、GN等模塊加上去有沒有提升也可以去嘗試。
Loss的設計,一般問題的抽象就是設計Loss數據公式的過程。比如多任務中的各個任務權重配比,centor Loss可以讓特征分布更緊湊,SmoothL1Loss更平滑避免梯度爆炸等。
3. 優化算法
一般來說,只要時間足夠,Adam和SGD+Momentum可以達到的效果差異不大。用框架提供的理論上最好的優化策略就是了。
4. 訓練過程
finetune網絡,我習慣分兩步:首先訓練fc層,迭代幾個epoch后保存模型;然后基於得到的模型,訓練整個網絡,一般迭代40-60個epoch可以得到穩定的結果。total_loss會一直下降的,過程中可以評測下模型在測試集上的表現。真正的loss往往包括兩部分。后面total_loss的下降主要是正則項的功勞了。
四.難點
1. 訓練速度慢,收斂慢
深度學習其實就是一個反復調整模型參數的過程,得力於GPU等硬件性能的提升,使得復雜的深度學習訓練成為了可能。收斂速度過慢,訓練時間過長,一方面使得相同總訓練時間內的迭代次數變少,從而影響准確率,另一方面使得訓練次數變少,從而減少了嘗試不同超參數的機會。
1. 設置合理的初始化權重w和偏置b
f(x) = w * x + b
2. 優化學習率
型訓練就是不斷嘗試和調整不同的w和b,那么每次調整的幅度是多少呢,這個就是學習率。
3. 網絡節點輸入值正則化 batch normalization
神經網絡訓練時,每一層的輸入分布都在變化。不論輸入值大還是小,我們的學習率都是相同的,這顯然是很浪費效率的。而且當輸入值很小時,為了保證對它的精細調整,學習率不能設置太大。那有沒有辦法讓輸入值標准化得落到某一個范圍內,比如[0, 1]之間呢,這樣我們就再也不必為太小的輸入值而發愁了。
辦法當然是有的,那就是正則化!由於我們學習的是輸入的特征分布,而不是它的絕對值,故可以對每一個mini-batch數據內部進行標准化,使他們規范化到[0, 1]內。這就是Batch Normalization,簡稱BN。由大名鼎鼎的inception V2提出。它在每個卷積層后,使用一個BN層,從而使得學習率可以設定為一個較大的值。使用了BN的inceptionV2,只需要以前的1/14的迭代次數就可以達到之前的准確率,大大加快了收斂速度。
4. 采用更先進的網絡結構,減少參數量
1) 使用小卷積核來代替大卷積核。
VGGNet全部使用3x3的小卷積核,來代替AlexNet中11x11和5x5等大卷積核。小卷積核雖然參數量較少,但也會帶來特征面積捕獲過小的問題。inception net認為越往后的卷積層,應該捕獲更多更高階的抽象特征。因此它在靠后的卷積層中使用的5x5等大面積的卷積核的比率較高,而在前面幾層卷積中,更多使用的是1x1和3x3的卷積核。
2) 使用兩個串聯小卷積核來代替一個大卷積核。
inceptionV2中創造性的提出了兩個3x3的卷積核代替一個5x5的卷積核。在效果相同的情況下,參數量僅為原先的3x3x2 / 5x5 = 18/25
3)1x1卷積核的使用。
1x1的卷積核可以說是性價比最高的卷積了,沒有之一。它在參數量為1的情況下,同樣能夠提供線性變換,relu激活,輸入輸出channel變換等功能。VGGNet創造性的提出了1x1的卷積核
3) 非對稱卷積核的使用。
inceptionV3中將一個7x7的卷積拆分成了一個1x7和一個7x1, 卷積效果相同的情況下,大大減少了參數量,同時還提高了卷積的多樣性。
4) depthwise卷積的使用。
mobileNet中將一個3x3的卷積拆分成了串聯的一個3x3 depthwise卷積和一個1x1正常卷積。對於輸入channel為M,輸出為N的卷積,正常情況下,每個輸出channel均需要M個卷積核對輸入的每個channel進行卷積,並疊加。也就是需要MxN個卷積核。而在depthwise卷積中,輸出channel和輸入相同,每個輸入channel僅需要一個卷積核。而將channel變換的工作交給了1x1的卷積。這個方法在參數量減少到之前1/9的情況下,精度仍然能達到80%。
5) 全局平均池化代替全連接層。
這個才是大殺器!AlexNet和VGGNet中,全連接層幾乎占據了90%的參數量。inceptionV1創造性的使用全局平均池化來代替最后的全連接層,使得其在網絡結構更深的情況下(22層,AlexNet僅8層),參數量只有500萬,僅為AlexNet的1/12。