ICCV2019
论文:
代码:https://github.com/Legion56/Counting-ICCV-DSSINet
由于人群计数的数据中,人群的数目存在着较大的变化,因此一种做法是提炼图片不同尺度的特征进行融合,但在人群计数中许多的做法仅仅是对主干网络不同层级的特征进行融合,而这篇文章中使用了多个子网络,使用不同尺寸的图片作为输入来得到不同尺度的特征,对这些特征又提出了使用CRF来融合.
为解决人的尺度变化,结构特征表示学习和结构优化损失函数.
论文贡献:
1。特征的融合方式上,不是简单的加权叠加或者通道拼在一起。使用了条件随机场CRFS的Structured feature enhancement modeule去融合不同层之间的feature,通过消息传递机制对多尺度特征进行细化,达到互补目的。
2.改进了SSIM这个LOSS,提出了Dilation和SSIM结合的DMS-SSIM, 一种在不同尺寸下,对局部区域输出高质量密度图的loss计算方式
3、 SFEM模块,将两个子网络的特征作为输入,融合厚的特征作为输出,融合的过程借鉴了条件随机场CRF的思想,由势函数:
网络结构模型:
backbone依然采用VGG16,代码中采用的结构是
'I': [24, 22, 'M', 41, 51, 'M', 108, 89, 111, 'M', 184, 276, 228],
表-VGG16
Input(224*224*3) | output | |
Conv3-24 conv3-22 | conv1_1 conv1_2 | 224*224*3 224*224*3 |
maxpool | 112*112*3 | |
Conv3-41 Conv3-51 | conv2_1 conv2_2 | 112*112*3 112*112*3 |
maxpool | 56*56*3 | |
Conv3-108 conv3-89 conv3-111 | conv3_1 conv3_2 conv3_3 | 56*56*3 56*56*3 56*56*3 |
maxpool | 28*28*3 | |
Conv3-184 conv3-276 conv3-228 | conv4_1 conv4_2 conv4_3 | 28*28*3 28*28*3 28*28*3 |
而值得注意的是,网络由三个平行子网络组成,每个子网络具有相同的结构并共享参数,如下图所思,这些子网络由VGG16的10个卷积层构成,每个子网络输入图片的大小分别为原图的2倍,原大小和0.5倍大小。
假设输入图片尺寸H*W,首先构造一个三层金字塔
其中,是原始图像,是相应的缩放图.
每个图像都会被送入其中的一个子网络. 经过VGG16的部分卷积网络convi_j后,可以得到特征图. 然后,我们将从不同子网络得到的具有同样分辨率的特征图放在一起,形成4个具有不同尺寸的特征集合
结合表-VGG16来看,假设输入图片原始尺寸224*224*3,则图片尺寸为448*448*3, 图片尺寸为224*224*3, 图片尺寸为448*448*3,
可以看出上面特征图所形成的集合,集合内特征图除了通道数不同,宽高是相同的.因为同一个集合中的特征图是由不同的感受野,不同尺寸的图像经过不同的卷积层得到的,他们之间可以互补.例如,主要包含了外观信息,编码了部分的高级语义信息,为了提高尺度变化的鲁棒性,我们对上述4个集合中的特征通过SFEM模块进行精调. 因为具有更丰富的信息, 由增强得到的特征对尺度变化具有更强的鲁棒性.因此,被送入后续网络做深层特征提取.不同大小的图片经过不同数量的下采样子模块,在输入SFEM结构时,特征具有相同大小的尺寸。不同大小的图片通过不同数量的下采样子模块,在输入SFEM结构时,特征具有相同大小的尺寸。三个不同分辨率的图片经过三个网络支干,不断进行卷积&下采样,融合不同支干网络的特征,并小特征不断进行上采样再与之前的特征融合(类似FPN的模型流程)
论文最核心的两个东西就是图中的SFEM和DMS-SSIM,这里的conv2_2表示VGG16的第二个卷积块的第二层,也就是说这里每个convx_y其实代表了VGG16的一个卷积块。结构特征学习之后,我们得到了一个高分辨率的密度图.首先,我们对最后的特征做1*1的卷积以便使其通道降低到128维,然后对这个压缩特征做3*3卷积获得密度图M4.
CFRVGG_prune.py
dens1 = self.decoder1(mp_scale3_feature_conv4)
self.decoder1 = nn.Sequential(
Conv2d_dilated(228, 128, 1, dilation=1, same_padding=True, NL='relu', bn=bn),#1*1卷积,压缩通道到128维度
Conv2d_dilated(128, 1, 3, dilation=1, same_padding=True, NL=None, bn=bn),#3*3卷积,可以获得1通道的密度图M4
)
然而, M4的分辨率较低,为, M4缺乏人的空间信息. 为了解决这个问题,我们在低层生成了其他4个密度图,它,他们的分辨率是.特别的, 把concat 到一起的送入一个stacked卷积网络(第1个为1*1的卷积层被用来降维,第2个3*3卷积网络被用来回归),可以得到.是用同样的方式得到的.然或将这5个密度图逐步通过较深的密度图,
代码中,w_i=1, 是一个3*3的卷积层,UP()代表双线性插值,是由的精细调整得到的.最终得到密度图具有较好的人的空间分布信息.
dens1 = self.decoder1(mp_scale3_feature_conv4)#\tidle{M}4精细调节到M4
dens2 = self.decoder2(aggregation1)#M3
dens3 = self.decoder3(aggregation2)#M2
dens4 = self.decoder4(aggregation3)#M1
dens5 = self.decoder5(aggregation4)#M0
dens1 = self.prelu(dens1)#M4
#M3=M3+W1*M4 ,此处的M4需要上采样,保持维度与M3相同
dens2 = self.prelu(dens2 + self.passing_weight1(nn.functional.upsample(dens1, scale_factor=2, align_corners=False, mode="bilinear")))
#M2=M2+W2*M3 ,此处的M3是由上面融合得到的,并需要上采样,保持维度与M2相同
dens3 = self.prelu(dens3 + self.passing_weight2(nn.functional.upsample(dens2, scale_factor=2, align_corners=False, mode="bilinear")))
# M1=M1+W3*M2 此处的M2是由上面融合得到的,并需要上采样,保持维度与M1相同
dens4 = self.prelu(dens4 + self.passing_weight3(nn.functional.upsample(dens3, scale_factor=2, align_corners=False, mode="bilinear")))
dens5 = self.relu(dens5 + self.passing_weight4(nn.functional.upsample(dens4, scale_factor=2, align_corners=False, mode="bilinear")))
图片被resize到3个scale,一个是放大原图的2倍,一个是缩小到原图的一半,一个是原始尺寸,然后分别输入VGG16,本文用了VGG16的前面4个卷积块,共10层,然后,这里的3个VGG16其实是一个模型,因为他们之间是共享权重的,然后SFEM用来优化某几层输出的feature,再传入下一层,M0,M1,...M4表示density map,最后对M0去计算DMS-SSIM loss,他们没有用MSE loss去训练。
M4是最后conv4_3输出的228层的feature,先用1×1卷积降到128层,然后用3*3的卷积预测一个密度图,然后M3是concat conv4_3和conv3_3的feature,然后先用1×1降到128层,再用3×3卷积输出密度图,再跟M4用一个1*1的卷积加权求和:
依次类推,从M4最终获得跟输入图像一样分辨率的density map M0
SFEM模块结构化特征增强模块
作者提出了一个统一的结构化特征增强模块(SFEM),以提高特征对尺度变化的鲁棒性。受密集预测工作的启发,我们的SFEM通过充分利用条件随机场(CRFs)模型的互补性,在不同尺度上相互细化特征。SFEM模块是利用条件随机场来实现feature的优化的,假设图中某个SFEM模块的输入的feature为f1,f2,f3,那么优化后的featuref1',f2',f3',主要的操作就是一种迭代更新的机制,某一路的feature,要加上其他路的feature经过1*1卷积的结果,然后这样迭代n次,就实现了不同层的feature的融合了,虽然论文中实际上还有一些关于条件随机场CRF的推导,但是实际操作就是这么简单的迭代。距离来讲,假如现在有两个特征图
则SFEM对A,B的精细化特征修订为:
若有3个特征图,则SFEM对A,B,C的精细化特征修订为:
代码实现为
CRFVGG_Prune.py
#SFEM模块,对特征进行refine, 将扩大的图片与原始图片的特征进行融合
mp_scale1_feature_conv2, mp_scale2_feature_conv1 \
= self.passing1([mp_scale1_feature_conv2_na, mp_scale2_feature_conv1_na])
self.passing1 = MessagePassing( branch_n=2, #这个表征的是过来了2张特征图
input_ncs=[51, 22],#这两张特征图的通道数分别为51和22
)#input_ncs=[51, 22]是因为放大2倍的图片经过[0,7]的特征提取后,通道变成了51, 原始人尺寸的图片经过
#[0,2]的特征提取后,通道变成了22,所以这个本质表征的是输入图片的通道数
DMS-SSIM loss
DMS: Dilated(膨胀) multiscale structural similarity(DMS-SSIM)
论文之所以将dilation用到SSIM中,是觉得传统的ssim loss的感受野太小(为什么?),只能把握很小的局部信息,但是一些大结构的信息很难把握,于是用了dilation,增加感受野,对每个像素,测量以其为中心的多尺度区域上predicition 和gt之间的结构相似性.SFEM融合完得到的最终特征为X0,X0就是预测的跟图像同分辨率的density map M0,GT是Y0,然后对X0,Y0做同样的膨胀卷积,网络包含m个膨胀卷积层,这些层的参数是固定的归一化,偏差为1的,5*5高斯核,高斯核被,用DMS-SSIM网络来计算二者的LOSS.
DMS-SSIM是一个若干层的膨胀卷积(使用固定的,且共享的高斯核参数),得到不同层级的特征,具体计算公式为文中(8).
相比于没有dilation,空洞卷积使得每一层的感受野加大了,这样后面层级的特征,每个像素相当于融合了附近多个scale,然后对于每一对Xi,Yi,先计算均值,方差,协方差,再计算亮度L,对比度C,结构S,最后乘起来,这样再计算loss可以在不同scale都取得很好效果.然后对多个层级特征,应用一些统计学指标来度量相似性: