论文解读:Foreground-Aware Relation Network for Geospatial Object Segmentation in High Spatial Resolution

发表时间:2020
项目地址:https://github.com/Z-Zheng/FarSeg pytorch实现,依赖simplecv库(resnet、fpn支持)
论文地址:https://openaccess.thecvf.com/content_CVPR_2020/papers/Zheng_Foreground-Aware_Relation_Network_for_Geospatial_Object_Segmentation_in_High_Spatial_CVPR_2020_paper.pdf
在这里插入图片描述

在高空间分辨率(HSR)遥感图像中,总是面临着较大尺度的背景变化、较大的类内方差和前景-背景不平衡。然而,一般的语义分割方法主要关注自然场景中的尺度变化,而没有充分考虑到大面积地球观测场景中经常出现的另外两个问题(类内方差和前景背景不平衡)。本文针对前景建模的不足,并从基于关系和基于优化的前景建模的角度提出了前景感知关系网络(FarSeg),以缓解上述两个问题。从关系的角度来看,FarSeg通过学习前景-场景关系所关联的前景相关上下文,增强了对前景特征的识别能力。同时,从优化的角度出发,提出了一种前景感知优化方法,重点研究了平衡优化训练过程中的前景背景实例和硬背景实例。利用大规模数据集获得的实验结果表明,该方法优于现有的通用语义分割方法,并在速度和准确性之间实现了更好的权衡。

基本总结

  • 1、整体看来,FarSeg将目标检测中的类似PAFPN的结构迁移到了语义分割中,并对网络结构进行了拆解,赋予了PAFPN中特征聚合操作不同的含义(Foreground-Scene Relation提取)
  • 2、FarSeg将语义分割的研究对象转移到HSR遥感影像阵地,提出前景背景不平衡的现状,对Focal loss进行了变体实现(Foreground-Aware Optimization)
  • 3、在最终cout前对特征取平均值的操作与一般网络不同,但文章未给出说法;多尺度特征平均值、concat效果应该都是差不多的
  • 4、从文章实验效果上看,其IoU比最强的PSPNet高3%,细到类别主要是在HC类别项较为强劲(其他模型均无法有效识别HC这个类别)。

特性分析

