DETR实现目标检测(一)-训练自己的数据集

news2024/11/15 17:32:09

1、DETR架构

DETR(Detection Transformer)是一种新型的目标检测模型,由Facebook AI Research (FAIR) 在2020年提出。DETR的核心思想是将目标检测任务视为一个直接的集合预测问题,而不是传统的两步或多步预测问题。这种方法的创新之处在于它直接预测目标的类别和边界框,而不是先生成大量的候选区域,然后再对这些区域进行分类和边界框回归。

DERT的特点主要有二:

一是Transformer结构在CV网络中的应用;

二是提出了一种新的或者说不同的损失函数(Loss Function)。

2、模型下载

模型代码下载地址:

GitHub - facebookresearch/detr: End-to-End Object Detection with Transformers

预训练模型(即权重文件)下载地址:

GitHub - facebookresearch/detr: End-to-End Object Detection with Transformers

下载后放到项目下待使用:

3、labelme标注文件转为coco模式

首先,labelme标注的文件存放在指定位置,包含json和jpg文件

然后,利用代码将labelme的标注文件转化为coco。包含annotations(两个json文件)、train2017(训练集图片)、val2017(验证集图片)

备注:必须严格按照笔者图中的文件命名方式进行命名,训练集清一色命名为instances_train2017.json,验证集清一色命名为instances_val2017.json,这是模型本身的命名要求,用户需要严格遵守。

实现代码如下:

import json
from labelme import utils
import numpy as np
import glob
import PIL.Image


class MyEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, np.integer):
            return int(obj)
        elif isinstance(obj, np.floating):
            return float(obj)
        elif isinstance(obj, np.ndarray):
            return obj.tolist()
        else:
            return super(MyEncoder, self).default(obj)


class labelme2coco(object):
    def __init__(self, labelme_json=[], save_json_path='./tran.json'):
        self.labelme_json = labelme_json
        self.save_json_path = save_json_path
        self.images = []
        self.categories = []
        self.annotations = []
        # self.data_coco = {}
        self.label = []
        self.annID = 1
        self.height = 0
        self.width = 0

        self.save_json()

    def data_transfer(self):

        for num, json_file in enumerate(self.labelme_json):
            with open(json_file, 'r') as fp:
                data = json.load(fp)  # 加载json文件
                self.images.append(self.image(data, num))
                for shapes in data['shapes']:
                    label = shapes['label']
                    if label not in self.label:
                        self.categories.append(self.categorie(label))
                        self.label.append(label)
                    points = shapes['points']  # 这里的point是用rectangle标注得到的,只有两个点,需要转成四个点
                    points.append([points[0][0], points[1][1]])
                    points.append([points[1][0], points[0][1]])
                    self.annotations.append(self.annotation(points, label, num))
                    self.annID += 1

    def image(self, data, num):
        image = {}
        img = utils.img_b64_to_arr(data['imageData'])  # 解析原图片数据
        height, width = img.shape[:2]
        image['height'] = height
        image['width'] = width
        image['id'] = num + 1
        image['file_name'] = data['imagePath'].split('/')[-1]

        self.height = height
        self.width = width

        return image

    def categorie(self, label):
        categorie = {}
        categorie['supercategory'] = 'Cancer'
        categorie['id'] = len(self.label) + 1  # 0 默认为背景
        categorie['name'] = label
        return categorie

    def annotation(self, points, label, num):
        annotation = {}
        annotation['segmentation'] = [list(np.asarray(points).flatten())]
        annotation['iscrowd'] = 0
        annotation['image_id'] = num + 1
        annotation['bbox'] = list(map(float, self.getbbox(points)))
        annotation['area'] = annotation['bbox'][2] * annotation['bbox'][3]
        annotation['category_id'] = self.getcatid(label)  # 注意,源代码默认为1
        annotation['id'] = self.annID
        return annotation

    def getcatid(self, label):
        for categorie in self.categories:
            if label == categorie['name']:
                return categorie['id']
        return 1

    def getbbox(self, points):
        polygons = points
        mask = self.polygons_to_mask([self.height, self.width], polygons)
        return self.mask2box(mask)

    def mask2box(self, mask):
        """从mask反算出其边框
        mask:[h,w]  0、1组成的图片
        1对应对象,只需计算1对应的行列号(左上角行列号,右下角行列号,就可以算出其边框)
        """
        # np.where(mask==1)
        index = np.argwhere(mask == 1)
        rows = index[:, 0]
        clos = index[:, 1]
        # 解析左上角行列号
        left_top_r = np.min(rows)  # y
        left_top_c = np.min(clos)  # x

        # 解析右下角行列号
        right_bottom_r = np.max(rows)
        right_bottom_c = np.max(clos)

        return [left_top_c, left_top_r, right_bottom_c - left_top_c,
                right_bottom_r - left_top_r]  # [x1,y1,w,h] 对应COCO的bbox格式

    def polygons_to_mask(self, img_shape, polygons):
        mask = np.zeros(img_shape, dtype=np.uint8)
        mask = PIL.Image.fromarray(mask)
        xy = list(map(tuple, polygons))
        PIL.ImageDraw.Draw(mask).polygon(xy=xy, outline=1, fill=1)
        mask = np.array(mask, dtype=bool)
        return mask

    def data2coco(self):
        data_coco = {}
        data_coco['images'] = self.images
        data_coco['categories'] = self.categories
        data_coco['annotations'] = self.annotations
        return data_coco

    def save_json(self):
        self.data_transfer()
        self.data_coco = self.data2coco()
        # 保存json文件
        json.dump(self.data_coco, open(self.save_json_path, 'w'), indent=4, cls=MyEncoder)  # indent=4 更加美观显示


