深度學習算法效果提升-網絡結構

1. 前言

  優化深度學習算法的效果可以從三個方面入手,數據+網絡結構+損失函數。一般來說,外行改網絡結構,內行改損失函數,公司層面收集數據。

  在一般情況下,特別是手機端應用,直接拿個成熟的小網絡進行遷移學習,如shufflenet、mobilenet等,是較爲常見的做法。而且,由於一些開源框架提供了官方預訓練的模型,只要自己的數據集和imagenet的數據類別出入不大,在其基礎上做finetune效果往往也會很好。

  對於服務器端應用,在算法開發階段,我們通常會選擇imagenet數據集上效果較好的預訓練模型,比如resnet 101, inception_resnet_v2等,具體可以參見https://github.com/tensorflow/models/tree/master/research/slim中給出的對比數據。在工程部署階段,可能會因爲服務器的配置、網絡延遲等因素的影響,模型的inference時間不滿足產品定義的響應時間,此時便需要對網絡結構做裁剪,也即修改當前網絡模型的backbone,然後重新訓練整個網絡的參數。此時面臨兩種選擇:一是將當前網絡的backbone替換成小網絡,比如替換成mobilenet;二是對大的網絡做裁剪,比如resneXT,將其裁剪成小的網絡,然後作爲backbone,至於是Mobilenet好還是裁剪後的resneXT好呢,不同的網絡結構提取的圖像特徵是不一樣的,所以要基於具體的任務做完對比實驗後才知道。

  事實上,裁剪網絡屬於網絡結構設計的範疇,這個範疇包含了兩大子類別:一是“從無到有”,可以直接髮網絡結構方面的paper了;二是”從有到有“,站在巨人的肩膀上,包括了network prune、knowledge distillation。 前者需要很多的經驗和技巧,往往都出自於Google、SenseTime等公司的牛人之手,可能大家看到這裏會說,“不是已經有自動化的網絡結構搜索了嗎,比如nasnet等”,但是網絡結構的自動化搜索同樣門檻也很高,對於大多數深度學習從業者來說也是很少會去用的。因此,本篇先對一些已有網絡結構中的精華點進行講解,爲有志於網絡結構設計方面的同學找到一些inspiration,然後結合自己的思考,從工業應用的角度,介紹調整網絡結構的常用策略

2. 現有的優秀網絡結構

  不同網絡結構的模型,它們的表徵能力不一樣,有些模型是爲了提升精度,而有些兼顧了精確度和速度。從應用平臺上來劃分,可以分爲”雲“上模型和“端”上模型。一般來說,大的網絡結構的模型,它的精確度較高,但是因爲模型較厚重,所以只適合在服務器端部署。與此同時,小的網絡結構的模型,設計這在設計之初考慮了速度和精度的折中,因此這類網絡模型更適合手機端部署。

2.1 “雲”上模型

  說起部署在雲端的模型,不得不從Inception網絡Inception系列網絡結構在網絡設計領域是非常重要的,具有很好的借鑑意義。爲什麼這麼說呢,因爲在它之前,所有的網絡爲了提升Imagenet分類效果,都是考慮增加捲積層的個數。Inception系列都是在前一個版本的基礎上進行速度和精度的優化,讓我們開始欣賞網絡設計人員的智慧吧。

2.1.1 Inception v1(GoogLeNet)

  Motivation

  (1) 圖像中的顯著性區域有很大的差異性。比如貓狗識別,對於一條狗的圖片,顯著性區域則爲狗的身體部分,可能圖片中的狗顏色、品種、姿勢、尺寸都不相同,所以差異性很大;

  (2) 如果想學習圖片中全局的信息,應該使用大的kernel,如果想學習圖片中局部的信息,應該使用小的kernel;

  (3) 網絡越深,越容易過擬合,而且存在梯度消失問題;

  (4) 減小計算量;

  Solution

  網絡往 "wider"方向發展而不是 “deeper”,一種解決辦法是同一層使用多個尺寸的filter,模塊結構如下,
在這裏插入圖片描述
  爲了減小模型的計算量,使用了1x1的卷積層進行降維,修改後的模塊結構如下,
在這裏插入圖片描述

2.1.2 Inception v2

  Motivation

  (1) 如果 1x1卷積使通道數減得太多,容易導致信息丟失;

  (2) 對大的卷積kernel進行分解,節約計算量;

  Solution

  將 5x5的卷積分解成兩個級聯的3x3卷積操作,當輸入和輸出通道數分別相同時,兩種網絡結構的參數量比值爲25/(9x2)= 1.38,可以節約計算量,模塊結構如下,
在這裏插入圖片描述
  更進一步地,將 3x3的卷積分解成1x3卷積和3x1卷積的級聯形式,兩種網絡結構的參數量比值爲9/(3x2)= 1.5,也節約了計算量,模塊結構如下,
在這裏插入圖片描述
  上圖中的級聯卷積層較多,容易對輸入的通道數降維太多,導致過多的有用信息丟失,這被稱爲“ representational bottleneck”。爲了緩解這一問題,作者將濾波器組(filter banks)設計的wider而不是deeper,模塊結構如下,
在這裏插入圖片描述
  這三個圖代表了不同類型的inception模塊,這裏分別記作A、B、C,Inception v2的網絡結構主要是這三種模塊的級聯形式,層之間的具體連接形式如下表,
在這裏插入圖片描述

2.1.3 Inception v3

  Motivation

  (1) 在不對Inception v2的module結構進行大改的前提下,儘可能地提升模型效果;

  Solution

  (1) RMSProp優化器;

  (2) BatchNorm層;

  (3) Label Smoothing(正則化技術);

2.1.4 Inception v4

  Motivation

  (1) 在設計Inception v3的過程中,作者考慮了是否能在DistBelief進行分佈式訓練,導致模型過於複雜,現在遷移到了tensorflow平臺上,就可以做一個簡單一致的網絡設計;

  Solution

  (1) 使用更多的inception模塊來增強網絡的表達能力,但是這裏的Inception模塊相比於v3中的更簡單,所以整體上沒有增加計算量;

  (2) 設計了專用的“Reduction Blocks”,用於減小feature map的尺寸;

2.1.4 Inception_resnet_v1

  Motivation

  (1) 借鑑何凱明大神的“residual connection”的思想,;

  Solution

  (1) 對於每個inception模塊,增加殘差連接;
在這裏插入圖片描述

2.1.5 ResneXT

  Motivation

  (1) 在不增加模型參數量的前提下,儘可能地提升模型的準確率;
  (2) inception 系列網絡中每個inception模塊設計的較複雜,當應用在別的數據集上時,不容易修改網絡結構。

  Solution

  (1) ResneXT引入了“cardinality”的概念,可以理解成通路,每一條通路的結構完全相同,所以設計起來更加簡單化。
在這裏插入圖片描述
  (2) 作者證明了下面的三種拓撲結構是完全等價的,意思是說模型在測試集的效果理論上是一樣的,在論文中,爲了工程上更容易實現,所有的實驗結果採用了©結構。
在這裏插入圖片描述

2.2 “端”上模型

  說起部署在移動端的模型,mobilenet是令人最印象深刻的網絡結構了。各位讀者可能注意到,inception和mobilenet都是谷歌家的呀,是的,筆者項目中部署到手機端的模型,用的最多的就是mobilenet系列了,效果確實可以,下面按照在imagenet測試集上的效果從低到高排序,分別解釋當前可用且有效的輕量化模型。

2.2.1 squeezenet

  Motivation

  (1) 在減少模型參數量的前提下,儘可能地提升模型的準確率。

  Solution

  (1) 在網絡結構中,儘量多使用1x1而不是3x3 的濾波器,因爲前者是後者參數量的1/9;
  (2) 爲了進一步較少計算量,使用了論文中提到的“squeeze layer”, 減小3x3濾波器的輸入通道數;
  (3) 爲了在參數量不變的情況下,儘可能地提升精度。作者認爲卷積層的feature map尺寸越大,模型效果越好,於是就儘可能地把下采樣層放到整個網絡的後面。

  squeezenet的整體網絡結構類似於inception v1,網絡結構的核心“Fire” module可以類比於inception v1的“Inception” module,“Fire” module的結構如下圖,
在這裏插入圖片描述
  注:源代碼使用的是caffe框架。

