文章目录
最近在做的一个比赛,用到了Deeplabv3,顺便看了一下源码,记录一下。
预备知识
本文提到的output_stride来源于deeplabv3论文,指的是(输入图像的分辨率/特征图的分辨率),可以看出,output_stride越大,说明特征图越小,越高层。
ResNet50
ResNet50包括一个Init Block和四个stage,以及最后的Avgpool和fc。下采样了32倍。(一般的分类网络都是下采样32倍)
1. Init Block
由3个3×3的卷积层+一个maxpooling层组成,其中一个卷积层的stride为2,因此经过Init block后的输出尺寸降了4倍。 Init Block输出为64通道。
2. stage1-4
stage1-4的残差块个数依次为[3,4,6,4]
- stage1
stage1由三个unit(残差单元)构成,都是1×1或3×3的小卷积,且stride都为1,因此经过stage1后的输出尺寸相对于原图还是降了4倍(与Init block的输出尺寸相同),stage1输出为256通道。 - stage2
stage2由四个unit组成,其中unit1的3×3卷积核stride为2,因此,经过stage2后的输出尺寸相对于原图降了8倍,stage2输出为512通道。 - stage3
stage3由六个unit组成,其中unit1的3×3卷积核stride为2,因此,经过stage3后的输出尺寸相对于原图降了16倍,stage3输出为1024通道。 - stage4
stage4由三个unit组成,其中unit1的3×3卷积核stride为2,因此,经过stage4后的输出尺寸相对于原图降了32倍 ,stage4输出为2048通道。
3. Avgpooling
4. FC
输出为num_class(分类的数量)
Deeplabv3原理分析
自己随手画了一个Deeplabv3的结构图,便于理解,backbone用的是ResNet50。
1.Init Block
输入Image,经过Init Block,这里的Init Block就是ResNet50的那个。经过Init block后的输出尺寸降了4倍。(用output_stride=4来描述)
2. 四个stage
-
经过stage1阶段,stage1由三个unit(残差单元)构成,且stride都为1,因此经过stage1后的输出尺寸相对于原图还是降了4倍(与Init block的输出尺寸相同)(output_stride=4)
-
经过stage2,stage2由四个unit组成,其中unit1的3×3卷积核stride为2,因此,经过stage2后的输出尺寸相对于原图降了8倍(output_stride=8)
-
经过stage3,stage3由六个unit组成,其中unit2-unit6的3×3卷积中使用了rate=2的空洞卷积,因此经过stage3后的输出尺寸相对于原图降了8倍(output_stride=8),但是感受野相对于原图降了4倍
-
经过stage4,stage4由三个unit组成,unit1中3×3卷积的rate=2,unit2,unit3中3×3卷积的rate=4,因此,经过stage4后的输出尺寸相对于原图降了8倍(output_stride=8),但是感受野与原图一样大。
3. ASPP(核心模块)
ASPP的输入:stage4的输出特征图;
ASPP的输出:output_stride=8的特征图(尺寸相当于原图降了8倍),但是感受野相当于原图。
ASPP的结构包括5个branch,第一个branch为1×1卷积,中间三个branch为空洞卷积,第五个branch为全局平局池化层+1×1卷积层。五个branch做融合得到ASPP的输出。
ASPP的具体结构包括(结合图一起看):
- 第一个branch是普通的1×1卷积层
- 前二、三、四个branch为3×3的空洞卷积层,rate分别为12,24,36(output_size=8的时候,rate依次为12,24,36,如果output_size=16,rate应该依次变成6,12,18)
- 第五个branch论文中称为Image Pooling,是一个Avgpooling(获得全局信息)外加一个1×1卷积(改变通道数)(因为pooling无法改变通道数,而为了保证五个branch的输出通道数相等,后面必须再接一个卷积)。
- 五个branch的输出都是256维(一共1280维),使用1×1卷积将这五个branch输出的结果进行融合(concat),最后输出256维的新特征。
4. Final_block
Final_block的输入为:ASPP的输出;
Final_block的输出为:num_class张分割掩码结果图;
Final block包含两个卷积层和一个unsampling:
- 一个3×3卷积做的是concat操作(过渡作用)
- 一个1×1卷积,改变输出通道数为num_class。
- 再将num_class张特征图使用bilinear的方式插值到输入图片的尺寸,至此,得到了deeplabv3的输出。
5. 关于aux_block分支
aux_block分支与Final_block分支很像,也是由两个卷积层+upsampling构成,输出的也是num_class张分割掩码图。aux分支与Final_block的区别是,aux的输入是stage3的输出(相当于从stage3后直接输出结果。)
aux分支往往只用来训练,不用于测试。