【传知代码】主动学习实现领域自适应语义分割(论文复现)

在计算机视觉的领域中,语义分割作为一种核心技术,致力于将图像中的每一个像素分类到不同的语义类别中。随着应用场景的不断拓展,从自动驾驶到医疗图像分析,传统的语义分割方法面临着越来越复杂的挑战。然而,在不同领域和环境下,模型的性能往往受到显著影响,这催生了对领域自适应技术的迫切需求。

目录

概述

核心代码

复现过程

写在最后


概述

        自训练极大地促进了领域自适应语义分割,在无标签目标数据上迭代生成伪标签并重新训练网络。到目前为止,由于数据集移位,考虑将注释从在给定域(合成数据集)上训练的模型迁移到不同域(真实世界数据集)的工作很少。然而,它在实践中经常发生,但并没有得到完美解决。一般来说,伪标签是有噪声的,而自我训练会着重于高频率的类,而牺牲了在罕见类或小物体上的性能,从而导致不期望的偏差,在此,让我们简要介绍一下主动学习的目标。主动学习(Active learning)旨在在尽可能减少标记工作量的同时,最大化模型性能。常见的策略包括不确定性抽样和代表性抽样。然而,迄今为止,由于数据集的偏移,训练于特定领域(如合成数据集)的模型在迁移到不同领域(如真实世界数据集)时,面临的挑战很少被解决,但这种情况在实际应用中经常发生,但却尚未得到充分的解决。在本项工作中,有效地解决了这一问题。

主要贡献有以下几个方面:

1)对之前关于语义分割的主动域适应方法的性能进行了基准测试,发现使用基于图像或基于点的选择策略的方法是无效的

2)提出了一种基于区域的自适应语义分割策略,称为RIPU。它利用了区域杂质和预测不确定性识别空间邻接性不同、预测输出不确定的图像区域

3)实验表明,使用标准的分割模型,即DeepLab-v2和DeepLab-v3+,该方法在两个代表性的域适应基准上带来了显著的性能提升,即 GTAV → Cityscapes, SYNTHIA → Cityscapes

核心代码

下图为模型整体结构图;我们将整个模型运行分为3部分讲解:图像区域生成,主动学习过程,损失函数计算;接下来我们将分别进行详细介绍:

区域生成:传统的基于区域的主动学习语义分割方法只是将图像分割成互不重叠的矩形或采用超像素算法。作者认为这些固定的区域不灵活或不适合基于区域的选择策略。主要原因是相邻区域的模型预测也需要考虑,本文将像素的k平方邻域视为一个区域,具体来说,将大小为(2k + 1, 2k + 1)的规则形状的正方形视为以每个像素为中心的区域。下图是对传统和本文提出的区域生成方法的对比:

以下是区域选取算法的核心代码,计算当前样本中需要选择的活跃区域数量:

active_regions = math.ceil(num_pixel_cur * active_ratio / per_region_pixels)
            # 选择指定数量的活跃区域
            for pixel in range(active_regions):
                values, indices_h = torch.max(score, dim=0)
                _, indices_w = torch.max(values, dim=0)
                w = indices_w.item()
                h = indices_h[w].item()

                active_start_w = w - active_radius if w - active_radius >= 0 else 0
                active_start_h = h - active_radius if h - active_radius >= 0 else 0
                active_end_w = w + active_radius + 1
                active_end_h = h + active_radius + 1

                mask_start_w = w - mask_radius if w - mask_radius >= 0 else 0
                mask_start_h = h - mask_radius if h - mask_radius >= 0 else 0
                mask_end_w = w + mask_radius + 1
                mask_end_h = h + mask_radius + 1

主动学习过程:在实际应用中,语义分割常常面临类别不平衡问题,因为某些类别的出现频率较低。这导致少数类别的性能在训练过程中可能显著下降,因为训练样本不足。为了解决这个问题,可以在训练过程中采用类重新平衡或增强的方法,主动学习通过在数据收集阶段迭代地选择一批样本进行标注,可以隐式地帮助解决这种类别不平衡的问题。给定预定义的图像区域,本文描述了采集策略,并实现了两种不同的标注机制,即基于区域的标注 Region-based (RA)和基于像素的标注 Pixel-based (PA):

1)Region-based Annotating:RA标注所选区域中的每个像素

2)Pixel-based Annotating:PA通过选择区域内的中心像素,更注重标记效率

下图是两种传统策略和Region-based策略的对比:

以下我们将以Region-based策略为例,讲解部分核心代码,计算当前样本中需要选择的活跃区域数量:

active_regions = math.ceil(num_pixel_cur * active_ratio / per_region_pixels)

选择指定数量的活跃区域: 

for pixel in range(active_regions):
     values, indices_h = torch.max(score, dim=0)
     _, indices_w = torch.max(values, dim=0)
     w = indices_w.item()
     h = indices_h[w].item()

active_start_w = w - active_radius if w - active_radius >= 0 else 0
active_start_h = h - active_radius if h - active_radius >= 0 else 0
active_end_w = w + active_radius + 1
active_end_h = h + active_radius + 1

mask_start_w = w - mask_radius if w - mask_radius >= 0 else 0
mask_start_h = h - mask_radius if h - mask_radius >= 0 else 0
mask_end_w = w + mask_radius + 1
mask_end_h = h + mask_radius + 1

