基于迁移学习的语义分割算法分享与代码复现
Posted 华为云
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于迁移学习的语义分割算法分享与代码复现相关的知识,希望对你有一定的参考价值。
摘要:语义分割的数据集是比较大的,因此训练的时候需要非常强大的硬件支持。
本文分享自华为云社区《【云驻共创】基于迁移学习的语义分割算法分享》,原文作者:启明。
此篇文章是分享两篇基于迁移学习的语义分割算法论文。第一篇:《Learning to adapt structured output space for semantic segmentation》,第二篇《ADVENT: Adversarial Entropy Minimization for Domain Adaptation in Semantic Segmentation》。
Part 1:迁移分割的背景介绍
语义分割,与检测和分类,是机器视觉领域的三个主流方向。但是语义分割相对于检测和分类来说,它面临着2个非常困难的问题:
一是它缺少数据集。分类的数据集是指标注一个类别,检测的数据集是指标注一个检测框,而分割的话,它的目的是要做语义级的预测。这就意味着它的标注也需要是像素级别的标注。我们知道,标注一个像素级别的数据集是十分耗时耗力的,以自动驾驶里面的Cityspaces举例,此数据集标注一幅图需要1.5个小时。在这种情况下,如果要我们自己来构建语义分割的数据集的话,时间精力成本是非常大的。
另一种问题,就是因为语义分割还需要覆盖现实世界的数据集。但实际情况是,它很难覆盖所有的情况,比如不同的天气,不同地方,建筑的不同风格,这都是语义分割要面临的问题。
那在面对上面两种情况下,研究者是如何解决语义分割的这2个问题的呢?
除了要从数据集上来解决,他们发现可以通过计算机图形学等技术通过合成出模拟的数据集代替真实世界的这些数据集,从而降低标注的成本。
以一款大家熟悉且常见的GTA5游戏来说:在GTA5里,有一个任务就是采集GTA5游戏里的模拟数据,然后通过数据引擎这种自然而然的标注去降低标注成本。但是这里会出现一个问题:在这些模拟数据上训练的模型,在实际现实世界的时候,会出现性能的降低。因为传统的机器学习需要有一个前提条件,就是你的测试集和你的训练集是相同分布的,而你模拟数据集和现实数据集必然的就存在分布的差异。
因此我们现在的目标就是,通过研究出来的迁移算法解决在源域训练的模型在目标域上性能降低的问题。
两篇论文的主要贡献介绍及相关工作
主要贡献
第一篇:《Learning to adapt structured output space for semantic segmentation》:
1、提出了一种机遇对抗学习的迁移分割算法;
2、验证了在output space 进行对抗能够有效的对其两个域的场景布局和上下文信息;
3、利用对多个层次的输出进行对抗,进一步提高了模型的迁移性能。
第二篇《ADVENT: Adversarial Entropy Minimization for Domain Adaptation in Semantic Segmentation》:
1、利用基于熵的损失函数,防止网络对目标域做出可信度较低的预测;
2、提出了一种机遇熵的对抗学习方式,同时考虑熵减和两个域的结构对齐;
3、提出了一种基于类别分布先验的约束方法。
相关工作
在讲解两篇论文之前,我们先简单介绍另一篇文章:《FCNs in the wild》。这篇论文,是将迁移学习用在语义分割上的第一篇论文。其提出通过对语义分割的特征提取器提取出来的特征送入到这个判别器里面,然后通过对齐Global的信息,完成分割任务上的迁移。
首先,我们先介绍一下常用的语义分割的网络是一个什么样的形式。常用的语义分割一般是由两部分组成:一部分是特征提取器,比如可以用Resnet系列,或者VGG系列来提取图片的特征;二是分类器,将前面提取的特征送入到分类器里面(分类器比较常见的是PSP,或者DA分割里面最常用的 DeepLab V2里的ASPP)。通过把特征提取提到的特征送入到判别器里面,进而来完成整个DA。
为什么把特征送入判别器能完成DA呢?从判别器的作用上,我们可以来理解这个问题。
训练判别器,就能让它区分输入进来的图片到底是真还是假。在这个过程中,需要用判别器区分输入的特征是源域还是目标域。得到一个能够区分特征是源域和目标域的判别器之后,固定判别的参数不变,去训练分割网络的特征提取器。如何训练呢:让这个特征提取器来混淆这个判别器。
那么特征提取器又怎么来混淆判别器呢?无论是提取源域还是目标域的特征,都要把这两个特征的分布对齐,这样的话就相当于把这两个域的特征,使这个判别器区分不出来,那么就完成了“混淆”的任务。一旦完成了“混淆”任务,就说明特征提取器提取到了这个“域不变”的信息。
提取到“域不变”的信息,实际上就是在做一个迁移过程。因为网络有了提取“域不变”信息的功能,那么无论是源域还是目标域都能提取出来一个非常好的特征。
后面我们的两篇文章都是基于“利用对抗及判别器”这个思想进行指导的,但不同的是,后面两篇文章输入判别器的信息不一样,具体的我们后面再详细介绍。
第一篇论文算法模型剖析:
文章标题:《Learning to adapt structured output space for semantic segmentation》
这篇论文和前面相关工作论文里的第一篇工作一样,是由分割网络和判别器组成的。从上面的图,或者就从题目上就可以看出,它是output space做adapted。那什么是output space呢?
这里的output space就是,语音分割网络输出的结果经过softmax之后,变成了一个概率的东西,我们称这个概率为output space,
此论文的作者认为直接用特征做对抗是不好的,不如用output space概率来做对抗,为什么呢?因为作者认为,在原本,就比如分类里面,大家都是用特征来做的,但是分割是不一样的。因为分割的高维度特征,就是你前面的特征部分,是一个非常长的向量,比如Resnet101的最后一层,它的特征长度2048维的,如此高维度特征,编码的信息当然更加复杂。但是对于语义分割,可能这些复杂信息并不是有用的。这是作者的一个观点。
作者的另一个观点是,语义分割的输出的结果虽然是低维度的,即output space这个概率,实际上只有类别数的这样的一个维度,就是假如类别数c的话,它这个概率对于每个像素点就是c*1的一个向量。虽然是低维度空间,但是一整个图片的输出,实际上包含了场景、布局以及上下文这些丰富的信息。本论文作者认为不管图片来自于源域还是目标域,分割出来的结果在空间上,应该是具有非常强的相似性的。因为不管是仿真数据还是模拟数据,同样都是在做的分割任务上。如上图,其源域和目标域都是针对于自动驾驶来做的。很明显的一个观点是,中间大部分可能是路,上面一般是天,然后左右可能是建筑。这种场景上的分布是有非常强的相似性的,因此作者认为直接使用低维度的这个概率,就是softmax输出来进行对抗就能取得一个非常好的效果。
基于以上两个insight,作者就设计直接把概率放到判别器里面。训练的过程实际上和GAN是一样的,只不过不再是把特征传入判别器里面,而是把最终输出的概率传到判别器里面。
回到上面那张图,可以看到,左边的两个DA,它们是多尺度的。回到我们一开始讲到的语义分割网络,它分为特征提取器和分类器,分类器的输入实际上就是特征提取器提取出来的特征。
大家都知道,Resnet实际上有好几层。作者基于这个事实提出,可以分别在最后一层以及倒数第二层,这两部分上来做output space的对抗。也就是把这两部分特征送到分类器上,然后把分类器的结果拿出来,输入判别器(Discriminator)里面来做对抗。
总结一下,本篇论文的算法创新点是:
1、在output space 进行对抗,利用了网络预测结果的结构信息;
2、利用对多个层次的输出进行对抗,进一步提高了模型。
那么我们来看看这样的结果是如何的吧?
上图是从GTA5到Cityspaces这个任务的实验结果。我们可以看到,第一条数据Baseline(Resnet)在源域上训练一个模型,然后拿到目标域上去测试。第二条数据是在特征维度上做出来一个结果,39.3。虽然相比于source only的模型有所提升,但是和下面两个在output space上做的对抗是相对较低的。第一个single level,是直接在Resnet最后一层提取出了特征,然后输入到分类器产生得到的结果;第二个multi-level是在Resnet倒数一二层都做对抗,结果可以看到,是会更好。
第二篇论文算法模型剖析
文章标题:《ADVENT: Adversarial Entropy Minimization for Domain Adaptation in Semantic Segmentation》
接下来,我们来讲第二篇:基于熵减和熵对抗的迁移分割的方法。
要理解这篇文章,我们要先理解“熵”这个概念。作者在文章中用信息熵来作为熵,就是公式中P和logP,也就是一个概率log。
语义分割,是网络对一张图片的每个像素点做预测。那么对于每个像素点来说,其最终结果是c*1的一个向量,c就是代表可能存在的这个类别数,因此,应该是每个类别的概率乘以log这个类别的概率。那么对一个像素点来说,把这个类别的熵来加起来,就代表这个像素点的熵。因此,对于一幅图来说的话,需要对图片的长和宽,也就是对每个像素点的熵做一个求和。
通过观察上图,作者发现了一个现象:在源域的分割图中得到熵值的分布,可以发现在这些类别的边缘部分,熵值是非常高的(颜色越深,代表熵值越低;颜色越浅,代表熵值越高)。那么对于目标域的那个图片,我们可以看到,其预测出来的结果,整张图片的颜色浅的部分是非常多的。因此,作者认为,因为源域上有太多没有用的熵值(因为存在一定噪声),通过减少目标率的熵值可以缩减源域和目标域之间的差距。
那么怎么去减少目标域的熵值呢?作者提出了两种方法,也即本文的算法创新点:
1、利用基于熵的损失函数,防止网络对目标域做出可信度较低的预测;
2、提出了一种基于熵的对抗学习方式,同时考虑熵减和两个领域的结构对齐。
利用对抗学习来最小化熵值,即得到一个图片总体的熵,直接通过梯度反向传播来优化总体的熵。但是作者认为如果直接做熵减的话,会忽略很多信息,就比如图片本身的语义结构信息等。因此作者借鉴第一篇讲output space对抗的方式,其提出了一种利用对抗学习来做熵减的方法。
可以看到,前面图片中源域的熵是非常低的,因此他认为如果能够用一个Discriminator来区分源域和目标域,从而使源域和目标域最终的输出的熵图非常相似的话,就可以减少目标域的熵。具体的做法就是和上一篇类似,只不过第一篇是直接把概率做到判别器里面,而第二篇是把熵送到判别器里面进行判别,从而完成整个过程。
本篇论文一方面考虑了熵减的过程,另一方面运用到了结构信息,因此实验的结果可以明显的看到在GTA5到Cityspace上,直接最小化熵相比于FCNs和使用output space做对抗已经有一定很很大的提高,再做熵对抗的更是比原本的方法要提升了一点几个点。
此外作者还发现,如果把直接做熵减和做熵来做对抗两者预测出来的概率相加,再求最大值,结果会再提高一点几个点。在语义分割任务里面,这种提高是非常可观的。
代码复现
下面我们进入代码复现的过程。
复现论文的原则是与论文中描述的具体方法、参数、数据增强等保持一致。
此次复现,首先在GitHub上查找开源代码,在开源代码的基础上,基于PyTorch框架将上述两篇论文用一个相同的框架实现。如果读懂一篇论文的代码,那么另一篇的代码是非常好理解的。
下面有两个二维码,分别是两篇论文的代码,可以扫码前往查看。
ModelArts简介
两篇论文都是基于华为云的ModelArts。我们首先简单介绍一下ModelArts。
ModelArts是面向开发者的一站式AI开发平台,为机器学习与深度学习提供海量数据预处理及半自动化标注、大规模分布式Training、自动化模型生成,及端-边-云模型按需部署能力,帮助用户快速创建和部署模型,管理全周期AI工作流。具体拥有以下核心功能:
数据管理,最多可节约80%的人工数据处理成本:涵盖图像、声音、文本、视频4大类数据格式9种标注工具,同时提供智能标注、团队标注极大提高标注效率;支持数据清洗,数据增强,数据检验等常见数据处理能力;数据集多版本灵活可视化管理,支持数据集导入导出,轻松用于ModelArts的模型开发和训练。
开发管理,可使用本地开发环境(IDE)对接云上服务:ModelArts除了可以在云上通过(管理控制台)界面开发外,同时还提供了Python SDK功能,可通过SDK在任意本地IDE中使用Python访问ModelArts, 包括创建、训练模型,部署服务,更加贴近自己的开发习惯。
训练管理,更快速训练高精度的模型:以大模型(EI-Backbone)为核心的普适AI建模工作流的3大优势:
1、基于小样本数据训练高精度模型,大量节约数据标注成本;
2、全空间网络架构搜索和自动超参优化技术可自动快速提升模型精度;
3、加载EI-Backbone集成的预训练模型后,模型训练到部署的流程可从数周缩短至几分钟,大幅降低训练成本。
模型管理,支持对所有迭代和调试的模型进行统一管理:AI模型的开发和调优往往需要大量的迭代和调试,数据集、训练代码或参数的变化都可能会影响模型的质量,如不能统一管理开发流程元数据,可能会出现无法重现最优模型的现象。ModelArts支持4个场景的导入模型:从训练中选择,从模板中选择,从容器镜像中选择,从OBS中选择。
部署管理,一键部署至端、边、云:ModelArts支持在线推理、批量推理、边缘推理多种形态。同时,高并发在线推理满足线上大业务量诉求,高吞吐批量推理能快速解决沉积数据推理诉求,高灵活性边缘部署使推理动作可以在本地环境完成。
镜像管理,自定义镜像功能支持自定义运行引擎:ModelArts底层采用容器技术,您可自行制作容器镜像并在ModelArts上运行。自定义镜像功能支持自由文本形式的命令行参数和环境变量,灵活性比较高,便于支持任意计算引擎的作业启动需求。
代码解释
接下来,我们给代码做一个具体的解释。
首先是第一篇:AdaptSegNet中的multi-level output space对抗,代码如下:
如前所述,把通过softmax得到的概率送到判别器里面,就是上图画红框部分。
为什么会有D1和D2呢?正如之前讲过的,特征可以采用Resnet101的倒数第一层和倒数第二层形成一个multi-level的对抗过程。那在具体loss的时候,可以使用bce_loss来处理对抗。
第二篇:ADVENT中的Minimizing entropy with adversarial learning
此论文需要来计算熵。那熵是怎么计算的呢?
首先获得概率。通过把网络的输出通过softmax求得一个概率,然后使用P*logP来求出熵值,再把熵送入Discriminator。
两篇论文都是用对抗的方法,唯一的区别是一个把softmax的输出放进去,另一个是把softmax的输出概率转化成熵再送进去。代码也就进行了这一处更改。因此大家如果能够看懂第一篇代码的流程的话,很容易对第二篇代码上手了
结语
语义分割的数据集是比较大的,因此训练的时候需要非常强大的硬件支持。一般来说,实验室可能只有10/11/12g的GPU,而如果使用华为云ModelArts的话(综合之前对ModelArts的一个功能介绍),可以获得更好的一个输出结果。
如果感兴趣,可以点击>>>AI开发平台ModelArts,前往体验。
大家如果对《Learning to adapt structured output space for semantic segmentation》和《ADVENT: Adversarial Entropy Minimization for Domain Adaptation in Semantic Segmentation》这两篇文章感兴趣,可以通过下面的二维码获得论文的原文全文。
以上是关于基于迁移学习的语义分割算法分享与代码复现的主要内容,如果未能解决你的问题,请参考以下文章