理解並實現 ResNet(Keras)
本文為 AI 研習社編譯的技術博客,原標題 :
Understanding and Coding a ResNet in Keras
作者 | Priya Dwivedi @ Deep Learning Analytics
翻譯 | linlh、通夜 編輯 | 鄧普斯?傑弗、Pita
原文鏈接:
https://towardsdatascience.com/understanding-and-coding-a-resnet-in-keras-446d7ff84d33
ResNet 是殘差網路(Residual Network)的縮寫,是一種作為許多計算機視覺任務主幹的經典神經網路。這個模型是2015年ImageNet挑戰賽的獲勝者,ResNet最根本的突破在於它使得我們可以訓練成功非常深的神經網路,如150+層的網路。在ResNet之前,由於梯度消失(vanishing gradients)的問題,訓練非常深的神經網路是非常困難的。
AlexNet,2012年ImageNet的獲勝者,這個模型就明顯開始關註解決僅有8個卷積層的深度學習,VGG網路有19層,Inception或者GoogleNet有22層,ResNet 152有152層。在這篇文章中,我們會編寫一個ResNet-50的網路,ResNet 152的小型版本,經常在開始的時候用在遷移學習上。
深度革命
但是,提升網路的深度並不是簡單的將網路層堆疊起來。深層網路很難訓練的原因,是因為非常煩人的梯度消失問題——隨著梯度反向傳播回前面的網路層,重複的乘積操作會使得梯度變得非常小。結果呢,隨著網路越來越深,它的性能就變得飽和了,並開始迅速下降。
我是在Andrew Ng的 DeepLearning.AI 課程上學習到關於編寫ResNet的內容的,非常推薦大家觀看這個課程。
在我的Github repo上,我分享了兩個Jupyter Notebook,一個是如DeepLearning.AI中所述,從頭開始編碼ResNet,另一個在Keras中使用預訓練的模型。希望你可以把代碼下載下來,並自己試一試。
殘差連接(Skip Connection)——ResNet的強項ResNet是第一個提出殘差連接的概念。下面的圖闡述了殘差連接。左邊的圖演示了網路層的堆疊,一層接著一層。在右邊的圖中,我們仍然看了之前網路層的堆疊,但是我們還將原始的輸入添加到卷層單元的輸出。
殘差連接示意圖 (來自 DeepLearning.AI)
可以寫成下面兩行代碼:
代碼是非常簡單,但是這裡有一個非常重要的考慮因素——上面的X,X_shortcut是兩個矩陣,只有在他們是相同的形狀時,你才可以相加。因此,如果卷積+批量規範(batch norm)操作以輸出形狀相同的方式完成,那麼我們可以簡單地添加它們,如下所示。
當 x 和 x_shortcut 是相同的形狀
否則,x_shortcut通過選定的卷積層,使得它的輸出與卷積塊的輸出相同,如下所示:
X_shortcut 通過卷積單元
在Github的Notebook上,identity_block 和convolution_block 兩個函數實現了上面的內容。這些函數使用Keras來實現帶有ReLU激活函數的Convolution和Batch Norm層。殘差連接實現上就是這行代碼: X = Add([X, X_shortcut])。
這裡需要注意的一件重要的事情是殘差連接是應用在ReLU激活函數之前,正如上圖所示。研究人員發現這樣可以得到最好的結果。
為什麼要跳過連接?這是個有趣的問題。我認為在這裡跳過連接有兩個原因:
他們通過允許梯度通過這條可選的捷徑來緩解梯度消失的問題
它們允許模型學習一個恆等函數,該函數確保高層的性能至少與低層一樣好,而不是更差。
事實上,由於ResNet跳過連接被用於更多的模型架構中,比如全卷積網路(FCN)和U-Net。它們用於將信息從模型中的較早層傳遞到較晚層。在這些體系結構中,它們用於將信息從下採樣層傳遞到上採樣層。
測試我們構建的ResNet模型然後將筆記本中編碼的恆等和卷積塊組合起來,創建一個ResNet-50模型,其架構如下:
ResNet-50模型
ResNet-50模型由5個階段組成,每個階段都有一個卷積和恆等塊。每個卷積塊有3個卷積層每個單位塊也有3個卷積層。ResNet-50有超過2300萬個可訓練參數。
我已經在我的Github repo中包含的signs數據集上測試了這個模型。這個數據集有對應於6個類的手動圖像。我們有1080張火車圖像和120張測試圖像。
符號數據集
我們的ResNet-50經過25個階段的訓練,測試精度達到86%。不錯!
在Keras中用預訓練庫構建ResNet我喜歡自己編寫ResNet模型,因為它讓我更好地理解了我經常在與圖像分類,對象定位,分割等相關的許多遷移學習任務中使用的網路。
但是,對於更為常用的做法,在Keras中預訓練的ResNet-50模型更快。Keras擁有許多這些骨幹模型,其庫中提供了Imagenet權重。
Keras 預訓練的模型
我上傳了一個Notebook放在Github上,使用的是Keras去載入預訓練的模型ResNet-50。你可以用一行的代碼來載入這個模型:
base_model = applications.resnet50.ResNet50(weights= None, include_top=False, input_shape= (img_height,img_width,3))
在這裡weights=None,因為我想用隨機權重初始化模型,就像我在ResNet-50 I編碼時所做的那樣。或者也可以載入預訓練的ImageNet的權重。設置include_top=False,表示不包含原始模型中最後的池化層(pooling)和全連接層(fully connected)。我在ResNet50模型中添加了全局平均池化層(global average pooling)和密集輸出層(dense output)。
從上面的可以看到,Keras提供非常方便的介面去載入預訓練模型,但重要的是至少要對ResNet自己編碼一次,這樣你才能理解這個概念,並且可以將這種學習應用到你正在創建的另一個新架構中。
這個Keras ResNet模型在使用了Adam優化器和0.0001的學習率,訓練了100個epoch之後得到75%的正確率。這個正確率比我自己編碼的模型要低一些,我想這應該和權重初始化有關。
Keras也提供了非常簡單的數據增強(data augmentation)的介面,所以如果有機會,在數據集上試試增強,看看結果能不能得到更好的性能。雷鋒網雷鋒網雷鋒網
總結ResNet是非常強大的骨幹模型(backbone model),經常在許多計算機視覺任務中使用
ResNet 使用殘差連接(skip connection)將較早的網路層的輸出添加到更後面網路層。這有助於緩解梯度消失的問題
你可以使用Keras載入預訓練的ResNet-50模型或者使用我分享的代碼來自己編寫ResNet模型。
我有自己深度學習的諮詢工作,喜歡研究有趣的問題。我幫助許多初創公司部署基於AI的創新解決方案。 請訪問 http://deeplearninganalytics.org/查看我們。
你也可以在medium上查看我的其他文章:
https://medium.com/@priya.dwivedi
參考DeepLearning.AI
Keras
ReNet Paper
想要繼續查看該篇文章相關鏈接和參考文獻?
點擊【理解並實現 ResNet(Keras)】即可訪問:
今日資源推薦:計算機視覺頂會 CVPR 2019 即將於 6 月在美國長灘召開,今年大會共收到超過 5165 篇論文投稿,最終收錄的論文為 1299 篇。隨著會議臨近,無論是學術界還是業界都迎來了一波 CVPR 2019 入選論文解讀熱潮。本論文集合從近 300 篇 CVPR 2019 Oral 論文精選了數十篇論文,領域包括人臉檢測、目標檢測、手勢識別、機器人等熱門領域,供各位開發者和學術青年閱讀研究。
https://ai.yanxishe.com/page/resourceDetail/819
※CVPR 2019 Oral 論文解讀 | 無監督域適應語義分割
※商湯的醫療狂想曲
TAG:雷鋒網 |