if __name__ == '__main__':
    labelme_json = glob.glob('data/LabelmeData_frame_count/val2017/*.json')  # labelme标注好的.json文件存放目录
    labelme2coco(labelme_json, 'data/coco_frame_count/annotations/instances_val2017.json')  # 输出结果的存放目录

4、修改训练模型参数

先在pycharm中新建python脚本文件detr_r50_tf.py,代码如下:

import torch

pretrained_weights = torch.load('detr-r50-e632da11.pth')

num_class = 1  # 类别数
pretrained_weights["model"]["class_embed.weight"].resize_(num_class + 1, 256)
pretrained_weights["model"]["class_embed.bias"].resize_(num_class + 1)
torch.save(pretrained_weights, "detr-r50_%d.pth" % num_class)

将其中类别数改成自己数据集的类别数即可,执行完成后会在目录下生成适合自己数据集类别的预训练模型:

然后在models文件夹下打开detr.py,修改其中的类别数(一定要全部保持一致):

最后打开main.py,修改其中的coco_path(数据存放路径)、output_dir(结果输出路径)、device(没有cuda就改为cpu)、resume(自己生成的预训练模型)。

5、执行main.py来开始训练模型

如果不想跑太多了轮可以修改epochs数:

训练好的模型会保存在结果输出路径中:

跑起来的效果是这样的:

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

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

相关文章

WebGIS开发:你还在纠结的10大问题合集!

问题1:GIS开发到底是学Java还是Python? Java是后端语言,Python更重数据分析和算法。 假设通常说的GIS开发是指Webgis,Web就是指网页端,所以我们说的GIS开发大部分情况下是指网页端的地图可视化开发。 GIS开发需要学…

使用MySQL全文索引实现高效搜索功能

MySQL全文索引是MySQL提供的一种高效的搜索功能,可以快速地搜索文本内容。全文索引可以用于搜索大量文本数据,通常应用在文章、博客、论坛等需要搜索的场景中。 什么是MySQL全文索引 MySQL全文索引是一种用于快速搜索文本内容的索引技术。它可以在存储和…

积累和消耗,人生本质的两件事

人生的本质其实就两件事,消耗和积累。 纵观你身边所有的人,他们做的所有的事,基本都可以分为两类。 一、积累 二、消耗 比如说感情,在我们每一个人的青春回忆里,都或多或少有一段刻骨铭心的感情,有些人的感…

编辑并保存hosts文件

1.以管理员权限打开cmd 2.执行命令 notepad C:\Windows\System32\drivers\etc\hosts 回车后会通过记事本打开hosts文件,然后就可以编辑并保存了。

bat脚本—快速修改网络配置

一、bat编写前注意事项 windows桌面用文本文件打开把批命令输入在文本框中,保存采用ANSI编码,后缀用.bat 可参考博客——bat脚本简介学习原理以及具体创建方式 (文件扩展名位置) 语法准确性:严格遵循 BAT 脚本的语…

零一科技Yi-VL 6B视觉大模型环境搭建推理

引子 最近看新闻博客说零一科技的Yi-VL-Plus视觉大模型效果很不错,那就想着尝尝鲜。这是第四篇关于视觉大模型的博客。之前有写过一篇零一科技的chat大模型零一科技Yi-34B Chat大模型环境搭建&推理_python部署大模型yi-34b-chat-CSDN博客,感兴趣的童…

【Gitlab】访问默认PostgreSQL数据库

本地访问PostgreSQL gitlab有可以直接访问内部PostgreSQL的命令 sudo gitlab-rails dbconsole # 或者 sudo gitlab-psql -d gitlabhq_production效果截图 常用SQL # 查看用户状态 select id,name,email,state,last_sign_in_at,updated_at,last_credential_check_at,last_act…

Visual Studio Code的安装与配置

Visual Studio Code(简称 VS Code)是 Microsoft 在2015年4月30日 Build 开发者大会上正式宣布一个运行于 Mac OS X、Windows和 Linux 之上的,针对于编写现代 Web 和云应用的跨平台源代码编辑器,可在桌面上运行,并且可用…

