VoVNet:實(shí)時(shí)目標(biāo)檢測(cè)的新backbone網(wǎng)絡(luò)
AI編輯:我是小將
目前基于深度學(xué)習(xí)的目標(biāo)檢?測(cè)模型無不依賴CNN分類網(wǎng)絡(luò)來作為特征提取器,如SSD采用VGG,YOLO采用DarkNet,F(xiàn)aster R-CNN采用ResNet,我們一般稱這些網(wǎng)絡(luò)為目標(biāo)檢測(cè)模型的backbone。ResNet是目標(biāo)檢測(cè)模型最常用的backbone,DenseNet其實(shí)比ResNet提取特征能力更強(qiáng),而且其參數(shù)更少,計(jì)算量(FLOPs)也更少,用于目標(biāo)檢測(cè)雖然效果好,但是速度較慢,這主要是因?yàn)镈enseNet中密集連接所導(dǎo)致的高內(nèi)存訪問成本和能耗。VoVNet就是為了解決DenseNet這一問題,基于VoVNet的目標(biāo)檢測(cè)模型性能超越基于DenseNet的模型,速度也更快,相比ResNet也是性能更好。
高效網(wǎng)絡(luò)設(shè)計(jì)要素
在設(shè)計(jì)輕量級(jí)網(wǎng)絡(luò)時(shí),F(xiàn)LOPs和模型參數(shù)是主要考慮因素,但是減少模型大小和FLOPs不等同于減少推理時(shí)間和降低能耗。比如ShuffleNetv2與MobileNetv2在相同的FLOPs下,前者在GPU上速度更快。所以除了FLOPs和模型大小外,還需要考慮其他因素對(duì)能耗和模型推理速度的影響。這里考慮兩個(gè)重要的因素:內(nèi)存訪問成本(Memory Access Cost,MAC)和GPU計(jì)算效率。
(1)內(nèi)存訪問成本
對(duì)于CNN網(wǎng)路來說,內(nèi)存訪問比計(jì)算對(duì)能耗貢獻(xiàn)還大,如果網(wǎng)絡(luò)中間特征比較大,甚至在同等模型大小下內(nèi)存訪問成本會(huì)增加,所以要充分考慮CNN層的MAC。在ShuffleNetV2論文中給出計(jì)算卷積層MAC的方法:
這里的 分別為卷積核大小,特征高和框,以及輸入和輸出的通道數(shù)。卷積層的計(jì)算量,如果固定的話,那么有:
根據(jù)均值不等式,可以知道當(dāng)輸入和輸出的channel數(shù)相同時(shí)MAC才取下界,此時(shí)的設(shè)計(jì)是最高效的。
(2)GPU計(jì)算效率
GPU計(jì)算的優(yōu)勢(shì)在于并行計(jì)算機(jī)制,這意味著當(dāng)要計(jì)算的tensor較大時(shí)會(huì)充分發(fā)揮GPU的計(jì)算能力。如果將一個(gè)較大的卷積層拆分成幾個(gè)小的卷積層,盡管效果是相同的,但是卻是GPU計(jì)算低效的。所以如果功效一樣,盡量采用較少的層。比如MobileNet中采用深度可分離卷積(depthwise conv+1x1 conv)雖然降低了FLOPs,但是因?yàn)轭~外的1x1卷積而不利于GPU運(yùn)算效率。相比FLOPs,我們更應(yīng)該關(guān)注的指標(biāo)是FlOPs per Second,即用總的FLOPs除以總的GPU推理時(shí)間,這個(gè)指標(biāo)越高說明GPU利用越高效。
OSA(One-Shot Aggregation)模塊
對(duì)于DenseNet來說,其核心模塊就是Dense Block,如下圖1a所示,這種密集連接會(huì)聚合前面所有的layer,這導(dǎo)致每個(gè)layer的輸入channel數(shù)線性增長(zhǎng)。受限于FLOPs和模型參數(shù),每層layer的輸出channel數(shù)是固定大小,這帶來的問題就是輸入和輸出channel數(shù)不一致,如前面所述,此時(shí)的MAC不是最優(yōu)的。另外,由于輸入channel數(shù)較大,DenseNet采用了1x1卷積層先壓縮特征,這個(gè)額外層的引入對(duì)GPU高效計(jì)算不利。所以,雖然DenseNet的FLOPs和模型參數(shù)都不大,但是推理卻并不高效,當(dāng)輸入較大時(shí)往往需要更多的顯存和推理時(shí)間。