从上图中可以看到FarSeg在这Bridge、HC、SP这三个类别上要稳定的强很多,尤其是在HC类别上。故此对iSAID数据集进行初分析,可以发现Bridge、HC、SP都属于面积不大,而在像素级的色彩上容易混淆的类别[Bridge与一般道路相近,HC与飞机相近,SP与港口水体相近],使用Foreground-Scene Relation或可提升对易混淆目标的识别。
(图片参考自https://blog.csdn.net/carry_hjr/article/details/115388749)

且HC在实例数量上还属于小类别,这或许是Foreground-Aware Optimization的功劳(类别不平衡优化)

1、背景

1.1 技术背景

自然场景相比,HSR遥感图像的地理空间目标分割更具挑战性。至少有三个原因

    1. 物体在HSR遥感图像[14,42]中总是有更大尺度的变化。这就导致了多尺度问题,使得定位和识别物体很困难。
    1. HSR遥感图像[36,13]的背景要复杂得多,由于类内方差较大,会导致严重的误报。
    1. 前景中目标出现的比例远比背景中小的多,导致严重的类别不平衡。

1.2 研究方向

现有的技术中,以自然图像为主,故主要针对多尺度和感受野进行建模,忽略了HSR遥感影像中前背景差异问题。
FarSeg探讨了明确的前景建模的两个角度:基于关系和基于优化的前景建模,并进一步提出了两个模块:foreground-scene relation module 和 foreground-aware optimization。

  • foreground-scene relation module: 前景-场景关系模块学习场景与前景之间的共生关系,将与前景相关的上下文关联起来,从而增强前景特征,从而减少误报。
  • foreground-aware optimization: 前景感知优化通过抑制大量简单的背景例子,将模型集中在前景上,以缓解前景-背景不平衡问题。

1.3 研究成果

  • 提出了一种用于HSR遥感图像地理空间对象分割的前景感知关系网络(FarSeg)。
  • 为了继承多尺度上下文建模和学习地理空间场景表示,FarSeg构建了基于特征金字塔网络(FPN)的前景分支,并在共享主干网络上建立场景嵌入分支,即多分支编码器。
  • 为了抑制误检,F-S关系模块利用了地理空间场景与地理空间对象之间的共生关系,将与前景相关的上下文关联起来,增强了对前景特征的识别能力。同时,没有任何贡献的背景被这种共生关系所抑制,从而抑制了误检
  • 为了缓解前景-背景不平衡,提出了F-A优化方法,将网络逐步集中在硬样本上,从而降低大量背景样本的梯度贡献,用于前景-背景平衡训练

2、方法

所提出的FarSeg由特征金字塔网络(FPN)、前景场景(F-S)关系模块、轻量级解码器和前景感知(F-A)优化组成。FPN负责多尺度的目标分割。在F-S关系模块中,我们首先将误检问题表述为前景中缺乏识别信息的问题,然后引入潜在场景语义和F-S关系来提高前景特征的识别能力。轻量级解码器的设计旨在恢复语义特征的空间分辨率。为了使网络在训练过程中关注前景,提出了F-A优化方法来缓解前景-背景不平衡问题。

模型主体实现代码如下:

@registry.MODEL.register('FarSeg')
class FarSeg(CVModule):
    def __init__(self, config):
        super(FarSeg, self).__init__(config)
        self.register_buffer('buffer_step', torch.zeros((), dtype=torch.float32))

        self.en = resnet.ResNetEncoder(self.config.resnet_encoder)
        self.fpn = fpn.FPN(**self.config.fpn)
        self.decoder = AssymetricDecoder(**self.config.decoder)
        self.cls_pred_conv = nn.Conv2d(self.config.decoder.out_channels, self.config.num_classes, 1)
        self.upsample4x_op = nn.UpsamplingBilinear2d(scale_factor=4)
        self.device = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')
        if 'scene_relation' in self.config:
            print('scene_relation: on')
            self.gap = scm.GlobalAvgPool2D()
            self.sr = SceneRelation(**self.config.scene_relation)

        if 'softmax_focalloss' in self.config:
            print('loss type: softmax_focalloss')

        if 'cosineannealing_softmax_focalloss' in self.config:
            print('loss type: cosineannealing_softmax_focalloss')

        if 'annealing_softmax_focalloss' in self.config:
            print('loss type: {}'.format(self.config.annealing_softmax_focalloss.annealing_type))

    def forward(self, x, y=None):
        feat_list = self.en(x)
        fpn_feat_list = self.fpn(feat_list)
        if 'scene_relation' in self.config:
            c5 = feat_list[-1]
            c6 = self.gap(c5)
            refined_fpn_feat_list = self.sr(c6, fpn_feat_list)
        else:
            refined_fpn_feat_list = fpn_feat_list

        final_feat = self.decoder(refined_fpn_feat_list)
        cls_pred = self.cls_pred_conv(final_feat)
        cls_pred = self.upsample4x_op(cls_pred)

        if self.training:
            cls_true = y['cls']
            loss_dict = dict()
            self.buffer_step += 1
            cls_loss_v = self.config.loss.cls_weight * self.cls_loss(cls_pred, cls_true)
            loss_dict['cls_loss'] = cls_loss_v

            mem = torch.cuda.max_memory_allocated() // 1024 // 1024
            loss_dict['mem'] = torch.from_numpy(np.array([mem], dtype=np.float32)).to(self.device)
            return loss_dict

        return cls_pred.softmax(dim=1)

2.1 Multi-Branch Encoder

多分支编码器由前景分支和场景嵌入分支组成。如图2 (a)所示,这些分支都建立在一个主干网络之上。在该方法中,选择ResNets [21]作为基本特征提取的主干网络。 C i ∣ i = 2 , 3 , 4 , 5 {C_i |i = 2,3,4,5} Cii=2,3,4,5表示从ResNets中提取的特征映射集,其中特征映射 C i C_i Ci相对于输入图像具有 2 i 2^i 2i像素的输出步幅。与最初的FPN类似,自上而下的路径和横向连接被用于生成具有相同channel的金字塔特征图 P i ∣ i = 2 , 3 , 4 , 5 {P_i |i = 2,3,4,5} Pii=2,3,4,5

以上过程可以公式化为以下形式,其中,ζ表示由conv1×1实现的横向连接,Γ表示尺度因子为2的最近邻上采样。通过这种上向下路径和横向连接,可以利用浅层的高分辨率细节和深层的强语义来增强特征图,有助于恢复对象的细节和多尺度上下文建模。除了金字塔形特征图vi外,在C5上还附加了一个额外的分支,通过全局上下文聚合生成一个地理空间场景特征C6。为简单起见,我们使用全局平均池作为聚合函数。C6用于模拟地理空间场景与前景之间的关系,如下节所示。

其对应代码forword实现如下:

class FarSeg(CVModule):
    def __init__(self, config):
        super(FarSeg, self).__init__(config)
        ''' 省略大部分不相干代码'''
        self.register_buffer('buffer_step', torch.zeros((), dtype=torch.float32))
        self.en = resnet.ResNetEncoder(self.config.resnet_encoder)
        self.fpn = fpn.FPN(**self.config.fpn)
    def forward(self, x, y=None):
        feat_list = self.en(x) #由resnet50返回特征list【多尺度特征】
        fpn_feat_list = self.fpn(feat_list)#对特征list进行fpn操作

2.2 Foreground-Scene Relation Module

HSR遥感图像的背景要复杂得多。这意味着背景中存在较大的类内方差,导致误警问题。为了解决这一问题,提出了前景场景(F-S)关系模块,通过关联与地理空间场景相关的上下文来提高前景特征的识别能力。其主要思想如图3所示。F-S关系模块首先明确地建模前景与地理空间场景之间的关系,并利用潜在的地理空间场景将前景与相关上下文关联起来。然后利用该关系对输入特征图进行增强,以增加前景特征与背景特征之间的视差,从而提高前景特征的分辨能力。

如图2 (b)所示,对于金字塔形特征图vi,F-S关系模块将生成一个新的特征图zi。通过对vi进行重新编码,然后使用关系映射ri对其进行重新加权,得到了特征映射zi。关系映射ri是地理空间场景表示与前景表示之间的相似性矩阵。为了将这两个特征表示对齐成一个共享的流形 R d u R^{du} Rdu,需要分别学习地理空间场景和前景学习两个投影函数。 v i vi vi是由尺度感知投影函数 ψ θ i ( ⋅ ): R d × H × W → R d u × H × W ψθi(·):R^{d×H×W}→R^{d_u×H×W} ψθi):Rd×H×WRdu×H×W(conv1x1的CBR模块) 转换的特征图vi

其对应代码forword实现如下,需要注意的是SceneRelation1有两个输入

class FarSeg(CVModule):
    def __init__(self, config):
        super(FarSeg, self).__init__(config)
        ''' 省略大部分不相干代码'''
        if 'scene_relation' in self.config:
            print('scene_relation: on')
            self.gap = scm.GlobalAvgPool2D()
            self.sr = SceneRelation(**self.config.scene_relation)

    def forward(self, x, y=None):
        feat_list = self.en(x)
        fpn_feat_list = self.fpn(feat_list)
        if 'scene_relation' in self.config:
            c5 = feat_list[-1]
            c6 = self.gap(c5)
            refined_fpn_feat_list = self.sr(c6, fpn_feat_list) #这里实现前景关联
        else:
            refined_fpn_feat_list = fpn_feat_list

其中SceneRelation的具体实现代码如下,先由content_encoders对fpn的输出进行第一次编码得到content_feats(对输入的多尺度特征进行编码),然后由scene_encoder进行第二次编码得到 relations (将c6特征与编码后的特征做点乘),再由feature_reencoders进行第三个编码得到p_feats (对输入的多尺度特征进行编码),最后将relations与p_feats进行点乘。

class SceneRelation(nn.Module):
    def __init__(self,
                 in_channels,
                 channel_list,
                 out_channels,
                 scale_aware_proj=True):
        super(SceneRelation, self).__init__()
        self.scale_aware_proj = scale_aware_proj

        if scale_aware_proj:
            self.scene_encoder = nn.ModuleList(
                [nn.Sequential(
                    nn.Conv2d(in_channels, out_channels, 1),
                    nn.ReLU(True),
                    nn.Conv2d(out_channels, out_channels, 1),
                ) for _ in range(len(channel_list))]
            )
        else:
            # 2mlp
            self.scene_encoder = nn.Sequential(
                nn.Conv2d(in_channels, out_channels, 1),
                nn.ReLU(True),
                nn.Conv2d(out_channels, out_channels, 1),
            )
        self.content_encoders = nn.ModuleList()
        self.feature_reencoders = nn.ModuleList()
        for c in channel_list:
            self.content_encoders.append(
                nn.Sequential(
                    nn.Conv2d(c, out_channels, 1),
                    nn.BatchNorm2d(out_channels),
                    nn.ReLU(True)
                )
            )
            self.feature_reencoders.append(
                nn.Sequential(
                    nn.Conv2d(c, out_channels, 1),
                    nn.BatchNorm2d(out_channels),
                    nn.ReLU(True)
                )
            )

        self.normalizer = nn.Sigmoid()

    def forward(self, scene_feature, features: list):
        content_feats = [c_en(p_feat) for c_en, p_feat in zip(self.content_encoders, features)]
        if self.scale_aware_proj:
            scene_feats = [op(scene_feature) for op in self.scene_encoder]
            relations = [self.normalizer((sf * cf).sum(dim=1, keepdim=True)) for sf, cf in
                         zip(scene_feats, content_feats)]
        else:
            scene_feat = self.scene_encoder(scene_feature)
            relations = [self.normalizer((scene_feat * cf).sum(dim=1, keepdim=True)) for cf in content_feats]

        p_feats = [op(p_feat) for op, p_feat in zip(self.feature_reencoders, features)]

        refined_feats = [r * p for r, p in zip(relations, p_feats)]

        return 

2.3. Light-weight decoder

轻量级解码器以轻量级方式从F-S关系模块中恢复关系增强语义特征映射的空间分辨率。轻量级解码器的详细体系结构如图5所示。

Decoder在做class预测前的处理代码如下,其主要就是对每一个尺度的输出进行编码并上采样到固定尺寸,然后用4个尺度的平均值代替原来的值。

class AssymetricDecoder(nn.Module):
    def __init__(self,
                 in_channels,
                 out_channels,
                 in_feat_output_strides=(4, 8, 16, 32),
                 out_feat_output_stride=4,
                 norm_fn=nn.BatchNorm2d,
                 num_groups_gn=None):
        super(AssymetricDecoder, self).__init__()
        if norm_fn == nn.BatchNorm2d:
            norm_fn_args = dict(num_features=out_channels)
        elif norm_fn == nn.GroupNorm:
            if num_groups_gn is None:
                raise ValueError('When norm_fn is nn.GroupNorm, num_groups_gn is needed.')
            norm_fn_args = dict(num_groups=num_groups_gn, num_channels=out_channels)
        else:
            raise ValueError('Type of {} is not support.'.format(type(norm_fn)))
        self.blocks = nn.ModuleList()
        for in_feat_os in in_feat_output_strides:
            num_upsample = int(math.log2(int(in_feat_os))) - int(math.log2(int(out_feat_output_stride)))

            num_layers = num_upsample if num_upsample != 0 else 1

            self.blocks.append(nn.Sequential(*[
                nn.Sequential(
                    nn.Conv2d(in_channels if idx == 0 else out_channels, out_channels, 3, 1, 1, bias=False),
                    norm_fn(**norm_fn_args) if norm_fn is not None else nn.Identity(),
                    nn.ReLU(inplace=True),
                    nn.UpsamplingBilinear2d(scale_factor=2) if num_upsample != 0 else nn.Identity(),
                )
                for idx in range(num_layers)]))

    def forward(self, feat_list: list):
        inner_feat_list = []
        for idx, block in enumerate(self.blocks):
            decoder_feat = block(feat_list[idx])
            inner_feat_list.append(decoder_feat)

        out_feat = sum(inner_feat_list) / 4.
        return out_feat

2.4 Foreground-Aware Optimization

前景-背景不平衡问题通常会导致背景例子在训练过程中主导梯度。然而,在训练后期,只有困难背景例子对于训练后期的优化是有价值的,因为困难背景的例子比简单的背景例子要少得多。在此基础上,提出了前景感知优化,使网络关注前景和困难背景进行平衡优化。预先感知优化包括三个步骤:困难背景示例估计、动态加权和反向传播,如图2 (d).所示

其具体实现代码如下:

def annealing_softmax_focalloss(y_pred, y_true, t, t_max, ignore_index=255, gamma=2.0,
                                annealing_function=cosine_annealing):
    losses = F.cross_entropy(y_pred, y_true, ignore_index=ignore_index, reduction='none')
    with torch.no_grad():
        p = y_pred.softmax(dim=1)
        modulating_factor = (1 - p).pow(gamma)
        valid_mask = ~ y_true.eq(ignore_index)
        masked_y_true = torch.where(valid_mask, y_true, torch.zeros_like(y_true))
        modulating_factor = torch.gather(modulating_factor, dim=1, index=masked_y_true.unsqueeze(dim=1)).squeeze_(dim=1)
        normalizer = losses.sum() / (losses * modulating_factor).sum()
        scales = modulating_factor * normalizer
    if t > t_max:
        scale = scales
    else:
        scale = annealing_function(1, scales, t, t_max)
    losses = (losses * scale).sum() / (valid_mask.sum() + p.size(0))
    return losses

hard example estimation

用于获得反映实例的困难程度的权重,以调整像素级损失的分布。这个像素更难了,这就意味着它的重量更大了。受focal loss[30]的激励,采用 ( 1 − p ) γ (1−p)^γ (1p)γ作为权重来估计困难的例子,其中p∈[0,1]是网络的预测概率,γ是聚焦因子。该公式用于目标检测,但对于前景-背景不平衡的像素级任务,我们只期望调整损失分布而不改变梯度的总和,以避免梯度消失。因此对其进行泛化,引入一个标准化常数Z来调整每一个像素的loss,因此,对于每个像素的损失,它的权重为 1 Z ( 1 − p i ) γ \frac{1}{Z}(1−p_i)^γ Z1(1pi)γ

dynamic weighting

困难估计依赖于模型的判别。然而,在训练的初始阶段,模型判别是不稳定的,这使得难例估计不自信。如果使用这种不自信的困难样本权值,模型训练将是不稳定的,影响收敛性能。为了解决这一问题,我们提出了一种基于退火函数的动态加权策略。我们设计了三个退火函数作为候选项,如表1所示。给定交叉熵损失l(pi,yi),动态加权损失表示为:

其中ζ(·)的具体形式有以下三种。这样,随着困难样本的置信度pi的增加,损失分布的焦点可以逐渐转移到困难样本上。 实际上ζ是不断下降的(初始值接近1),困难样本pi是不断增加的,也就是一开始困难样本的的loss权重接近1,然后随着ζ的减小和pi的增大,困难样本的权重逐步增大(使易样本的权重逐步减少)

3、实验

3.1 实验设置

  • 数据集: iSAID数据集由2,806张HSR的遥感图像组成。这些图像来自多个分辨率的多个传感器和平台。原始图像的大小范围从800×800像素到4000×13000像素。iSAID数据集提供了对象15个类别的655,451个实例注释,这是HSR遥感图像分割的最大数据集。预定义的训练集包含1411张图像,而验证集包含458张图像,测试集包含937张图像。在这项工作中,我们只使用语义掩码注释来进行对象分割。我们使用预定义的训练集来训练模型并对验证集进行评估。因为该测试集不可用。

  • 实验参数: 使用ResNet50做backbone,其中FPN的channel为256;Foreground-Aware Optimization中focal loss中的系数γ为2 , 调度器采用poly模式,annealing_step为10k,decay_factor|power为0.9; 总共进行60k次迭代 ; SGD weight decay 为0.0001 , momentum 为 0.9 ,batchsize为8(2个GPU,每个为4); 数据增强 镜像和旋转,crop size为896896,stride为512512

  • 评价指标: IoU

3.2 基本对比

比较了FarSeg与几种基于cnn的方法,从经典的到最先进的,包括U-Net[38],FCN-8[33],DenseASPP[44],Deeplabv3[6],Semantic FPN[32],Deeplabv 3+[8],RefineNet[29],PSPNet[48]。表2中列出的定量结果表明,FarSeg在HSR场景中优于其他方法。

图6显示了速度和精度之间的权衡关系。这表明,FarSeg在速度和精度之间实现了更好的权衡,这受益于轻量级和有效的模块设计。

4、消融实验

4.1 Foreground-Scene Relation Module

The effect of F-S relation module 表3 (b)和©显示了基于基线方法添加F-S关系的消融结果(表3 (a))。F-S关系模块(w/o和w/scale-aware projection)分别增加了为1.11%和1.18%。∆#参数表示由相应模块引入的额外参数。这表明F-S关系模块仅为2.89 M和1.12 M,其中参数的相对增量分别为∼10%和∼4%。这表明,性能的增益不仅来自于参数的增益,而且还来自于利用地理空间场景特征的F-S关系设计,将相关的背景特征关联起来,以增强前景特征。

Scale-aware projection for scene embedding 投影函数η用于F-S关系模块中的地理空间场景表示。我们探讨了每个金字塔层是否需要标度感知投影函数η。表3 (b)/©和(e)/(f)的结果表明,尺度感知投影函数表现更好。通过F-A优化,来自尺度感知投影的mIoU增益更大。说明地理空间场景表示与尺度和前景有关。

Visual interpretation for F-S relation module F-S关系模块结合地球科学知识,具有良好的视觉可解释性。图7显示了在不同的金字塔层次上的F-S关系的可视化。每个像素表示潜在的地理空间场景与像素自身之间的关系强度。有三个经典的场景:机场、港口和停车场。我们可以发现,不同的场景关注于不同的对象,这对这个场景是有区别的。例如,港口主要关注船舶和水,而机场主要关注飞机及其环境。同时,这些关系图再次说明了地理空间场景与尺度、前景和前景相对上下文相关。因为我们可以发现,在具有高空间分辨率的关系图(OS = 4)中,小物体是热的,如小型车辆和船舶。较大的对象在空间分辨率较低的关系图中温度较高。然而,上下文在关系图中并不是特定于空间分辨率的。它揭示了地理空间场景与特定尺度的前景和与尺度无关的背景有关。

4.2 Foreground-Aware Optimization

The effect of F-A optimization. 表3 (d)和(f)分别显示了基于基线法(表3 (a))和基于F-S关系和标度感知投影的基线法(表3 ©)的F-A优化的消融结果。F-A优化在mIoU中分别提高了2.2%和3.24%的性能,而没有任何额外的计算和内存占用。结果表明,F-A优化可以显著缓解HSR遥感图像目标分割的前景-背景不平衡问题。同时,这表明F-A优化与F-S关系模块具有很好的兼容性。

Normalization 表4 ©显示了对原始softmax focal loss加归一化的结果(表4 (b))。直接使用softmax focal loss,mIoU下降4.05%。而当添加归一化时,mIoU的性能显著提高了2.49%。与单纯的softmax focal loss相比,其在mIoU中增加了6.54%。结果表明,不改变梯度总和与调整损失分布是缓解前景-背景不平衡问题的关键。

Annealing function 退火函数用于F-A优化的动态加权阶段。它旨在缓解在早期训练期间由于硬实例估计错误而导致的训练不稳定性。表4 (d)、(e)和(f)显示了应用三种所提出的退火函数的结果。我们可以发现,基于退火的动态加权通过减少在早期训练期间错误的困难样本估计来提高性能。直观地看,余弦退火函数在mIoU中获得了最显著的增益,为0.63%。因为,在与linear annealing 和 polynomial annealing相比中,余弦退火函数在训练开始和结束时,下降速度较慢,可以稳定地调整损失分布以实现健康收敛。

The choice of the focusing factor γ 引入聚焦因子γ来调整困难样本的权重。更大的γ,更大的重量在困难样本。我们使用不同的γ来进行实验。结果如表5所示。随着γ的增加,性能得到不断提高。使用γ = 2,F-A优化使mIoU比基线提高3.29%,使mIoU达到63.71%。然而,在使用γ = 5时,性能就会下降。可能的原因是,噪声标签被错误地视为困难的例子,正如在[27]中提到的。

猜你喜欢

转载自blog.csdn.net/a486259/article/details/129716337