在Lua解释器中注册自定义函数

本文目录 1、引言2、函数注册2.1注册原理 2.2 注册函数 3、实操3.1 编写注册函数3.2编写测试代码 4、结论 文章对应视频教程: 暂无,可以关注我的B站账号等待更新。 点击图片或链接访问我的B站主页~~~ 1、引言 在之前的博客中,已经介绍了如何…

JEPaaS 低代码平台 j_spring_security_check SQL注入漏洞复现

0x01 产品简介 JEPaaS是一款优秀的软件平台产品,可视化开发环境,低代码拖拽式配置开发,操作极其简单,可以帮助解决Java项目80%的重复工作,让开发更多关注业务逻辑,大大提高开发效率,能帮助公司大幅节省人力成本和时间成本,同时又不失灵活性。适用于搭建 OA、ERP、CRM、…

基于WPF技术的换热站智能监控系统07--实现左侧数据报表

1、区域划分 2、UI布局 LiveCharts是一个比较漂亮的WPF图表控件,在数据变化时还会有动画切换的效果,并且样式也可以控制。 Values:数据值 Fill:填充颜色 StrokeThickness:粗细 LabelPosition:标签位置 3、运行效果 走过路过不…

便携式EL检测仪:高效便捷的太阳能组件光伏EL检测设备

TH-EL2随着全球对可再生能源的日益重视,太阳能作为清洁、可再生的能源形式,受到了广泛的关注和应用。太阳能光伏组件作为太阳能发电系统的核心部件,其质量直接关系到整个系统的发电效率和寿命。因此,对太阳能光伏组件进行高效、准…

网格细分技术在AI绘画中的革新应用

导语: 随着人工智能技术的不断突破,艺术创作也迈入了一个新的时代。AI绘画不仅为艺术家提供了新的工具和灵感源泉,还极大地扩展了艺术的边界。在这背后,网格细分技术扮演着至关重要的角色,它通过将画面划分为数以万计的…

FlowUs本地部署:数据自主权与定制化服务的完美融合|FlowUs息流企业级解决方案本地私有化部署|FlowUs本地部署保证客户数据安全

在当今数字化时代,企业对数据的控制和安全性要求越来越高,同时,用户对软件的使用习惯也趋向多样化。针对这些需求,FlowUs作为一款多功能的协作平台,提供了灵活的解决方案。 FlowUs本地部署 对于有本地化需求的客户&a…

人工智能代理:关键概念及如何克服LLM限制

人工智能代理是一种自主软件实体,通常用于增强大型语言模型。以下是开发人员需要了解的内容。 随着大型语言模型 (LLM) 变得更加强大,一种被称为“代理”的新型软件应运而生,以增强和提升 LLM 的能力。本文介绍了代理的关键概念以及它们如何…

【Mac】精通或死亡Spellz Mastery or Death(角色扮演游戏))游戏介绍

前言 今天给大家介绍一款游戏,《精通或死亡Spellz Mastery or Death for mac》(角色扮演游戏) 。 游戏介绍 《精通或死亡:Spellz Mastery or Death》是一款以魔法为核心的策略角色扮演游戏(RPG),玩家在游戏中需要掌…

干货分享:宏集物联网HMI通过S7 MPI协议采集西门子400PLC数据

前言 为了实现和西门子PLC的数据交互,宏集物联网HMI集成了S7 PPI、S7 MPI、S7 Optimized、S7 ETH等多个驱动来适配西门子200、300、400、1200、1500、LOGO等系列PLC。 本文主要介绍宏集HMI通过S7 MPI协议采集西门子400PLC数据的操作步骤,其他协议的操作…

​揭秘Grok大模型:未来AI的无限可能

🚀 大家好,今天我们要带大家走进一个充满未来科技感的世界,探秘一款备受瞩目的大模型——Grok! 一、Grok背后的神秘力量 Grok,这个名字可能对于大多数人来说还是陌生的,但它背后的公司——xAI&#xff0c…

3D线扫相机中的深度数据与激光反射强度数据获取及其应用

1. 引言 3D线扫相机(3D line scan camera)是一种高精度的三维测量设备,广泛应用于工业自动化、质量控制和精密测量等领域。与传统二维成像相机不同,3D线扫相机能够同时获取物体的深度信息和反射强度信息,从而为高精度…

【小白学Python】自定义图片的生成(二)

Python学习 【小白学Python】自定义图片的生成(一) 目录 1. 文件内容2.生成图片规则3. 修改代码2.1 尝试一行汉字展示3.1 读取txt文件3.2 解决文字过长问题3.3 删减指定文字 4. 总结 1. 文件内容 正如上篇文章所说,我需要读取txt文件的文字内…