2019发表于CVPR的一篇显著目标检测论文
论文原文
代码地址
显著性检测是计算机视觉的基本挑战之一。如何提取有效的特征是显著性检测的一个关键点。最近的方法主要是不加区分地采用融合多尺度卷积特征。然而,并非所有的特征都对显著性检测有用,有些甚至会造成干扰。为了解决这个问题,我们提出了金字塔特征注意力网络,以关注有效的高级背景特征和低级空间结构特征。首先,我们设计了上下文感知的金字塔特征提取(CPFE)模块,用于多尺度高层特征图,以捕获丰富的上下文特征。其次,我们在CPFE特征图后采用通道注意力(CA),在低层次特征图后采用空间注意力(SA),然后将CA和SA的输出融合在一起。最后,我们提出了一个边缘保留损失,以指导网络在边界定位中学习更多的细节信息。在五个基准数据集上进行的广泛评估表明,所提出的方法在不同的评估指标下优于最先进的方法。
类似文献综述,不多赘述。
由于注意机制具有很强的特征选择能力,因此它是对显著性检测的最佳选择。在集成卷积特征的同时,大多数现有的方法对多层次特征的处理都没有区别。有些方法采用了一些有效的策略,如门函数[42]和渐进注意[45],但这些方法选择一定方向选择特征,忽略了高级特征和低级特征之间的差异。与之不同的是,对于高级特征,我们采用了上下文感知的金字塔特征提取(CPFE)模块和通道注意模块来获取丰富的上下文信息。在CPFE模块中,我们在VGG网络的三个高级块侧采用多尺度空洞卷积,然后通过通道注意机制对突出物体显示出高响应的通道分配较大的权重。对于低级特征,存在一些背景区域,分散了显著性地图的生成。空间注意机制根据高级特征过滤掉一些背景细节,更多地关注前景区域,有助于生成显著性预测的有效特征。
我们将VGG-16中的conv 3-3、conv 4-3和conv 5-3作为基本的高级特征。为了使最终提取的高级特征包含尺度和形状不变性特征,我们采用不同扩张率的空洞卷积,设置为3、5和7以捕获多接受域上下文信息。然后结合不同卷积层的特征映射和1×1维降维特征。在此之后,我们得到了三个具有上下文感知信息的不同尺度特征,我们将两个较小的特征上采样到最大的一个。最后,我们通过跨通道连接将它们合并,作为上下文感知金字塔特征提取模块的输出。
根据不同层次特征的特征,对高级特征采用通道注意,对低层次特征采用空间注意来选择有效的特征。此外,我们不对高级特征使用空间注意,因为高级特征包含高抽象语义[16,45],因此不需要过滤空间信息。然而,我们没有对低级特征使用通道级注意,因为在低级特征的不同通道之间几乎没有语义区别。
在上下文感知金字塔特征提取后,我们将加权多尺度多接受域高级特征的[16,3]模块添加到通道注意(CA)中。CA将为对突出物体显示高响应的通道分配更大的权重。
我们将高级特征fh∈RW×H×C展开为fh= [ fh1,fh2 ,…,fhC ],其中fhi∈RW×H是fh的第i个切片,C是总通道数。首先,我们将平均池化应用于每个fhi,以获得一个通道特征向量vh。之后,使用两个连续的完全连接(FC)层来完全捕获通道级依赖关系(见上图)。[16]为了限制模型的复杂性和帮助泛化,我们通过在非线性周围形成一个具有两个FC层的瓶颈来对通道级特征向量进行编码。然后,通过 sigmoid运算,对映射到[0,1]的编码通道特征向量进行归一化处理。
其中W为通道级注意块中的参数,σ1为sigmoid运算,fc为FC层,δ为ReLU函数。通过对上下文感知的金字塔特征与CA进行加权,得到了块的最终输出feh。
代码如下:
class ChannelwiseAttention(nn.Layer):
def __init__(self, in_channels):
super(ChannelwiseAttention, self).__init__()
self.in_channels = in_channels
self.linear_1 = nn.Linear(self.in_channels, self.in_channels // 4)
self.linear_2 = nn.Linear(self.in_channels // 4, self.in_channels)
def forward(self, input_):
n_b, n_c, h, w = input_.shape
feats = F.adaptive_avg_pool2d(input_, (1, 1)).reshape((n_b, n_c))
feats = F.relu(self.linear_1(feats))
feats = F.sigmoid(self.linear_2(feats))
# Activity regularizer
ca_act_reg = paddle.mean(feats)
feats = feats.reshape((n_b, n_c, 1, 1))
feats = feats.expand_as(input_).clone()
return feats, ca_act_reg
在显著性检测中,我们希望获得显著性物体和背景之间的详细边界,而没有其他会分散人类注意力的纹理。因此,我们没有平均考虑所有的空间位置,而是采用空间注意来更多地关注前景区域,这有助于生成预测显著性的有效特征。
我们将低级特征表示为fl∈RW×H×C。空间位置的集合用R = {(x,y)|x = 1,…,W;y = 1,…,H}表示,其中j =(x,y)为低层次特征的空间坐标。为了增加感受野和获取全局信息而不增加参数,类似于[26],我们采用两个卷积层,一个核为1×k,另一个核为k×1,对于高级特征捕获空间问题(见上图)。然后,利用sigmoid运算,对编码的空间特征图映射到[0,1]进行归一化处理。
其中W为空间注意块中的参数,σ2为sigmoid操作,conv1和conv2为1×k×C和k×1×1卷积,我们在实验中设置k=9。用SA将fl加权,得到该块的最终输出fel
代码如下:
class SpatialAttention(nn.Layer):
def __init__(self, in_channels, kernel_size=9):
super(SpatialAttention, self).__init__()
self.kernel_size = kernel_size
self.in_channels = in_channels
pad = (self.kernel_size - 1) // 2 # Padding on one side for stride 1
self.grp1_conv1k = nn.Conv2D(self.in_channels, self.in_channels // 2, (1, self.kernel_size), padding=(0, pad))
self.grp1_bn1 = nn.BatchNorm2D(self.in_channels // 2)
self.grp1_convk1 = nn.Conv2D(self.in_channels // 2, 1, (self.kernel_size, 1), padding=(pad, 0))
self.grp1_bn2 = nn.BatchNorm2D(1)
self.grp2_convk1 = nn.Conv2D(self.in_channels, self.in_channels // 2, (self.kernel_size, 1), padding=(pad, 0))
self.grp2_bn1 = nn.BatchNorm2D(self.in_channels // 2)
self.grp2_conv1k = nn.Conv2D(self.in_channels // 2, 1, (1, self.kernel_size), padding=(0, pad))
self.grp2_bn2 = nn.BatchNorm2D(1)
def forward(self, input_):
# Generate Group 1 Features
grp1_feats = self.grp1_conv1k(input_)
grp1_feats = F.relu(self.grp1_bn1(grp1_feats))
grp1_feats = self.grp1_convk1(grp1_feats)
grp1_feats = F.relu(self.grp1_bn2(grp1_feats))
# Generate Group 2 features
grp2_feats = self.grp2_convk1(input_)
grp2_feats = F.relu(self.grp2_bn1(grp2_feats))
grp2_feats = self.grp2_conv1k(grp2_feats)
grp2_feats = F.relu(self.grp2_bn2(grp2_feats))
added_feats = F.sigmoid(paddle.add(grp1_feats, grp2_feats))
added_feats = added_feats.expand_as(input_).clone()
return added_feats
在显著目标检测中,我们总是使用最终显著图与真实图之间的交叉熵损失。损失函数的定义为:
我们利用拉普拉斯算子[12]来得到网络输出的地面真实值边界和网络输出的显著性图,然后利用交叉熵损失来监督显著目标边界的生成。
拉普拉斯算子是n维欧几里得空间中的一个二阶微分算子,定义为梯度的散度(∆f)。因为二阶导数可以用来检测边缘,所以我们使用拉普拉斯算子来得到突出的对象边界。二维中的拉普拉斯算符由等式(8)给出,其中x和y是xy平面的标准笛卡尔坐标。事实上,由于拉普拉斯算子使用了图像的梯度,所以它在内部调用卷积操作来执行其计算。然后我们使用绝对操作,然后是tanh激活(9).将该值映射到[0,1]。最后,我们利用交叉熵损失来监督显著目标边界的生成等式 (10).总损失函数是它们的加权和:
通过实验得出α的最佳取值为0.7
以下是我自己在paddlepaddle中跑出来的指标(仅供参考):
数据集 | MAE | Fm | E-measure | S-measure | Wgt-F |
---|---|---|---|---|---|
ECSSD | 0.0511 | 0.9022 | 0.9267 | 0.9019 | 0.8572 |
PASCALS | 0.0750 | 0.8517 | 0.8686 | 0.8530 | 0.7902 |
HKU-IS | 0.0399 | 0.8945 | 0.9443 | 0.9054 | 0.8547 |
DUTS-TE | 0.0481 | 0.8225 | 0.8726 | 0.8666 | 0.7568 |
DUT-OMRON | 0.0668 | 0.7510 | 0.8340 | 0.8122 | 0.6656 |