TensorFlow:卷積神經網絡手勢識別項目的調參感悟

調參感悟

對於網絡的選擇,我採用通用的由簡入繁的做法(在吳恩達的課程中,他也多次表達了這類思想)。

  • 首先,嘗試了簡單網絡LeNet-5,由於網絡的設計原因,對於5分類測試集上的表現非常糟糕(過擬合)。

  • 其次,嘗試複雜一些的AlexNet。經過調參和優化環節,最終取得了不錯的成績。

調參的過程無非是解決兩個問題,欠擬合和過擬合。因爲這個五分類問題的複雜度低,因此自始至終,我們面臨的都是過擬合。

解決過擬合

第一次嘗試:LeNet-5

一開始每種手勢動作只拍攝了500張,用的是LeNet-5結構,訓練集的accuracy很高,loss也很高,測試集的效果很明顯差到爆炸。

  • 這是明顯的過擬合,考慮到LeNet-5中無Dropout,使用tanh非ReLu,也是可以理解的

  • 此外,數據量也是可以再增加以便緩解過擬合

第二次嘗試:AlexNet + SAME Pooling

出於上述原因,因此決定試試經典的AlexNet結構(卷積層數和池化層數爲AlexNet結構,池化方式選擇SAME),在兩個全連接層加入droupout = 0.5,防止過擬合。Batch size設置爲256以加快訓練速度,這樣可以更快看到結果。

                               ​

 

雖然測試集的accuracy已經比LeNet-5提升很多,接近63%,但很明顯依然過擬合。後發現Pooling的方式對過擬合亦有影響。

第三次嘗試:AlexNet + VALID Pooling

相對於SAME池化方式,VALID方式會輸入周圍更少的特徵,對減少過擬合肯定是有幫助的,於是嘗試VALID。

                                    

預測集的正確率提高了10%,但是肯定還有很大的提高空間,而且很明顯還是過擬合。

解決過擬合的最直接的方式是增加數據集和減小模型參數,例如之前貓狗分類問題是各12500張。

第四次嘗試:AlexNet + VALID Pooling + 調整Batch Size

再加數據之前,我先再調大了batch size = 512,看看batch size對結果的影響:

                                           

​如圖,作用並不是很明顯,而且無法再加大batch size,會爆顯存。於是按此前計劃開始增加數據集。

第五次嘗試:AlexNet + VALID Pooling + 增加數據集

增加數據集(每個手勢+100)

                                           ​

增加數據集(每個手勢再+200)

               ​

 

每種手勢增加300張圖片後,我發現測試集的正確率突然飆升上了90%

增加數據集(每個手勢再 +100)

                ​

 

這個時候測試集的正確率算看得過去了,此時訓練集是每種手勢900張,一共4500張圖片。

在線測試中,發現5種手勢有4種識別的還可以,但是Good手勢識別經常錯誤,於是單獨給Good手勢增加150張圖片。

增加數據集(只給Good手勢再 +150)

                                                ​

增加數據集(每個手勢再 +100)

正確率有微弱提升,然後再每種手勢+100照片,正確率不再提升了。

現在的正確率雖然可以接受了,但實時測試的效果並不是很理想。可能是因爲測試集比實時測試的時候背景乾淨,噪聲更小,爲了更好的檢驗模型,我在測試集上除了輸出正確率還輸出損失。

​                                               

​損失率達到了0.77難怪我的實時測試消息並不理想。

第六次嘗試:AlexNet + VALID Pooling + 大數據集 + 數據預處理

解決思路是從數據集入手,檢測自己拍的數據集,把一些拍的不好的數據刪除替換,並把實時檢測的圖片大小由400x400 切割變化爲300x300,從而突出手勢動作,而忽略其他背景干擾。

同時增加數據集的300x300的手勢動作圖片,使訓練集前4種手勢各有1300張照片,Good手勢有1450張照片。(切割出感興趣區域提高識別準確率)

                                               

 

第七次嘗試:AlexNet + VALID Pooling + 大數據集 + 數據預處理 + 小Mini-Batch

想起此前Yann LeCun(2019年獲得圖靈獎獲得者)的一個言論:

Training with large minibatches is bad for your health. More importantly, it's bad for your test error. Friends don‘t let friends use minibatches larger than 32. Let's face it: the only people have switched to minibatch sizes larger than one since 2012 is because GPUs are inefficient for batch sizes smaller than 32. That's a terrible reason. It just means our hardware sucks.

他認爲大於32的batch-size都是深惡痛絕的。

The best performance has been consistently obtained for mini-batch sizes between m=2 and m=32, which contrasts with recent work advocating the use of mini-batch sizes in the thousands.

也就是最好的實驗表現都是在batch size處於 2 ~ 32 之間得到的,這和最近深度學習界論文中習慣的動輒上千的batch size選取有很大的出入。

嘗試於是調小Batch Size爲32。測試集準確率已接近96%。對於實時測試,手勢基本都能識別對了,達到了應用的目標!

                                               ​

 

                                                     ​

一些調參過程的圖

(極端情形)

Step=step*20

只改動:把Batch-size =32

 

一些Batch選擇觀點

下屬觀點來源知乎

回想我們使用mini-batch技術的原因,無外乎是因爲mini-batch有這幾個好處 :

  • 提高了運行效率,相比batch-GD的每個epoch只更新一次參數,使用mini-batch可以在一個epoch中多次更新參數,加速收斂。

  • 解決了某些任務中,訓練集過大,無法一次性讀入內存的問題。

  • 雖然第一點是mini-batch提出的最初始的原因,但是後來人們發現,使用mini-batch還有個好處,即每次更新時由於沒有使用全量數據而僅僅使用batch內數據,從而人爲給訓練帶來了噪聲,而這個操作卻往往能夠帶領算法走出局部最優(鞍點)。理論證明參見COLT的這篇論文Escaping From Saddle Points-Online Stochastic Gradient for Tensor Decomposition。也就是說,曾經我們使用mini-batch主要是爲了加快收斂和節省內存,同時也帶來每次更新有些“不準”的副作用,但是現在的觀點來看,這些“副作用”反而對我們的訓練有着更多的增益,也變成mini-batch技術最主要的優點。

但是,Batch size的選擇需要考慮如下的trade-off:

  • 小Batch訓練的穩定性較差。小batch確實有這個缺點,而且對設置學習速率有更高的要求,否則可能引起惡性的震盪無法收斂。但是小batch的優點仍然是顯著的。

  • Batch size 可能也不是越大越好,ICLR 2017 On Large-Batch Training for Deep Learning: Generalization Gap and Sharp Minima 比較了一直用small batch(實驗設置的256,貌似也不小了...)和一直用large batch(整個數據集十分之一...)訓練,最後發現同樣訓練到最終收斂,在多個數據集上large batchsmall batch泛化能力差。

  • 前期用小batch引入噪聲,有利於跳出sharp minima,後期用大batch避免震盪,同樣目的也可以通過調小lrate做到,同比例地增大batch size和同比例地減小lrate能得到極相近的loss-epoch曲線,不過前者update次數會少很多~(Don't Decay the Learning Rate, Increase the Batch Size)

 

                     

 

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