在接下来的文章中,我们介绍一种有效的获取函数,联合捕获区域不纯度(Region Impurity)和预测不确定性(Prediction Uncertainty),提取空间邻接多样性和预测输出不确定性的区域。

Region Impurity:给定一个目标图像,我们首先将其传递给网络,然后得到softmax输出。通过最大概率输出可以直接推导出目标伪标签。我们将一个区域划分为C个子集。目前,我们可以收集一个区域的类别统计信息。如果一个区域中有很多类别,我们认为它在标记后有助于训练网络。也就是选择区域内类别最多的区域进行再训练

Prediction Uncertainty:由于预测结果携带语义关系信息,为了衡量不确定性,我们使用每个像素的预测熵作为预测的不确定性;在基于像素的标注(PA)中,每个像素的不确定性就是熵的值;在基于区域的标注(RA)中,用区域内所有像素熵的平均值来评估其预测不确定性。总而言之,也就是选取预测不确定性最大的数据进行再训练

最后,将两种获取函数进行融合形成最终的获取函数:

# 将区域不纯度和预测不确定性相乘获得得分
score = region_impurity * prediction_uncertainty
return score.squeeze(dim=0).squeeze(dim=0), region_impurity.squeeze(dim=0).squeeze(
            dim=0), prediction_uncertainty.squeeze(dim=0).squeeze(dim=0)

Loss函数计算:来自源域和目标域的所有标记数据都用于通过优化标准监督损失来微调网络:使用分类交叉熵损失,同时,加强源图像中某个像素与其邻近像素之间的预测一致性,从而使模型的预测更加平滑,避免对源数据的过拟合:使用区域内所有像素的均值预测,此外,在训练的早期阶段,目标图像的较低输出概率实际上显示了特定的缺席类,称为负伪标签。例如,我们很难判断一个预测值为 [0.49,0.50,0.01] 的像素属于哪个类别,但我们可以清楚地知道它不属于得分为0.01的类别。因此,我们赋予负伪标签,因为τ是负阈值,在这项工作中使τ = 0.05,称为负学习损失:

# 源域监督损失
loss = torch.Tensor([0]).cuda()
loss_sup = sup_criterion(src_out, src_label)
meters.update(loss_sup=loss_sup.item())
loss += loss_sup

# 目标域活动监督损失
if torch.sum((tgt_mask != 255)) != 0:  # 目标域有标记像素
    loss_sup_tgt = sup_criterion(tgt_out, tgt_mask)
    meters.update(loss_sup_tgt=loss_sup_tgt.item())
    loss += loss_sup_tgt

# 源一致性正则化损失
if cfg.SOLVER.CONSISTENT_LOSS > 0:
    consistent_loss = local_consistent_loss(src_out, src_label) * cfg.SOLVER.CONSISTENT_LOSS
    meters.update(cr_loss=consistent_loss.item())
    loss += consistent_loss

# 目标负伪损失
if cfg.SOLVER.NEGATIVE_LOSS > 0:
    negative_learning_loss = negative_criterion(predict) * cfg.SOLVER.NEGATIVE_LOSS
    meters.update(nl_loss=negative_learning_loss.item())
    loss += negative_learning_loss

复现过程

下载所需库

pip install -r requirements.txt

下载数据集:并放在对应文件夹路径内:

ln -s /path_to_cityscapes_dataset datasets/cityscapes
ln -s /path_to_gtav_dataset datasets/gtav
ln -s /path_to_synthia_dataset datasets/synthia

运行生成GTAV/SYNTHIA数据集的标签静态文件: 

python datasets/generate_gtav_label_info.py -d datasets/gtav -o datasets/gtav/
python datasets/generate_synthia_label_info.py -d datasets/synthia -o datasets/synthia/

数据文件夹的结构应如下:

├── datasets/
│   ├── cityscapes/     
|   |   ├── gtFine/
|   |   ├── leftImg8bit/
│   ├── gtav/
|   |   ├── images/
|   |   ├── labels/
|   |   ├── gtav_label_info.p
│   └──	synthia
|   |   ├── RAND_CITYSCAPES/
|   |   ├── synthia_label_info.p
│   └──	

开始训练:

训练固定轮数后继续提取数据:

语义分割结果:

写在最后

综上所述,主动学习在领域自适应语义分割中的应用,展现了其独特的优势和巨大潜力。通过智能选择最具信息量的样本进行标注,主动学习不仅显著降低了数据标注的成本,还极大地提升了模型在新领域的适应能力。这种技术的进步,不仅突破了传统语义分割的局限,也为智能视觉系统的发展开辟了新的道路。

未来,随着技术的不断演进,我们可以预见,主动学习将更加深入地融合到语义分割的各个应用场景中,从自动驾驶到医学影像,乃至智能监控等领域,它的影响将不断扩大。面对日新月异的挑战和机遇,主动学习无疑将成为推动领域自适应语义分割前沿突破的关键力量。让我们期待,这一技术如何不断创新,重塑智能视觉的未来,为我们带来更为精准和智能的图像理解体验。

详细复现过程的项目源码、数据和预训练好的模型可从地址获取。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

亦世凡华、

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值