【CoSOD】ICNet: Intra-saliency Correlation Network for Co-Saliency Detection
ICNet: Intra-saliency Correlation Network for Co-Saliency Detection
前言
这是南开大学发表在NeurIPS 2020上的一篇关于Co-Saliency的文章. 这篇文章同样也是利用现有的SOD方法(EGNet)设计的框架式的模型. 所以研究的关键在于如何同时利用来自SOD模型的intra-saliency cues, 并通过利用correlation techniques将其与inter-saliency cues进行整合.
整体框架
本文针对这个问题, 设计了一个模型. 整体框架如下:
- 首先利用normalized masked average pooling (NMAP) 组合单图像slaiency maps (SISMs), 提取latent intra-saliency categories
- 再利用correlation fusion module (CFM)通过利用intra cues和单张图像特征的相关性来获取inter cues
- 同时也提出了category-independent rearranged self-correlation feature (RSCF) strategy来维持特征相对于语义类别的独立性, 既可以从全局感受野中收益, 又可以提升性能
提取intra Cues
现有方法试图使用SISM作为训练目标来训练子网络, 而不是直接集成SISM到网络中端到端训练. 由于SISM的并不能准确的指示single-salient regions, 显式用其监督模型会导致不准确的intra cues.
为了更好地而集成SISM和语义特征以获取更加具有判别力的intra cues, 这里使用了normalized masked average pooling (NMAP)[Amp: Adaptive masked proxies for few-shot segmentation] 操作.
# 从VGG16 backbone中提取特征.
conv1_2 = self.vgg(image_group, 'conv1_1', 'conv1_2_mp') # shape=[N, 64, 224, 224]
conv2_2 = self.vgg(conv1_2, 'conv1_2_mp', 'conv2_2_mp') # shape=[N, 128, 112, 112]
conv3_3 = self.vgg(conv2_2, 'conv2_2_mp', 'conv3_3_mp') # shape=[N, 256, 56, 56]
conv4_3 = self.vgg(conv3_3, 'conv3_3_mp', 'conv4_3_mp') # shape=[N, 512, 28, 28]
conv5_3 = self.vgg(conv4_3, 'conv4_3_mp', 'conv5_3_mp') # shape=[N, 512, 14, 14]
# 对high-level features的特征先进行一次压缩.
conv6_cmprs = self.conv6_cmprs(conv5_3) # shape=[N, 128, 7, 7]
conv5_cmprs = self.conv5_cmprs(conv5_3) # shape=[N, 256, 14, 14]
conv4_cmprs = self.conv4_cmprs(conv4_3) # shape=[N, 256, 28, 28]
# 获得co-saliancy features.
cosal_feat_6 = self.Co6(conv6_cmprs, SISMs) # shape=[N, 128, 7, 7]
cosal_feat_5 = self.Co5(conv5_cmprs, SISMs) # shape=[N, 128, 14, 14]
cosal_feat_4 = self.Co4(conv4_cmprs, SISMs) # shape=[N, 128, 28, 28]
- 首先NMAP输入包含两部分: 来自VGG的高层特征和来自现有SOD方法(off-the-shelf SOD model)的预测结果SISM, 作者给出的理由是: we use the SISMs predicted by any off-the-shelf SOD model to directly filter out the features of potentially non-salient regions by multiplication, rather than taking these SISMs as the training targets and forcing the Co-SOD models into overfitting inaccurate SISMs with performance drop. In this way, even though the SISMs are not precisely accurate, the inaccuracy will be largely diluted after averaging and normalizing operations.
def forward(self, feats, SISMs):
N, C, H, W = feats.shape
HW = H * W
# 将SISMs调整到和输入特征feats一样的尺度.
SISMs = resize(SISMs, [H, W]) # shape=[N, 1, H, W]
- 输入一组来自VGG的后两层的l2归一化后的特征F:
# NFs: L2标准化(normalize)后的特征.
NFs = F.normalize(feats, dim=1) # shape=[N, C, H, W]
- 使用对应的SISM S来对其放缩并生成single-image vectors (SIVs), 如式1. 也即是先空间上加权平均后在进行l2归一化:
# 计算 SIVs [3.2节, 式1].
SIVs = F.normalize((NFs * SISMs).mean(dim=3).mean(dim=2), dim=1).view(N, C, 1, 1) # shape=[N, C, 1, 1]
提取Inter Cues
这部分主要设计来提取intra cues之间的Inter cues. 不同于现有方法通过拼接、或者使用固定数量图片分组(这类方法使用循环结构, 对于输入顺序有依赖, 而固定的数量也会导致, 预定义类别上学习到的语义矢量难以处理看到没有见过的目标类别)来整合特征, 为此作者提出了correlation fusion module (CFM) 来避免以上的这些问题.
受到VOS的启发, 这座认为获得准确CoSOD map的关键在于_dense correlations between the SIVs and single-image features_, 所以CFM主要就是在计算SIV中的V和SISM中的F之间的像素级相关性, 从而可以生成有用的inter cues, 并且处理任意数量的图片组. 主要过程如下:
- 该部分输入包含两部分, 前面得到的SIV特征V和l2归一化后的来自VGG的特征F:
# 计算 co-salient attention (CSA) maps [3.3节].
CSA_maps = CFM(SIVs, NFs) # shape=[N, 1, H, W]
- 使用SIV中的矢量(
shape=[N, C, 1, 1]
这里直接作为F.conv2d的权重, 也就是对应于\((\text{out_channels} , \frac{\text{in_channels}}{\text{groups}} , kH , kW)\)的卷积核, 与归一化特征计算相似性(内积), 从而获得correlation maps C, 这里实际上关联起了单样本特征内部的通道和外部样本的分组.
def CFM(SIVs, NFs):
# 计算SIVs和NFs中每个像素的内积, 产生correlation maps [图4].
# 我们通过 ``F.conv2d()'' 来实现这一过程, 其中将SIVs作为1*1卷积的参数对NFs进行卷积.
correlation_maps = F.conv2d(NFs, weight=SIVs) # shape=[N, N, H, W]
- 但是由于SIVs并不表示co-salient category类别, 所以生成的相关图会强调与co-salient category无关的区域. 为了抑制这些噪声的影响, 作者进一步使用相关图之间的相关性对自身加权.
# 向量化(vectorize)并标准化(normalize) correlation maps.
correlation_maps = F.normalize(correlation_maps.reshape(N, N, HW), dim=2) # shape=[N, N, HW]
# 计算权重向量(weight vectors) [式2].
correlation_matrix = torch.matmul(correlation_maps, correlation_maps.permute(0, 2, 1)) # shape=[N, N, N]
weight_vectors = correlation_matrix.sum(dim=2).softmax(dim=1) # shape=[N, N]
- 接下来使用权重W加权C, 获得一个co-salient attention (CSA) map A, 作为F的Inter cue.
# 根据权重向量(weight vectors)对correlation maps进行融合, 产生co-salient attention (CSA) maps.
CSA_maps = torch.sum(correlation_maps * weight_vectors.view(N, N, 1), dim=1) # shape=[N, HW]
- 之后使用min-max归一化操作获得A. 这样的相关性权重可以在一定程度上弱化噪声的影响, 因为有噪声的相关图和其他相关图势必有更小的相关性.
# Max-min normalize CSA maps (将CSA maps的范围拉伸至0~1之间).
min_value = torch.min(CSA_maps, dim=1, keepdim=True)[0]
max_value = torch.max(CSA_maps, dim=1, keepdim=True)[0]
CSA_maps = (CSA_maps - min_value) / (max_value - min_value + 1e-12) # shape=[N, HW]
CSA_maps = CSA_maps.view(N, 1, H, W) # shape=[N, 1, H, W]
return CSA_maps
Rearranged Self-Correlation Feature
获得CSA map之后, 正如[Co-saliency detection via mask-guided fully convolutional networks with multi-scale label smoothing]中建议的, 将其与l2规范化的特征F相乘来专注于co-salient region和最终预测得到Co-SOD map A. 然而, 观察到这种方式下, 模型不能判断有着相似但是却不同类别的像素.这主要是因为A和F之间不一致的类别依赖.
- A是category-independent且可以反映出潜在的co-saliency socre得分
- F是category-related且每个像素都是一个表示特定类别的向量
- 为了计算SCF, 这里需要输入前面的归一化特征F.
# 计算 self-correlation features (SCFs) [3.4节].
SCFs = get_SCFs(NFs) # shape=[N, HW, H, W]
- 计算F内部的自相关矩阵, 并调整维度. 最终得到的张量中, 会表示F中的任一点与全图HxW之间的相关性. 这确保SCF不依赖于特定的类别信息, 而是与全局有关.
def get_SCFs(NFs):
NFs = NFs.view(N, C, HW) # shape=[N, C, HW]
SCFs = torch.matmul(NFs.permute(0, 2, 1), NFs).view(N, -1, H, W) # shape=[N, HW, H, W]
return SCFs
- 虽然SCF与CSA的组合受益于类别独立的一致性, 但是SCF的使用可能导致潜在的过拟合风险, 这是因为SCF中的每个通道是一个关于某个空间位置的自相关图, 这使得基于固定通道顺序学习到的参数是位置相关的. 为了缓解这一问题, 这里对SCF使用了通道重排的策略.
- 对于通道重排, 这里是基于得到的CSA作为索引参考的. 也就是在A中有着更高co-saliency value的位置, 在F中的对应的\(z=(x-1)W+y\)通道会被放置到重新生成的RSCF F中的靠上的通道位置里. 这样的设计使得FSCF中的通道顺序独立于像素位置. 这里使用
gather
方法对SCF的通道进行调整.
# 重排列(Rearrange)SCFs的通道顺序, 产生RSCFs [3.4节].
evidence = CSA_maps.view(N, HW) # shape=[N, HW]
indices = torch.argsort(
evidence, dim=1, descending=True
).view(N, HW, 1, 1).repeat(1, 1, H, W) # shape=[N, HW, H, W]
RSCFs = torch.gather(SCFs, dim=1, index=indices) # shape=[N, HW, H, W]
cosal_feat = self.conv(RSCFs * CSA_maps) # shape=[N, 128, H, W]
实验细节
-
训练设置:
- 数据集为COCO的9213张子集图片, 可在github上下载到.
- 输入尺寸为:224x224.
- 每个迭代的batch是一组包含10个图像的分组
-
测试设置:
- 输入尺寸为:224x224.
- 每个包含任意数量的图像的图像组作为一个batch, 一次性预测结果(也就是整个测试数据中的图像组一起处理).
-
损失函数:
- IOUloss:
失败案例分析
由于本文的模型构建与SISM之上, 当使用的SISM不够可靠的时候, 会出现CoSOD的错误预测. 作者回应道, 虽然失败案例可能会让人怀疑我们的ICNet的健壮性, 但这种极端情况很少发生. 同时, 我们的实验表明, 只要不是大部分的SISM是不可靠的, ICNet就可以稳定地运行.