GSANet
论文阅读
- code: https://github.com/Hydragon516/GSANet
摘要
无监督视频对象分割是指分割出视频序列中最引人注目的对象。然而,复杂背景和多个前景对象的存在使得这一任务具有挑战性。针对这一问题,提出了一种引导槽注意力网络来增强空间结构信息,获得更好的前景-背景分离。根据与模板信息的交互,对用query指导初始化的前台和后台槽进行迭代细化。此外,为了改善槽-模板的交互性,有效融合目标帧和参考帧的全局和局部特征,引入了K近邻滤波和特征融合Transformer。实验结果表明,该方法在两个常用的数据集上均达到了最佳的性能。此外,通过各种对比实验,验证了该模型在复杂场景下的鲁棒性。
1.引言
1.1背景及问题
视频目标分割是计算机视觉领域中的一个重要课题,其目的是对视频序列中的目标进行逐帧分割。VOS被用作视频字幕[27]、光流估计[2]、自动驾驶[1,12,17]的预处理。VOS任务可分为半监督和无监督两种,这取决于是否存在明确的目标监督。在半监督VOS中,模型具有用于初始帧的分割掩模,并且其目标是在整个视频序列中跟踪和分割指定的对象。另一方面,无监督VOS要求模型在没有任何外部指导或初始帧掩码的情况下找到并分割视频序列中最显著的对象。无监督VOS是一项更具挑战性的任务,因为它涉及搜索在输入视频中一致出现的常见对象并有效地提取它们的特征。
由于无监督VOS的困难,基于深度学习的无监督VOS模型[3,7,9,19,22,33,35,38]最近受到关注。特别是,许多方法[3,7,9,38]将额外的运动信息(如光流)与RGB外观信息相结合,这是由目标对象通常表现出独特运动的事实所激励的。这些方法的重点是如何正确地融合外观和运动信息。这两类信息可以相互补充,产生有用的预测线索。然而,它们的问题在于,它们过度依赖于运动线索,并且忽略了场景的结构信息,例如颜色、纹理和形状。在场景具有复杂结构或者光流图的质量低的情况下,这些方法不能可靠地操作。
1.2提出方法:Guided Slot Attention Net
- 引言
为解决该问题,我们提出使用slot attention,该机制一开始由目标中心学习提出。该机制使得模型能够从富含上下文信息的特征中提取关键的空间结构信息,该信息对于区分前景和背景是必要的。我们之所以关注slot attention,是因为对象中心学习和无监督VOS都有一个共同的直觉,即这两种方法都旨在自学习并分割对象和背景的区别特征。
相关知识引入:
- “Object-centric” learning(以对象为中心的学习)描述一种学习方法,其中系统或模型专注于识别和理解图像或场景中的单个对象,而不是仅仅处理整个图像或场景作为一个整体。
- Slot:在机器学习模型中,slot 通常指的是一个特定的位置或“槽”,用于存储或处理特定的信息。在注意力机制的上下文中,slot 可以代表输入序列中的一个特定部分,比如一个词或一个短语。slot attention 允许模型在处理序列数据时,特别关注那些预先定义好的、与特定任务相关的 slot。这可以提高模型对关键信息的敏感性,从而提高性能。
相关文章:Object-Centric Learning with Slot Attention
- slot attention机制
在以目标为中心的学习中,槽注意(即slot attention)随机产生初始化的空槽,并利用输入图像特征进行迭代多头注意,以存储每个槽的个体目标和背景信息。在每个槽中的对象和背景的这些存储的个体信息通过捕获个体对象及其上下文的独特特性和交互来提供鲁棒的前景和背景辨别能力。这种区分的直觉也可以应用于无监督的VOS模型,以提高区分最显著对象的能力。
- slot attention存在的缺陷
然而,现有的基于槽注意力的图像分割方法[14,32,39]具有明显的局限性,因为它们仅在具有统一颜色和布局的合成图像或通过颜色和形状清楚区分的对象,或简单纹理(例如光流图)上工作,并且它们的性能在复杂的真实世界场景中降低。这种限制的产生有几个原因,包括:1)随机初始化的时隙难以表示复杂场景中的合理上下文,2)现有的简单多头注意操作缺乏鲁棒的特征辨别能力,以及3)在存在复杂背景和多个相似对象的情况下,对所有输入特征的注意可能充当噪声。
- 引导槽注意力网络 Guided Slot Attention Net
为了解决这个问题,我们提出了一种新的引导槽注意力网络(GSA-Net)的机制,使用引导槽,功能聚合Transformer(FAT),和K-最近邻(KNN)过滤。图1表明,所提出的引导槽注意即使在具有挑战性的场景中也能保持强大的前景和背景分离能力。
引导槽:通过嵌入上下文信息来生成引导槽,引导槽允许模型保持强壮的上下文提取能力
FAT:从key frame和参考帧中提取并聚合全局和局部特征
KNN:采样特征空间中靠近槽的特征,从而为槽重构传递有用信息
1)该模型通过从编码器的目标帧特征中嵌入上下文信息来生成引导槽,该上下文信息包括关于前景和背景候选的粗略空间结构信息。与现有的基于随机初始化的空槽作为查询特征的槽注意机制不同,本文提出的方法避免了在迭代多头注意的初始阶段槽的错误训练.另外,向槽提供引导信息允许模型在复杂的真实世界场景中保持鲁棒的上下文提取能力。
2)此外,该模型还从目标帧和参考帧中提取并聚合全局和局部特征,作为GSA的关键和价值。为此,我们设计FAT来创建有效地聚合局部和全局特征的特征。这些特征与引导槽一起被迭代地关注,以通过传达丰富的上下文信息来逐步地细化槽的空间信息。通过这种方式,我们补充了以往的槽注意的简单多头附着,提高了特征的区分能力。
3)特别地,提出的槽注意采用KNN滤波来采样特征空间中靠近槽的特征,从而为槽重构传递有用的信息。这在具有许多与目标对象相似的对象的复杂场景中稳定了槽细化过程,并有助于生成精确的重建图。换句话说,我们的槽注意力逐渐采样并使用与目标对象具有高相似性的输入特征,与同时使用所有输入特征的现有方法相反。
1.3 结构和贡献
- 结果
我们的方法在两个广泛使用的数据集上进行了评价:DAVIS-16 [20],FBMS [18]。这些数据集包含了各种各样的具有挑战性的场景,我们提出的模型在这三个方面都达到了最先进的性能。此外,通过各种消融研究,我们证明了我们的模型的有效性,并表明它可以实现鲁棒的视频对象分割,即使在挑战性的序列。
- 贡献
我们的主要贡献可以总结如下:
1)我们提出了一种新的无监督视频对象分割的引导槽注意机制,利用引导槽和KNN滤波来有效地分离复杂场景中的前景和背景空间结构信息。
2)该模型通过在目标帧中嵌入粗上下文信息来生成引导槽,并从目标帧和参考帧中提取和聚合全局和局部特征,从而在引导槽关注的情况下迭代地细化引导槽。
3)所提出的方法在两个流行的数据集上实现了最先进的性能,并通过各种消融研究证明了在具有挑战性的序列中的鲁棒性。
2.相关工作
2.1 无监督视频目标分割
MATNet [38]提出了一种用于无监督视频对象分割的运动注意过渡模型。该模型利用运动信息来指导分割过程,并可以分割对象。RTNet [22]提出了一种基于互逆变换的方法。该方法利用连续帧间对象外观和运动的一致性来分割视频中的对象。FSNet [7]介绍了一种用于视频对象分割的全双工策略。该方法使用双路径网络对视频中对象的外观和运动进行联合建模,并可以执行分割。AMC-Net [33]提出了一种共同注意门,可以调节外观和运动线索的影响。该模型学习同时关注运动和外观特征,以提高对象分割的准确性。TransportNet [35]利用传输理论对视频中对象外观和运动的一致性进行建模。HFAN [19]引入了一种分层特征对齐网络,该网络以多个尺度对齐来自不同帧的特征,以提高对象分割的准确性。在PMN [9]中,提出了一种原型记忆网络,该网络利用记忆模块来存储和检索用于分割的原型对象表示。TMO [3]将运动视为一种选项,并且可以在不依赖于运动信息的情况下执行分割。
2.2 slot attention mechanism
槽注意[14]是针对以对象为中心的学习任务而首次提出的。以对象为中心的学习是一种机器学习方法,其重点是对象及其在任务上下文中的关系。该方法已被应用于各种计算机视觉任务中,如目标检测、实例分割和场景理解。
例如,Li等人[11]提出了一种基于时隙注意力的分类器,用于透明和准确的分类,为由定制损失控制的每个类别提供直观的解释和正面或负面的解释。Zoran等人[41]提出了该模型,这是一种用于分割和表示3D视觉场景中的对象的完全无监督方法,通过使用循环时隙注意编码器和固定的帧无关先验,该模型的性能优于先前的工作。Zhou等人[39]提出了一种统一的视频全景分割端到端框架,通过使用视频全景检索器在称为全景槽的时空表示中对前景实例和背景语义进行编码。
3.方法
3.1整体结构
图2显示了拟议的全球服务协定的总体结构。该模型使用一个目标帧图像和NR参考帧图像作为输入。首先,时隙生成器从编码的目标帧图像特征生成前景和背景引导时隙。这些槽包含关于目标前景对象和背景的引导信息。此外,GSA使用局部提取器提取包括目标图像的详细信息的局部特征,并且使用全局提取器提取参考帧的全局特征。我们设计了一个聚合Transformer来整合这些信息,并有效地合并目标帧特征和参考帧特征。最后,该模型使用聚合特征和引导槽执行槽注意。在这个过程中,槽仔细调整的合并功能的基础上的KNN算法。因此,槽包含用于精确掩模生成的不同特征信息。注意,所提出的模型具有与RGB图像流相同的光流流,并且在图2中省略了该过程。从RGB图像和光流生成的特征在一个解码器中级联。
- 图2中的encoder结构如下:
1、初始化:
class GSANet(torch.nn.Module):
def __init__(self, num_slots=2):
super(GSANet, self).__init__()
self.cfg = None
self.rgb_encoder = SegformerForImageClassification.from_pretrained("nvidia/mit-b1")
self.flow_encoder = SegformerForImageClassification.from_pretrained("nvidia/mit-b1")
self.rgb_MFFM1 = Multi_Scale_Feature_Fusion_Module(512, 128)
self.rgb_MFFM2 = Multi_Scale_Feature_Fusion_Module(320, 128)
self.rgb_MFFM3 = Multi_Scale_Feature_Fusion_Module(128, 128)
self.rgb_MFFM4 = Multi_Scale_Feature_Fusion_Module(64, 128)
self.flow_MFFM1 = Multi_Scale_Feature_Fusion_Module(512, 128)
self.flow_MFFM2 = Multi_Scale_Feature_Fusion_Module(320, 128)
self.flow_MFFM3 = Multi_Scale_Feature_Fusion_Module(128, 128)
self.flow_MFFM4 = Multi_Scale_Feature_Fusion_Module(64, 128)
SegformerForImageClassification: 见SegFormer: Simple and Efficient Design for Semantic Segmentation with Transformers
2、不同尺度的特征融合
Multi_Scale_Feature_Fusion_Module 通过四个分支处理输入特征,每个分支具有不同的膨胀卷积层,这允许模型在不同的尺度上捕捉信息。然后,这些特征通过加权和ReLU激活函数进行融合,以产生一个综合了多尺度信息的特征表示。这种设计使得模型能够更全面地理解输入数据,从而在各种视觉任务中取得更好的性能。
class Multi_Scale_Feature_Fusion_Module(nn.Module):
def __init__(self, in_channel, out_channel):
super(Multi_Scale_Feature_Fusion_Module, self).__init__()
self.relu = nn.ReLU(True)
self.branch0 = nn.Sequential(
BasicConv2d(in_channel, out_channel, 1)
)
self.branch1 = nn.Sequential(
BasicConv2d(out_channel, out_channel, kernel_size=3, stride=1, padding=6, dilation=6)
)
self.branch2 = nn.Sequential(
BasicConv2d(out_channel, out_channel, kernel_size=3, stride=1, padding=12, dilation=12)
)
self.branch3 = nn.Sequential(
BasicConv2d(out_channel, out_channel, kernel_size=3, stride=1, padding=18, dilation=18)
)
self.in_conv = nn.Conv2d(in_channel, out_channel, 1)
def forward(self, x):
x0 = self.branch0(x)
sq_x = self.in_conv(x)
x1 = self.branch1(sq_x)
x2 = self.branch2(sq_x + x1)
x3 = self.branch3(sq_x + x2)
x = self.relu(x0 + x3)
return x
def initialize(self):
weight_init(self)
3、encoder流程
def forward(self, rgb, flow, rgb_ref, flow_ref):
shape = rgb.size()[2:]
rgb_ref, flow_ref = self.get_ref_feature(rgb_ref, flow_ref)
rgb_features = self.rgb_encoder(rgb, output_hidden_states=True).hidden_states
x4_r, x3_r, x2_r, x1_r = rgb_features[3], rgb_features[2], rgb_features[1], rgb_features[0]
flow_features = self.flow_encoder(flow, output_hidden_states=True).hidden_states
x4_f, x3_f, x2_f, x1_f = flow_features[3], flow_features[2], flow_features[1], flow_features[0]
x1_r, x2_r, x3_r, x4_r = self.rgb_MFFM4(x1_r), self.rgb_MFFM3(x2_r), self.rgb_MFFM2(x3_r), self.rgb_MFFM1(x4_r)
x1_f, x2_f, x3_f, x4_f = self.flow_MFFM4(x1_f), self.flow_MFFM3(x2_f), self.flow_MFFM2(x3_f), self.flow_MFFM1(x4_f)
3.2 槽生成器
(a)时隙生成器、(B)局部提取器和(c)全局提取器的结构。槽生成器创建存储用于掩码生成的重要特征的引导槽。局部提取器利用K-means聚类算法在特征级生成聚类掩码,并提取每个区域的局部特征。全局提取器通过逐通道softmax操作为场景生成软对象区域,并使用这些区域提取全局特征。
1、GSANet流程
#初始化
self.rgb_SG = Slot_Generator(128, 128, num_slots)
self.flow_SG = Slot_Generator(128, 128, num_slots)
..............
#流程
sqz_x3_r, rgb_agg_pt, rgb_ref_pt_list, rgb_slots, rgb_slot_mask = self.rgb_SG(x3_r, rgb_ref)
sqz_x3_f, flow_agg_pt, flow_ref_pt_list, flow_slots, flow_slot_mask = self.flow_SG(x3_f, flow_ref)
2、Slot Generator
- 使用一维卷积,将输入特征层有B,C,H,W变为B,2,H,W.这里的2是论文中提到的num_slots,分别表示前景和背景槽
- 对target进行聚类(不是很懂里面的数学原理??后续把2024cvpr的视频目标检测论文看完会进一步整理)
- 对全局进行聚类
class Slot_Generator(nn.Module):
#这里的num_slots为2,分别表示前景槽和背景槽
def __init__(self, in_channels, out_channels, num_slots):
super(Slot_Generator, self).__init__()
self.sqz = nn.Conv2d(in_channels, out_channels, 1)
self.slot_enc = nn.Conv2d(in_channels, num_slots, 1)
self.FAT = Feature_Aggregation_Transformer(out_channels)
def forward(self, target, ref):
sqz_target = self.sqz(target) # B, C, H, W
slot_target = self.slot_enc(target) # B, 2, H, W
target_pt = get_kmenas_prototypes(sqz_target, 64)
slot_pt, slot_mask = get_global_prototypes(sqz_target, slot_target, mode="softmax", dim=1) # B, 2, C
ref_pt_list = []
for i in range(len(ref)):
sqz_ref = self.sqz(ref[i])
ref_pt, _ = get_global_prototypes(sqz_ref, sqz_ref, mode="softmax", dim=2) # B, N, C
ref_pt_list.append(ref_pt) # B, N, C
ref_pt_block = torch.stack(ref_pt_list, dim=1) # b, cn, cl, c
ref_pt_block = rearrange(ref_pt_block, 'b cn cl c -> b c cn cl')
target_pt = rearrange(target_pt, 'b n c -> b c n') # B, C, N
agg_pt = self.FAT(target_pt, ref_pt_block) # B, C, N
agg_pt = rearrange(agg_pt, 'b c n -> b n c') # B, N, C
ref_pt_list.append(agg_pt)
return sqz_target, agg_pt, ref_pt_list, slot_pt, slot_mask
def initialize(self):
weight_init(self)
3、Slot Generator中引用的模块
def get_kmenas_prototypes(x, k):
# 从x中裁剪k大小的mask
mask = get_feature_clustering_masks(x, k)
#将mask进行克隆和提取
mask = mask.clone().detach()
#展平h、w维
probs = rearrange(mask, 'b c h w -> b c (h w)')
x = rearrange(x, 'b c h w -> b c (h w)')
#将mask和x进行矩阵相乘(ps,这个有点像attention机制,通过相乘获取x与mask相似的程度)
pb = torch.bmm(probs, x.transpose(1, 2))
return pb
def get_global_prototypes(target, mask, mode="softmax", dim=2):
H, W = target.size(2), target.size(3)
probs = rearrange(mask, 'b c h w -> b c (h w)')
if mode == "softmax":
ss_map = F.softmax(probs, dim=dim)
elif mode == "sigmoid":
ss_map = torch.sigmoid(probs)
x = rearrange(target, 'b c h w -> b c (h w)')
pb = torch.bmm(ss_map, x.transpose(1, 2))
vis_mask = rearrange(ss_map, 'b c (h w) -> b c h w', h=H, w=W)
return pb, vis_mask
3.3 全局和局部提取器
3.4 FAT:Feature Aggregation Transformer
图4.FAT和GSA的结构。FAT使用集中池从参考帧的全局特征生成帧内特征,并使用Transformer块生成全局到局部特征。GSA使用引导槽提供用于前景和背景区分的初始信息,使用KNN算法从聚集的特征中选择与每个槽最近的特征,并应用迭代注意机制来更新槽。FAT和GSA的目的是生成有用的特征,用于目标对象掩模重建,并提高时隙注意中的前景和背景区分度。
3.5 Guided Slot Attention
3.6 Slot Decoder
3.7 Objective Function
我们使用IOU损失和加权二进制交叉熵损失的总和作为目标函数,这通常用于显著对象检测任务[29,40]。该损失函数有助于将更多权重分配给硬情况像素。总损失函数表示如下:
总结
提出了一种新的无监督VOS引导时隙注意机制.该模型通过在目标帧中嵌入粗略的上下文信息来生成引导槽,从而有效地区分复杂场景中的前景和背景。我们设计FAT是为了创建可有效聚合局部和全局特征的特征。该算法利用KNN滤波对靠近狭缝的特征进行采样,从而提高了分割的准确性。试验结果表明,与现有经典算法相比,该方法具有较好的鲁棒性。