2.2.2 mobilenet_v1

  Motivation

  (1) 在減少模型參數量的前提下,儘可能地提升模型的準確率;

  Solution

  (1) 整個網絡結構的核心模塊是“Depthwise Separable Convolution”,它包含了兩層,“depthwise convolutions” 和“pointwise convolutions”,前者分別對逐個通道進行卷積,獲取空間域信息,後者對feature map做特徵融合,這兩層也使用了batchnorm和ReLU的策略,該核心模塊的圖形表示如下,
在這裏插入圖片描述
  注:源代碼使用的是tensorflow框架。

2.1.3 shufflenet

  Motivation

  (1) 在減少模型參數量的前提下,儘可能地提升模型的準確率;

  Solution

  (1) 本文提出的網絡結構的主要layer類型是"group convolution"和“channel shuffle”,前者是Alexnet文章中首次提出來的,並被ResneX網絡證明是有效的,後者是本文的創新點,”channel shuffle“能夠使當前goup包含其他group的信息,從而實現信息的融合。雖然mobilenet_v1中的“pointwise convolution”也可以實現信息融合的目的,但是卻引入了額外的參數量,“channel shuffle”的圖形解釋如下,
在這裏插入圖片描述
  類比於inception網絡中的inception模塊,shufflenet網絡的核心module結構如下圖,
在這裏插入圖片描述

2.1.4 mobilenet_v2

  Motivation

  (1) 對mobilenet_v1進一步優化;

  Solution

  (1) 作者實驗發現,線性bottleneck比非線性的top1 精度提升了0.5個點左右,這裏的“bottleneck”指的是Figure 3中淺藍色的輸出層;

  (2) 使用“Inverted residuals”,提升模型的速度。

  這裏貼上論文中幾個比較重要的圖。
在這裏插入圖片描述
在這裏插入圖片描述

3. 網絡結構調整

  在實際項目應用中,需要兼顧到模型的準確率、速度和模型大小,可以從以下方面調整所使用的網絡結構,

  (1) 最直接且常用的方法,使用作者提供的輕量一些的網絡,比如mobilenet系列,可以對比不同resolution和width的模型,以滿足產品上線要求;

  (2) 等比例減少整個網絡每一層的channels個數,比如1/2、1/4, 1/8等。以resnet50網絡爲例,雖然該模型很重,可以通過這種方法對網絡結構做簡化,使達到mobilenet等小網絡的參數量大小。

  可能大家看到這裏會提問,爲什麼不直接使用mobilenet這樣的小網絡,而要改resnet50的網絡結構然後重新訓練呢,這不是更麻煩嗎?這裏解釋一下,不同的網絡結構學習的特徵是不一樣的,假設我們得到了一個裁剪後的resnet50網絡,且其在imagenet測試集上的效果和mobilenet相當,那麼當在自己的業務數據集上做遷移學習時,可能mobilenet作爲backbone的效果卻不如裁剪後的resnet50網絡。

  (3) 知識蒸餾。就是用小的網絡模型來擬合大的網絡的效果,這種方式筆者沒有實踐過,但聽朋友說效果還不錯。

  (4) 通道剪枝。https://github.com/yihui-he/channel-pruning 提供了剪枝vgg和resnet50的代碼,但是筆者嘗試了修改剪枝resnet50的代碼,沒有復現成功。說句實話,我也不太看好這種逐層剪枝的方式,因爲需要設置很多的超參數,比如每一層要剪掉多少channels等,導致很難調試出比較好的效果。然而,最近作者在ECCV 2018又提出了使用reinforce learning進行剪枝的方法,效果很不錯,感興趣的讀者可以讀一下原文http://openaccess.thecvf.com/content_ECCV_2018/html/Yihui_He_AMC_Automated_Model_ECCV_2018_paper.html,作者暫未提供源代碼。現在鵝廠開源了PocketFlow,一個神經網絡模型的壓縮和加速庫,其提供的基於強化學習的剪枝方法比上面的“channel pruning with LASSO-based channel selection”提升了1.4個百分點,達到了67.9%,雖然跟AMC文章給出的 70.5%有很大差距,不過能夠開源也算是很不錯的了,同時也期待着該庫能夠復現出AMC文章的效果。

4. 參考資料

https://towardsdatascience.com/a-simple-guide-to-the-versions-of-the-inception-network-7fc52b863202

http://machinethink.net/blog/mobilenet-v2/.

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