使用 EasyCV Mask2Former 轻松实现图像分割

导言

图像分割(Image Segmentation)是指对图片进行像素级的分类,根据分类粒度的不同可以分为语义分割(Semantic Segmentation)、实例分割(Instance Segmentation)、全景分割(Panoptic Segmentation)三类。图像分割是计算机视觉中的主要研究方向之一,在医学图像分析、自动驾驶、视频监控、增强现实、图像压缩等领域有重要的应用价值。我们在EasyCV框架中对这三类分割SOTA算法进行了集成,并提供了相关模型权重。通过EasyCV可以轻松预测图像的分割谱以及训练定制化的分割模型。本文主要介绍如何使用EasyCV实现实例分割、全景分割和语义分割,及相关算法思想。

使用EasyCV预测分割图

EasyCV提供了在coco数据集上训练的实例分割模型和全景分割模型以及在ADE20K上训练的语义分割模型,参考EasyCV quick start(https://github.com/alibaba/EasyCV/blob/master/docs/source/quick_start.md)完成依赖环境的配置后,可以直接使用这些模型完成对图像的分割谱预测,相关模型链接在reference中给出。

实例分割预测

由于该示例中的mask2fromer算法使用了Deformable attention (在DETR系列算法中使用该算子可以有效提升算法收敛速度和计算效率),需要额外对该算子进行编译

cd thirdparty/deformable_attention
python setup.py build install

通过Mask2formerPredictor预测图像实例分割图

import cv2
from easycv.predictors.segmentation import Mask2formerPredictorpredictor = Mask2formerPredictor(model_path='mask2former_instance_export.pth',task_mode='instance')
img = cv2.imread('000000123213.jpg')
predict_out = predictor(['000000123213.jpg'])
instance_img = predictor.show_instance(img, **predict_out[0])
cv2.imwrite('instance_out.jpg',instance_img)

输出结果如下图:

全景分割预测

通过Mask2formerPredictor预测图像全景分割图

import cv2
from easycv.predictors.segmentation import Mask2formerPredictorpredictor = Mask2formerPredictor(model_path='mask2former_pan_export.pth',task_mode='panoptic')
img = cv2.imread('000000123213.jpg')
predict_out = predictor(['000000123213.jpg'])
pan_img = predictor.show_panoptic(img, **predict_out[0])
cv2.imwrite('pan_out.jpg',pan_img)

输出结果如下图:

语义分割预测

通过Mask2formerPredictor预测图像语义分割图

import cv2
from easycv.predictors.segmentation import Mask2formerPredictorpredictor = Mask2formerPredictor(model_path='mask2former_semantic_export.pth',task_mode='semantic')
img = cv2.imread('000000123213.jpg')
predict_out = predictor(['000000123213.jpg'])
semantic_img = predictor.show_panoptic(img, **predict_out[0])
cv2.imwrite('semantic_out.jpg',semantic_img)

示例图片来源:cocodataset

在阿里云机器学习平台PAI上使用Mask2Former模型

PAI-DSW(Data Science Workshop)是阿里云机器学习平台PAI开发的云上IDE,面向各类开发者,提供了交互式的编程环境。在DSW Gallery中(链接),提供了各种Notebook示例,方便用户轻松上手DSW,搭建各种机器学习应用。我们也在DSW Gallery中上架了Mask2Former进行图像分割的Sample Notebook(见下图),欢迎大家体验!

Mask2Former算法解读

上述例子中采用的模型是基于Mask2former实现的,Mask2former是一个统一的分割架构,能够同时进行语义分割、实例分割以及全景分割,并且取得SOTA的结果,在COCO数据集上全景分割精度57.8 PQ,实例分割精度达50.1 AP,在ADE20K数据集上语义分割精度达57.7 mIoU。

核心思想

Mask2Former采用mask classification的形式来进行分割,即通过模型去预测一组二值mask再组合成最终的分割图。每个二值mask可以代表类别或实例,就可以实现语义分割、实例分割等不同的分割任务。

在mask classsification任务中,一个比较核心的问题是如何去找到一个好的形式学习二值Mask。如先前的工作 Mask R-CNN通过bounding boxes来限制特征区域,在区域内预测各自的分割谱。这种方式也导致Mask R-CNN只能进行实例分割。Mask2Former参考DETR的方式,通过一组固定数量的特征向量(object query)去表示二值Mask,通过Transformer Decoder进行解码去预测这一组Mask。(ps:关于DETR的解读可以参考:基于EasyCV复现DETR和DAB-DETR,Object Query的正确打开方式)

在DETR系列的算法中,有一个比较重要的缺陷是在Transformer Decoder中的cross attention中会对全局的特征进行处理,导致模型很难关注到真正想要关注的区域,会降低模型的收敛速度和最终的算法精度。对于这个问题Mask2former提出了Transformer Decoder with mask attention,每个Transformer Decoder block 会去预测一个attention mask并以0.5为阈值进行二值化,然后将这个attentino mask作为下一个block的输入,让attention模块计算时只关注在mask的前景部分。

模型结构

Mask2Former由三个部分组成:

  1. Backbone(ResNet、Swin Transformer)从图片中抽取低分辨率特征
  2. Pixel Decoder 从低分辩率特征中逐步进行上采样解码,获得从低分辨率到高分辨率的特征金字塔,循环的作为Transformer Decoder中V、K的输入。通过多尺度的特征来保证模型对不同尺度的目标的预测精度。

其中一层的Trasformer代码如下所示(ps:为了进一步加速模型的收敛速度,在Pixel Decoder中采用了Deformable attention模块):

class MSDeformAttnTransformerEncoderLayer(nn.Module):def __init__(self,d_model=256,d_ffn=1024,dropout=0.1,activation='relu',n_levels=4,n_heads=8,n_points=4):super().__init__()# self attentionself.self_attn = MSDeformAttn(d_model, n_levels, n_heads, n_points)self.dropout1 = nn.Dropout(dropout)self.norm1 = nn.LayerNorm(d_model)# ffnself.linear1 = nn.Linear(d_model, d_ffn)self.activation = _get_activation_fn(activation)self.dropout2 = nn.Dropout(dropout)self.linear2 = nn.Linear(d_ffn, d_model)self.dropout3 = nn.Dropout(dropout)self.norm2 = nn.LayerNorm(d_model)@staticmethoddef with_pos_embed(tensor, pos):return tensor if pos is None else tensor + posdef forward_ffn(self, src):src2 = self.linear2(self.dropout2(self.activation(self.linear1(src))))src = src + self.dropout3(src2)src = self.norm2(src)return srcdef forward(self,src,pos,reference_points,spatial_shapes,level_start_index,padding_mask=None):# self attentionsrc2 = self.self_attn(self.with_pos_embed(src, pos), reference_points, src,spatial_shapes, level_start_index, padding_mask)src = src + self.dropout1(src2)src = self.norm1(src)# ffnsrc = self.forward_ffn(src)return src

3.Transformer Decoder with mask attention 通过Object query和Pixel Decoder中得到的Multi-scale feature去逐层去refine二值mask图,得到最终的结果。

其中核心的mask cross attention,会将前一层的预测的mask作为MultiheadAttention的atten_mask输入,以此来将注意力的计算限制在这个query关注的前景中。具体实现代码如下:

class CrossAttentionLayer(nn.Module):def __init__(self,d_model,nhead,dropout=0.0,activation='relu',normalize_before=False):super().__init__()self.multihead_attn = nn.MultiheadAttention(d_model, nhead, dropout=dropout)self.norm = nn.LayerNorm(d_model)self.dropout = nn.Dropout(dropout)self.activation = _get_activation_fn(activation)self.normalize_before = normalize_beforeself._reset_parameters()def _reset_parameters(self):for p in self.parameters():if p.dim() > 1:nn.init.xavier_uniform_(p)def with_pos_embed(self, tensor, pos: Optional[Tensor]):return tensor if pos is None else tensor + posdef forward_post(self,tgt,memory,memory_mask: Optional[Tensor] = None,memory_key_padding_mask: Optional[Tensor] = None,pos: Optional[Tensor] = None,query_pos: Optional[Tensor] = None):tgt2 = self.multihead_attn(query=self.with_pos_embed(tgt, query_pos),key=self.with_pos_embed(memory, pos),value=memory,attn_mask=memory_mask,key_padding_mask=memory_key_padding_mask)[0]tgt = tgt + self.dropout(tgt2)tgt = self.norm(tgt)return tgtdef forward_pre(self,tgt,memory,memory_mask: Optional[Tensor] = None,memory_key_padding_mask: Optional[Tensor] = None,pos: Optional[Tensor] = None,query_pos: Optional[Tensor] = None):tgt2 = self.norm(tgt)tgt2 = self.multihead_attn(query=self.with_pos_embed(tgt2, query_pos),key=self.with_pos_embed(memory, pos),value=memory,attn_mask=memory_mask,key_padding_mask=memory_key_padding_mask)[0]tgt = tgt + self.dropout(tgt2)return tgtdef forward(self,tgt,memory,memory_mask: Optional[Tensor] = None,memory_key_padding_mask: Optional[Tensor] = None,pos: Optional[Tensor] = None,query_pos: Optional[Tensor] = None):if self.normalize_before:return self.forward_pre(tgt, memory, memory_mask,memory_key_padding_mask, pos, query_pos)return self.forward_post(tgt, memory, memory_mask,memory_key_padding_mask, pos, query_pos)

Tricks

1.efficient multi-scale strategy

在pixel decoder中会解码得到尺度为原图1/32、1/16、1/8的特征金字塔依次作为对应transformer decoder block的K、V的输入。参照deformable detr的做法,对每个输入都加上了sinusoidal positional embedding和learnable scale-level embedding。按分辨率从低到高的循序依次输入,并循环L次。

2.PointRend

通过PointRend的方式来节省训练过程中的内存消耗,主要体现在两个部分a.在使用匈牙利算法匹配预测mask和真值标签时,通过均匀采样的K个点集代替完整的mask图来计算match cost b.在计算损失时按照importance sampling策略采样的K个点集代替完整的mask图来计算loss(ps实验证明基于pointreind方式来计算损失能够有效提升模型精度)

3.Optimization improvements

    1. 更换了self-attention和cross-attention的顺序。self-attention->cross-attention变成cross-attention->self-attention。
    2. 让query变成可学习的参数。让query进行监督学习可以起到类似region proposal的作用。通过实验可以证明可学习的query可以产生mask proposal。
    3. 去掉了transformer deocder中的dropout操作。通过实验发现这个操作会降低精度。

复现精度

实例分割及全景分割在COCO上的复现精度,实验在单机8卡A100环境下进行(ps :关于实例分割复现精度问题在官方repo issue 46中有提及)

ModelPQBox mAPMask mAPmemorytrain_time
mask2former_r50_instance_official43.7
mask2former_r50_8xb2_epoch50_instance46.0943.2613G3day2h
mask2former_r50_panoptic_official51.941.7
mask2former_r50_8xb2_epoch50_panoptic51.6444.8141.8813G3day4h

语义分割在ADE20K数据集上进行复现

ModelmIoUtrain memorytrain_time
mask2former_r50_semantic_official47.2
mask2former_r50_8xb2_e127_samantic47.035.6G15h35m

使用EasyCV训练分割模型

对于特定场景的分割,可以使用EasyCV框架和相应数据训练定制化的分割模型。这里以实例分割为例子,介绍训练流程。

一、数据准备

目前EasyCV支持COCO形式的数据格式,我们提供了示例COCO数据用于快速走通流程。

wget http://pai-vision-data-hz.oss-cn-zhangjiakou.aliyuncs.com/data/small_coco_demo/small_coco_demo.tar.gz && tar -zxf small_coco_demo.tar.gzmkdir -p data/  && mv small_coco_demo data/coco

二、模型训练

在EasyCV的config文件夹下,我们提供了mask2former的数据处理和模型训练及验证的配置文件(configs/segmentation/mask2former/mask2former_r50_8xb2_e50_instance.py),根据需要修改预测的类别、数据路径。

执行训练命令,如下所示:

#单机八卡
python -m torch.distributed.launch --nproc_per_node=8 --master_port 11111 tools/train.py \configs/segmentation/mask2former/mask2former_r50_8xb2_e50_instance.py \--launcher pytorch \--work_dir experiments/mask2former_instance \--fp16 

模型导出,将config文件保存到模型中,以便在predictor中得到模型和数据处理的配置,导出后的模型就可直接用于分割图的预测。

python tools/export.py configs/segmentation/mask2former/mask2former_r50_8xb2_e50_instance.py epoch_50.pth mask2former_instance_export.pth

Reference

实例分割模型:http://pai-vision-data-hz.oss-cn-zhangjiakou.aliyuncs.com/EasyCV/modelzoo/segmentation/mask2former_r50_instance/mask2former_instance_export.pth

全景分割模型:http://pai-vision-data-hz.oss-cn-zhangjiakou.aliyuncs.com/EasyCV/modelzoo/segmentation/mask2former_r50_panoptic/mask2former_pan_export.pth

语义分割模型:http://pai-vision-data-hz.oss-cn-zhangjiakou.aliyuncs.com/EasyCV/modelzoo/segmentation/mask2former_r50_semantic/mask2former_semantic_export.pth

作者:贺弘 谦言 临在

原文链接

本文为阿里云原创内容,未经允许不得转载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/510371.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

八皇后问题详解(最短代码)

八皇后问题算法分析: 分析1:八皇后由一个64格的方块组成,那么把八个皇后放入不考虑其他情况利用穷举法,有8^64种 可能。 分析2:显然任意一行有且仅有1个皇后,使用数组queen[0->7]表示第i行的皇后位于哪一…

5个编写技巧,有效提高单元测试实践

1. 什么是单元测试 “在计算机编程中,单元测试又称为模块测试,是针对程序模块来进行正确性检验的测试工作。程序单元是应用的最小可测试部件。在过程化编程中,一个单元就是单个程序、函数、过程等;对于面向对象编程,最…

谈谈我工作中的23个设计模式

序 从基础的角度看,设计模式是研究类本身或者类与类之间的协作模式,是进行抽象归纳的一个很好的速成思路。后面阅读设计模式后,为了加深理解,对相关图片进行了描绘和微调。 从技术的角度已经有很多好的总结,本文会换…

OpenSergo 流量路由:从场景到标准化的探索

流量路由,顾名思义就是将具有某些属性特征的流量,路由到指定的目标。流量路由是流量治理中重要的一环,多个路由如同流水线一样,形成一条路由链,从所有的地址表中筛选出最终目的地址集合,再通过负载均衡策略…

传统 Web 框架部署与迁移

与其说 Serverless 架构是一个新的概念,不如说它是一种全新的思路,一种新的编程范式。 但是原生的 Serverless 开发框架却非常少。以 Web 框架为例,目前主流的 Web 框架“均不支持 Serverless 模式部署”,因此我们一方面要尝试接…

三款“非主流”日志查询分析产品初探

前言 近些年在开源领域,用于构建日志系统的软件有两类典型: Elasticsearch:基于 Lucene 构建倒排索引提供搜索功能,DocValue 存储支持了其统计分析能力。Clickhouse:列式存储是其优秀 OLAP 性能的保障。 这里把上述系…

CIPU落地专有云:是“小众需求”还是“机会之门”?

引言:2022年11月,云栖大会主论坛,阿里巴巴集团副总裁、阿里云智能基础产品事业部负责人蒋江伟分享了阿里云专有云的一项新进展 —— CIPU落地飞天企业版。在分析师峰会上,阿里巴巴集团研究员、阿里云专有云总经理刘国华也向分析师…

基于开源 PolarDB-X 打造中正智能身份认证业务数据基座

一、公司及业务介绍 中正智能是全球领先的生物识别和身份认证公司之一。我们曾负责公安部指纹算法国家标准的起草、编写,具备从算法、终端、平台、设计、生产、交付全域自研的能力,拥有多项自主知识产权的产品,并积极与高校合作开展基础研发。…

如何开发一个标准的云原生应用?

从几个数字开始说 IDC 预计到 2024 年,由于采用了微服务、容器、动态编排和 DevOps 等技术,新增的生产级云原生应用在新应用的占比将从 2020 年的 10% 增加到 60%,其中微服务的 workload 在企业内将超过 80% 。上面的四点是云原生时代所代表…

Higress实战: 30行代码写一个Wasm Go插件

前言 在11月15号的直播 《Higress 开源背后的发展历程和上手 Demo 演示》中,为大家演示了 Higress 的 Wasm 插件如何面向 Ingress 资源进行配置生效,本文对当天的 Demo 进行一个回顾,并说明背后的原理机制。 本文中 Demo 运行的前提&#x…

Serverless 的前世今生

从云计算到 Serverless 架构 大家好,我是阿里云 Serverless 产品经理刘宇,很高兴可以和大家一起探索 Serverless 架构的前世今生。 从云计算到云原生再到 Serverless 架构,技术飞速发展的轨迹都有一定规律可循,那么 Serverless 架…

eunomia-bpf 项目重磅开源!eBPF 轻量级开发框架来了

近日,在 2022 云栖大会龙蜥峰会 eBPF & Linux 稳定性专场上,来自 eBPF 技术探索 SIG Maintainer 、浙江大学的郑昱笙分享了《eunomia-bpf:eBPF 轻量级开发框架》技术演讲,以下为本次演讲内容: 大家好!…

一文看懂分布式链路监控系统

背景 传统的大型单体系统随着业务体量的增大已经很难满足市场对技术的需求,通过对将整块业务系统拆分为多个互联依赖的子系统并针对子系统进行独立优化,能够有效提升整个系统的吞吐量。在进行系统拆分之后,完整的业务事务逻辑所对应的功能会…

深度 | 新兴软件研发范式崛起,云计算全面走向 Serverless 化

11月3日,2022 杭州 云栖大会上,阿里云智能总裁张建锋表示,以云为核心的新型计算体系正在形成,软件研发范式正在发生新的变革,Serverless 是其中最重要的趋势之一,阿里云将坚定推进核心产品全面 Serverless…

适用场景全新升级!扩展 Dragonfly2 作为分布式缓存系统架构

Dragonfly2 简介 Dragonfly 作为龙蜥社区的镜像加速标准解决方案,是一款基于 P2P 的智能镜像和文件分发工具。它旨在提高大规模文件传输的效率和速率,最大限度地利用网络带宽。在应用分发、缓存分发、日志分发和镜像分发等领域被大规模使用。 现阶段 D…

sdut 最长公共子序列问题

Problem Description 从一个给定的串中删去(不一定连续地删去)0个或0个以上的字符,剩下地字符按原来顺序组成的串。例如:“ ”,“a”,“xb”,“aaa”,“bbb”,“xabb”&a…

hdu1176 免费馅饼 动态规划 二维数组实现

免费馅饼 Time Limit: 1000MS Memory Limit: 32768KBSubmit Statistic DiscussProblem Description 都说天上不会掉馅饼,但有一天gameboy正走在回家的小径上,忽然天上掉下大把大把的馅饼。说来gameboy的人品实在是太好了,这馅饼别处都不掉&am…

如何通过链路追踪进行定时任务诊断

背景简介 什么是定时任务 定时任务是业务应用系统中存在定时周期性运行的业务逻辑。由于其运行于后端进程中往往存在执行状态和执行链路的不可见性《常见定时任务技术方案》。 什么是链路追踪 随着分布式微服务化架构在企业中大规模运用,业务运行的应用平台是一…

关于平台工程的开发者工具链,你还想加点啥?

前言 从 Kubernetes 诞生以来,以 DevOps、容器化、可观测、微服务、Serverless 等技术为代表的云原生,催生了应用架构新一轮的升级。有意思的是,与以往的技术迭代更新不同,原本是一个技术圈常规的一次技术实践,在千行…

阿里云联合“产学研媒”发起 BizDevOps 共促计划,助力企业提升组织效能

2012年全球最具影响力的独立研究咨询机构Forrester曾预言:“In the future, all companies will be software companies”(在未来,所有的企业都将成为软件企业) 近10年来,DevOps运动在全球和中国风起云涌,…