【实例分割|Mask2Former】 解决模型推理预测的代码中存在的一些问题
文章目录
- 取消终端输出网络结构
- 推理置信度设置
- 预测实例存在多个轮廓
- 预测模型返回筛选后实例
取消终端输出网络结构
在运行 demo.py
时,终端会输出大量网络结构信息,影响调试代码。
需要在 Detectron2 中的 detectron2/utils/memory.py
中注释 log :
def wrapped(*args, **kwargs):with _ignore_torch_cuda_oom():return func(*args, **kwargs)# Clear cache and retrytorch.cuda.empty_cache()with _ignore_torch_cuda_oom():return func(*args, **kwargs)# Try on CPU. This slows down the code significantly, therefore print a notice.logger = logging.getLogger(__name__)# logger.info("Attempting to copy inputs of {} to CPU due to CUDA OOM".format(str(func))) # 会在终端打印出大量信息new_args = (maybe_to_cpu(x) for x in args)new_kwargs = {k: maybe_to_cpu(v) for k, v in kwargs.items()}return func(*new_args, **new_kwargs)
推理置信度设置
虽然官方的 Maks2Former 继承自 Detectron2 ,但是网络结构是重新编写的,也就是从图像输入到预测输出部分都是 Mask2Former 自己的网络代码,Detectron2 在网络返回预测结果之前做了非极大值抑制和置信度阈值筛选,但 Mask2Former 代码每次都输出 100 个实例,没有做阈值设定和非极大值抑制,效果就是很多实例 mask 重叠在一起,惨不忍睹。
修改 demo/predictor.py
中的 def run_on_image(self, image)
函数的以下内容:
if "instances" in predictions:instances = predictions["instances"].to(self.cpu_device) # 类型: <class 'detectron2.structures.instances.Instances'># 取得分大于阈值的实例instances_ = Instances(instances.image_size)flag = Falsefor index in range(len(instances)):print(instances[index].scores)score = instances[index].scores[0]if score > 0.75: # 置信度设置if flag == False:instances_ = instances[index]flag = Trueelse:instances_ = Instances.cat([instances_, instances[index]])vis_output = visualizer.draw_instance_predictions(predictions=instances_)
预测实例存在多个轮廓
这里我将其中置信度大于一定的阈值的某个实例的 mask 单独输出,发现该实例存在不止一个轮廓,证明了误检的部分不是单独的实例,除了最大的那个轮廓,其他小轮廓是我们不需要的。
我选择对 mask 中的其他轮廓进行填充操作。instances[index].pred_masks = mask
这样无法对 Instances
对象的每个索引进行操作,只能对整个对象 pred_masks
进行赋值。在 Maks2Former 的 demo/predictor.py
中做修改:
if "instances" in predictions:instances = predictions["instances"].to(self.cpu_device) # 类型: <class 'detectron2.structures.instances.Instances'># 取得分大于阈值的实例instances_ = Instances(instances.image_size)flag = Falsefor index in range(len(instances)):score = instances[index].scores[0]if score > 0.75:print(instances.pred_masks.shape)mask = torch.squeeze(instances[index].pred_masks).numpy()*255import numpy as npmask = np.array(mask, np.uint8) # 类型转换后才能输入查找轮廓contours, hierachy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)areas = []for cnt in contours:areas.append(cv2.contourArea(cnt))for cnt in contours:if cv2.contourArea(cnt) < max(areas):cv2.drawContours(mask, [cnt], contourIdx=-1, color=0, thickness=-1)mask = torch.from_numpy(mask / 255).unsqueeze(0)if flag == False:instances_ = instances[index]masks = maskflag = Trueelse:instances_ = Instances.cat([instances_, instances[index]])masks = torch.cat((masks, mask), 0)print(masks.shape)instances_.pred_masks = masksvis_output = visualizer.draw_instance_predictions(predictions=instances_)
预测模型返回筛选后实例
上面只是在绘制预测结果的进行了阈值筛选,在使用 Detectron2 框架下的评估脚本时,必须让模型返回筛选后的实例才行,否则还是返回 100 个实例,这样无法准确评估模型。
我将上面的脚本迁移到了 mask2former/maskformer_model.py
中,在脚本中设置自己需要的阈值即可,读者也可以自己添加一个阈值参数到配置文件中,然后在模型代码中读入这个阈值参数。具体代码实现如下:
def instance_inference(self, mask_cls, mask_pred):# mask_pred is already processed to have the same shape as original inputimage_size = mask_pred.shape[-2:]# [Q, K]scores = F.softmax(mask_cls, dim=-1)[:, :-1]labels = torch.arange(self.sem_seg_head.num_classes, device=self.device).unsqueeze(0).repeat(self.num_queries, 1).flatten(0, 1)# scores_per_image, topk_indices = scores.flatten(0, 1).topk(self.num_queries, sorted=False)scores_per_image, topk_indices = scores.flatten(0, 1).topk(self.test_topk_per_image, sorted=False)labels_per_image = labels[topk_indices]topk_indices = topk_indices // self.sem_seg_head.num_classes# mask_pred = mask_pred.unsqueeze(1).repeat(1, self.sem_seg_head.num_classes, 1).flatten(0, 1)mask_pred = mask_pred[topk_indices]# if this is panoptic segmentation, we only keep the "thing" classesif self.panoptic_on:keep = torch.zeros_like(scores_per_image).bool()for i, lab in enumerate(labels_per_image):keep[i] = lab in self.metadata.thing_dataset_id_to_contiguous_id.values()scores_per_image = scores_per_image[keep]labels_per_image = labels_per_image[keep]mask_pred = mask_pred[keep]result = Instances(image_size)# mask (before sigmoid)result.pred_masks = (mask_pred > 0).float()result.pred_boxes = Boxes(torch.zeros(mask_pred.size(0), 4))# Uncomment the following to get boxes from masks (this is slow)# result.pred_boxes = BitMasks(mask_pred > 0).get_bounding_boxes()# calculate average mask probmask_scores_per_image = (mask_pred.sigmoid().flatten(1) * result.pred_masks.flatten(1)).sum(1) / (result.pred_masks.flatten(1).sum(1) + 1e-6)result.scores = scores_per_image * mask_scores_per_imageresult.pred_classes = labels_per_image# # 如果是实例分割,只保留大于阈值的if self.instance_on:import numpy as npimport cv2instances_ = Instances(image_size)instances = result.to(torch.device("cpu"))flag = Falsefor index in range(len(instances)):if instances[index].scores[0] > 0.9:mask = torch.squeeze(instances[index].pred_masks).numpy()*255mask = np.array(mask, np.uint8) # 类型转换后才能输入查找轮廓contours, hierachy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)areas = []for cnt in contours:areas.append(cv2.contourArea(cnt))for cnt in contours:if cv2.contourArea(cnt) < max(areas):cv2.drawContours(mask, [cnt], contourIdx=-1, color=0, thickness=-1)mask = np.array(mask, np.float32)mask = torch.from_numpy(mask / 255.0).unsqueeze(0)if flag == False:instances_ = instances[index]masks = maskflag = Trueelse:instances_ = Instances.cat([instances_, instances[index]])masks = torch.cat((masks, mask), 0)instances_.pred_masks = masksresult = instances_return result
【实例分割|Mask2Former】 解决模型推理预测的代码中存在的一些问题相关推荐
- Python时间序列模型推理预测实战:时序推理数据预处理(特征生成、lstm输入结构组织)、模型加载、模型预测结果保存、条件判断模型循环运行
Python时间序列模型推理预测实战:时序推理数据预处理(特征生成.lstm输入结构组织).模型加载.模型预测结果保存.条件判断模型循环运行 目录
- Python基于statsmodels包构建多元线性回归模型:模型构建、模型解析、模型推理预测
Python基于statsmodels包构建多元线性回归模型:模型构建.模型解析.模型推理预测 目录
- 化学实验室自动化 - 1. 深度学习视觉检测(实例分割) - Mask-RCNN模型训练和预测
在上一篇文章中,我们完成了化学实验室常见物体的COCO格式的实例分割数据集制作.上一篇文章的数据集中总共只有65张图像,而且被分成了训练集.验证集和测试集,经Mask-RCNN模型训练测试,发现模型的 ...
- 深度学习7 Transformer系列实例分割Mask2Former
文章目录 前言 正文 开源地址 安装 验证(下载对应模型) 训练 注册自定义数据集 指定训练数据集 训练 状况处理 1)显存不够 2) 3)数据集分类数与模型不一致 前言 正文 开源地址 https: ...
- 【PaddleOCR-kie】关键信息抽取1:使用VI-LayoutXLM模型推理预测(SER+RE)
背景:在训练自己数据集进行kie之前,想跑一下md里面的例程,但md教程内容混乱,而且同一个内容有多个手册,毕竟是多人合作的项目,可能是为了工程解耦,方便更新考虑--需要运行的模型和运行步骤散落在不用 ...
- 【图像分割模型】实例分割模型—DeepMask
这是专栏<图像分割模型>的第11篇文章.在这里,我们将共同探索解决分割问题的主流网络结构和设计思想. 本文介绍了用于实例分割任务的模型结构--DeepMask. 作者 | 孙叔桥 编辑 | ...
- 线性插值改变图像尺寸_【图像分割模型】实例分割模型—DeepMask
这是专栏<图像分割模型>的第11篇文章.在这里,我们将共同探索解决分割问题的主流网络结构和设计思想. 本文介绍了用于实例分割任务的模型结构--DeepMask. 作者 | 孙叔桥 编辑 | ...
- Yann LeCun等最新研究:如何对未来实例分割进行预测?
翻译 | 王柯凝 编辑 | 阿司匹林 出品 | 人工智能头条(公众号ID:AI_Thinker) [人工智能头条导读]近日,Yann LeCun 等人发表了一篇针对未来实例分割预测的论文.该论文提出了 ...
- 基于yolov7开发实践实例分割模型超详细教程
在我前面的博文中写过基于yolov5-v7.0模型开发的实例分割模型的超详细教程,即使是零基础入门的新手也都是可以按照教程步骤一步一步开发构建自己的应用.文章在下面,感兴趣的话可以自行移步阅读即可: ...
最新文章
- CMSGC造成内存碎片的解决方法
- python随机生成字符串_Python 2.6中的随机字符串(可以吗?)
- Java读取String分行字符串
- 怎样复制粘贴windows命令行中的内容
- 从对话框中传递参数到视图类
- OpenYurt 深度解读:如何构建 Kubernetes 原生云边高效协同网络?
- RuoYi-Vue 部署 Linux环境 若依前后端分离项目(jar包+nginx 多机版本)
- 资源 | 想进行数据科学项目却没有数据集?26个数据集网站汇总
- dhcp 授权的原理
- 全球首发!惯性导航导论(剑桥大学)第六部分
- php和gps终端设备通讯,运输车辆GPS定位+语音对讲通讯方案
- Javascript内置对象之Date对象与HTML BOM
- # 畸变矫正_拒绝拍照边缘畸变 坚果Pro 3 Smartisan OS v7.2.0系统体验
- qi接收启动协议_无线充电Qi通信协议分析
- linux中如何复制文件并重命名_在 Linux 上复制和重命名文件
- linux ncm网络性能优化,USB linux NCM usbnet驱动详解
- 航空维修计算机应用专业好吗,和龙口碑好的计算机应用与维修专业中专学校-可以考大专吗...
- android自定义大转盘,Android 自定义View 抽奖大转盘(1)
- 随机函数的rand、srand用法
- LED显示屏技术基本知识
热门文章
- MySQL深度分页的问题及优化方案:千万级数据量如何快速分页
- Hbase预分区与优化
- 如何建立一流的互联网产品研发体系?
- isset php 二维数组_php 一维数组按条件转换成二维数组
- 解读CRM是什么意思及其发展过程
- Medium题目总结
- Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'redis.maxIdle' in stri
- 带负荷测试要求二次最小电流_带负荷测向量简单分析方法
- 计算机科学速成课学习
- 10家企业上榜!2021“中国制造隐形冠军”完整榜单揭晓