天天看點

深度學習——手動實作殘差網絡ResNet 辛普森一家人物識别

通過深度學習,訓練模型識别辛普森一家人動畫中的14個角色

最終實作92%-94%的識别準确率。

深度學習——手動實作殘差網絡ResNet 辛普森一家人物識别

論文位址 https://arxiv.org/pdf/1512.03385.pdf

殘差網絡(ResNet)是微軟亞洲研究院的何恺明、孫劍等人2015年提出的,它解決了深層網絡訓練困難的問題。利用這樣的結構我們很容易訓練出上百層甚至上千層的網絡。

殘差網絡的提出,有效地緩解了深度學習兩個大問題

梯度消失:當使用深層的網絡時(例如> 100)反向傳播時會産生梯度消。由于參數初始化一般更靠近0,這樣在訓練的過程中更新淺層網絡的參數時,很容易随着網絡的深入而導緻梯度消失,淺層的參數無法更新。

退化問題:層數越多,訓練錯誤率與測試錯誤率反而升高。舉個例子,假設已經有了一個最優化的網絡結構,是18層。當我們設計網絡結構的時候,我們并不知道具體多少層次的網絡時最優化的網絡結構,假設設計了34層網絡結構。那麼多出來的16層其實是備援的,我們希望訓練網絡的過程中,模型能夠自己訓練這16層為恒等映射,也就是經過這層時的輸入與輸出完全一樣,這樣子最終的結果和18層是一緻的最優的。但是往往模型很難将這16層恒等映射的參數學習正确,那麼就一定會不比最優化的18層網絡結構性能好,是以随着網絡深度增加,模型會産生退化現象。它不是由過拟合産生的,而是由備援的網絡層學習了不是恒等映射的參數造成的。

ResNet使用了一個新的思想,ResNet的思想是假設我們的網絡,存在最優化的網絡層次,那麼往往我們設計的深層次網絡是有很多網絡層為備援層的。那麼我們希望這些備援層能夠完成恒等映射,保證經過該恒等層的輸入和輸出完全相同。

深度學習——手動實作殘差網絡ResNet 辛普森一家人物識别

這是殘差網絡的基本單元,和普通的網絡結構多了一個直接到達輸出前的連線(shortcut)。開始輸入的X是這個殘差塊的輸入,F(X)是經過第一層線性變化并激活後的輸出。在第二層輸出值激活前加入X,這條路徑稱作shortcut連接配接,然後再進行激活後輸出。

這個殘差怎麼了解呢?大家可以這樣了解線上性拟合中的殘差說的是資料點距離拟合直線的函數值的差,那麼這裡我們可以類比,這裡的X就是我們的拟合的函數,而H(x)的就是具體的資料點,那麼我通過訓練使的拟合的值加上F(x)的就得到具體資料點的值,是以這 F(x)的就是殘差了,還是畫個圖吧,如下圖:

深度學習——手動實作殘差網絡ResNet 辛普森一家人物識别

引用:https://blog.csdn.net/weixin_42398658/article/details/84627628

ResNet就是在網絡中添加shortcut,來構成一個個的殘差塊,進而解決梯度爆炸和網絡退化。

這是一個ResNet18的網絡結構,在我的實作中,我根據這個結構搭建網絡,并根據自己的實際情況進行調整。

深度學習——手動實作殘差網絡ResNet 辛普森一家人物識别

引用:https://www.researchgate.net/figure/ResNet-18-model-architecture-10_fig2_342828449

首先,ResNets利用恒等映射幫助解決漸變消失的問題。我開始嘗試使用簡單的MLP模型,例如一個輸入層、一個輸出層和三個卷積層。但是它的訓練表現很差,隻有45%的準确率。是以我需要更多的神經網絡層,但是如果太多的神經網絡層會導緻梯度消失的問題。最後我想到了ResNet。

其次,網絡深度決定了savedModel.pth(訓練好的模型)的檔案大小,該資料集總共有15,000張圖像和14個類别,并不是很多。是以我選擇了ResNet18,因為我們的資料集不是特别大。

而且不需要更深層次的網絡模型。

ResNet18是一個卷積神經網絡。它的架構有18層。它在圖像分類中是非常有用和有效的。首先是一個卷積層,核心大小為3x3,步幅為1。

在标準的ResNet18模型中,這一層使用7*7的核心大小和步幅2。我在這裡做了一些改變。

根據實際情況,因為原始模型中輸入的檔案大小是224 * 224,而我們的圖像大小是64 * 64,7*7的核心大小對于這個任務來說太大了。标準ResNet18模型的精度為大約89%,而我修改的模型的準确率大約為94%。

輸入層之後是由剩餘塊組成的四個中間層。ResNet的殘餘塊是由兩個33卷積層,包括一個shortcut,使用11卷積層直接添加的輸入前一層到另一層的輸出。最後,average pooling應用于的輸出,将最終的殘塊和接收到的特征圖賦給全連通層。

此外,模型中的卷積結果采用ReLu激活函數和歸一化處理。

為了減少過拟合,我使用圖像變換進行資料增強。并對輸入圖像進行歸一化處理。這樣可以保證所有圖像的分布是相似的,即在訓練過程中更容易收斂,訓練速度更快,效果更好。

我還嘗試将圖像的大小調整為224224,并在輸入層使用77的卷積核,但我發現圖像放大得太多,導緻特征模糊,模型性能變差。

歸一化:我使用下面的腳本來計算所有資料的均值和标準差。

<code>epochs = 120</code>, 如果太小,收斂可能不會結束。

<code>batch_size = 256</code>, 如果batch_size太小,可能會導緻收斂速度過慢或損失不會減少

<code>lr = 0.001</code>,當學習率設定過大時,梯度可能會圍繞最小值振蕩,甚至無法收斂

<code>torch.nn.CrossEntropyLoss()</code>是很适合圖像作業的

我嘗試過<code>SGD</code>, <code>RMSprop</code>, <code>Adadelta</code>等,但<code>Adam</code>是最适合我的。

當我試圖設定它們來減少過拟合問題時,效果并不好。這種設定使loss無法減少或精度降低。

圖像增強代碼

ResNet18手工搭建

論文:

https://arxiv.org/pdf/1512.03385.pdf

參考部落格:

https://www.cnblogs.com/gczr/p/10127723.html

https://blog.csdn.net/weixin_42398658/article/details/84627628