圖1 DenseNet與VoVnet模塊對(duì)比
DenseNet的一大問題就是密集連接太重了,而且每個(gè)layer都會(huì)聚合前面層的特征,其實(shí)造成的是特征冗余,而且從模型weights的L1范數(shù)會(huì)發(fā)現(xiàn)中間層對(duì)最后的分類層貢獻(xiàn)較少,這不難理解,因?yàn)楹竺娴奶卣髌鋵?shí)已經(jīng)學(xué)習(xí)到了這些中間層的核心信息。這種信息冗余反而是可以優(yōu)化的方向,據(jù)此這里提出了OSA(One-Shot Aggregation)模塊,如圖1b所示,簡(jiǎn)單來說,就是只在最后一次性聚合前面所有的layer。這一改動(dòng)將會(huì)解決DenseNet前面所述的問題,因?yàn)槊總€(gè)layer的輸入channel數(shù)是固定的,這里可以讓輸出channel數(shù)和輸入一致而取得最小的MAC,而且也不再需要1x1卷積層來壓縮特征,所以O(shè)SA模塊是GPU計(jì)算高效的。那么OSA模塊效果如何,論文中拿DenseNet-40來做對(duì)比,Dense Block層數(shù)是12,OSA模塊也設(shè)計(jì)為12層,但是保持和Dense Block類似的參數(shù)大小和計(jì)算量,此時(shí)OSA模塊的輸出將更大。最終發(fā)現(xiàn)在CIFAR-10數(shù)據(jù)集上acc僅比DenseNet下降了1.2%。但是如果將OSA模塊的層數(shù)降至5,而提升layer的通道數(shù)為43,會(huì)發(fā)現(xiàn)與DenseNet-40模型效果相當(dāng)。這說明DenseNet中很多中間特征可能是冗余的。盡管OSA模塊性能沒有提升,但是MAC低且計(jì)算更高效,這對(duì)于目標(biāo)檢測(cè)非常重要,因?yàn)闄z測(cè)模型一般的輸入都是較大的。
VoVNet
VoVNet由OSA模塊構(gòu)成,主要有三種不同的配置,如下表所示。VoVNet首先是一個(gè)由3個(gè)3x3卷積層構(gòu)成的stem block,然后4個(gè)階段的OSA模塊,每個(gè)stage的最后會(huì)采用一個(gè)stride為2的3x3 max pooling層進(jìn)行降采樣,模型最終的output stride是32。與其他網(wǎng)絡(luò)類似,每次降采樣后都會(huì)提升特征的channel數(shù)。VoVNet-27-slim是一個(gè)輕量級(jí)模型,而VoVNet-39/57在stage4和stage5包含更多的OSA模塊,所以模型更大。
表1 VoVNet架構(gòu)
VoVNet在檢測(cè)模型上的效果
VoVNet可以作為檢測(cè)模型的backbone,論文中共對(duì)比了3個(gè)檢測(cè)模型:DSOD,RefineDet和Mask R-CNN。前兩個(gè)是one stage檢測(cè)模型,而Mask R-CNN是two stage實(shí)例分割模型(三個(gè)模型都是train from scratch,而不是用了ImageNet預(yù)訓(xùn)練模型)。首先是DSOD,這個(gè)模型原先的backbone是DenseNet,現(xiàn)在替換為VoVNet,VOC數(shù)據(jù)集上對(duì)比效果如下表所示:
表2 DSOD檢測(cè)模型效果對(duì)比
可以看到相比DenseNet,基于VoVNet的檢測(cè)模型推理速度提升了一倍,而且效果更好,這說明VoVNet比DenseNet更高效。
另外是Mask R-CNN的結(jié)果如下表所示,可以看到VoVNet比ResNet效果更好,且推理時(shí)間稍低一些。這說明VoVNet充分繼承了DenseNet的優(yōu)勢(shì),但是計(jì)算更高效。
表3 Mask R-CNN模型效果對(duì)比
VoVNetV2
VoVNet只是繼承了DenseNet的優(yōu)點(diǎn),但是可以走的更遠(yuǎn),這就是CenerMask這篇論文所提出的改進(jìn)版本VoVNetV2。簡(jiǎn)單來說,VoVNetV2引入了ResNet的殘差連接和SENet的SE模塊:

圖2 VoVNetV2中的改進(jìn)OSA模塊
從圖2b可以看到,改進(jìn)的OSA模塊直接將輸入加到輸出上,增加短路連接,使得VoVNet可以訓(xùn)練更深的網(wǎng)絡(luò),論文中是VoVNet-99。從圖2c可以看到,改進(jìn)的另外一個(gè)點(diǎn)是在最后的特征層上加上了sSE模塊來進(jìn)一步增強(qiáng)特征,原始的SE模塊包含兩個(gè)FC層,其中中間的FC層主要是為降維,這在一定程度上會(huì)造成信息丟失。而sSE模塊是去掉了這個(gè)中間FC層。VoVNetV2相比VoVNet增加了少許的計(jì)算量,但是模型性能有提升:
表4 CenterMask模型效果對(duì)比
VoVNetV2的PyTorch實(shí)現(xiàn)
論文作者開源了VoVNet的實(shí)現(xiàn)代碼,是基于PyTorch的,OSA模塊的實(shí)現(xiàn)如下:
class _OSA_module(nn.Module):
def __init__(
self, in_ch, stage_ch, concat_ch, layer_per_block, module_name, SE=False, identity=False, depthwise=False
):
super(_OSA_module, self).__init__()
self.identity = identity
self.depthwise = depthwise
self.isReduced = False
self.layers = nn.ModuleList()
in_channel = in_ch
if self.depthwise and in_channel != stage_ch:
self.isReduced = True
self.conv_reduction = nn.Sequential(
OrderedDict(conv1x1(in_channel, stage_ch,
"{}_reduction".format(module_name), "0")))
for i in range(layer_per_block):
if self.depthwise:
self.layers.append(
nn.Sequential(OrderedDict(dw_conv3x3(stage_ch, stage_ch, module_name, i))))
else:
self.layers.append(
nn.Sequential(OrderedDict(conv3x3(in_channel, stage_ch, module_name, i)))
)
in_channel = stage_ch
# feature aggregation
in_channel = in_ch + layer_per_block * stage_ch
self.concat = nn.Sequential(
OrderedDict(conv1x1(in_channel, concat_ch, module_name, "concat"))
)
self.ese = eSEModule(concat_ch)
def forward(self, x):
identity_feat = x
output = []
output.append(x)
if self.depthwise and self.isReduced:
x = self.conv_reduction(x)
for layer in self.layers:
x = layer(x)
output.append(x)
x = torch.cat(output, dim=1)
xt = self.concat(x)
xt = self.ese(xt)
if self.identity:
xt = xt + identity_feat
return xt
這里的OSA模塊包含了sSE模塊以及殘差模塊,另外支持depthwise卷積,OSA模塊是VoVNet的核心,最終的VoVNet的實(shí)現(xiàn)可以見vovnet-detectron2
參考
An Energy and GPU-Computation Efficient Backbone Network for Real-Time Object Detection https://arxiv.org/abs/1904.09730 CenterMask : Real-Time Anchor-Free Instance Segmentation https://arxiv.org/pdf/1911.06667.pdf vovnet-detectron2 https://github.com/youngwanLEE/vovnet-detectron2/blob/master/vovnet/vovnet.py
推薦閱讀
堪比Focal Loss!解決目標(biāo)檢測(cè)中樣本不平衡的無采樣方法
PyTorch重大更新:將支持自動(dòng)混合精度訓(xùn)練!
另辟蹊徑!斯坦福大學(xué)提出邊界框回歸任務(wù)新Loss:GIoU
機(jī)器學(xué)習(xí)算法工程師
一個(gè)用心的公眾號(hào)

