DEIM模型训练自己的数据集记录

DEIM模型训练自己的数据集记录

1、项目拉取,预训练模型下载

github: https://github.com/Intellindust-AI-Lab/DEIM

预训练模型选择:根据需要选择基于D-FINE或RT-DERT的DEIM模型,下面一定要修改、使用对应的模型配置文件,比如下载deim-d-fine-s模型,步骤3就要修改数据配置文件dfine-hgnetv2-s-coco.yml
在这里插入图片描述

2、配置环境

我的习惯:先创建一个虚拟环境,安装对应cuda 版本的pytorch-gpu(pytorch版本参考requirement.txt文件中要求版本),再安装其他依赖

conda create -n deim python=3.11.9
conda activate deim
pip install -r requirements.txt  (如果单独安装了pytorch,需要删除文件中的torch相关)

3、自定义数据

1)将自己的数据转换成要求的标注格式
在这里插入图片描述我的数据标注格式是yolo格式(每个图片对应一个同名的txt文件),下面是yolo转换成coco格式的脚本:

# -*- coding:utf-8 -*-
import os
import json
from tqdm import tqdm
import cv2

# 类别名
CLASS_LIST = ['B1', 'B2', 'B3', 'A1', 'A2', 'A3', 'A4', 'A5', 'A6', 'A7', 'A8', 'A9', 'A10', 'A11']

def yolo_to_coco(image_dir, txt_dir, output_json_path):
    images_dir = os.path.join(image_dir)
    labels_dir = os.path.join(txt_dir)

    if not os.path.exists(images_dir) or not os.path.exists(labels_dir):
        raise FileNotFoundError("images or labels not exist")

    categories = [{"id": i, "name": name} for i, name in enumerate(CLASS_LIST)]

    coco_data = {
        "images": [],
        "annotations": [],
        "categories": categories
    }

    image_id = 1
    annotation_id = 1
    loss_label_num = 0

    class_dict = {}
    for i in range(len(CLASS_LIST)):
        class_dict[i] = 0

    for image_name in tqdm(os.listdir(images_dir)):
        if not image_name.endswith(('.jpg', '.png', '.jpeg')):
            print(f"{image_name} not endwith jpg or png")
            continue

        image_path = os.path.join(images_dir, image_name)
        image = cv2.imread(image_path)
        height, width, _ = image.shape

        coco_data["images"].append({
            "id": image_id,
            "file_name": image_name,
            "width": width,
            "height": height
        })

        label_name = os.path.splitext(image_name)[0] + '.txt'
        label_path = os.path.join(labels_dir, label_name)
        if not os.path.exists(label_path):
            loss_label_num += 1
            image_id += 1
            print(f"{image_name} not label")
            continue

        with open(label_path, 'r') as f:
            lines = f.readlines()

        for line in lines:
            parts = line.strip().split()
            if len(parts) != 5:
                continue

            class_id, x_center, y_center, bbox_width, bbox_height = map(float, parts)
            class_id = int(class_id)
            # new_class_id = CLASS_MAPPING.get(int(class_id), None)
            if class_id is None:
                continue

            x_center *= width
            y_center *= height
            bbox_width *= width
            bbox_height *= height

            x_min = max(x_center - (bbox_width / 2),)
            y_min = max(y_center - (bbox_height / 2),)

            area = bbox_width * bbox_height

            coco_data["annotations"].append({
                "id": annotation_id,
                "image_id": image_id,
                "category_id": class_id,
                "bbox": [x_min, y_min, bbox_width, bbox_height],
                "area": area,
                "iscrowd": 0
            })

            class_dict[class_id] += 1

            annotation_id += 1

        image_id += 1

    with open(output_json_path, 'w') as f:
        json.dump(coco_data, f, indent=4)

    print(f"end saved to {output_json_path},loss label num:{loss_label_num}")
    print(class_dict)


def main(image_dir, txt_dir, output_json_dir):
    os.makedirs(output_json_dir, exist_ok=True)
    sub_dirs = os.listdir(txt_dir)
    for subfolder in sub_dirs:
        yolo_image_dir = os.path.join(image_dir, subfolder)
        yolo_txt_dir = os.path.join(txt_dir, subfolder)
        output_json = os.path.join(output_json_dir, f"{subfolder}.json")
        yolo_to_coco(yolo_image_dir, yolo_txt_dir, output_json)


if __name__ == "__main__":
    image_dir = r".\00labeled\zhenzhi20241130\images"
    txt_dir = r".\00labeled\zhenzhi20241130\labels"
    output_dir = r".\00labeled\zhenzhi20241130\annotations_14class"
    main(image_dir, txt_dir, output_dir)

2)修改数据配置文件(数据路径、标签类别,模型使用的数据配置文件路径)
在这里插入图片描述
在这里插入图片描述

4、修改配置参数:batch_size, epochs,resize_size

在这里插入图片描述
在这里插入图片描述

5、训练

在这里插入图片描述
在这里插入图片描述

6、推断

在这里插入图片描述

7、部署(onnx、tensorrt)

# 导出onnx模型
python tools/deployment/export_onnx.py --check -c configs/deim_dfine/deim_hgnetv2_${model}_coco.yml -r model.pth
# 导出tensorrt模型
trtexec --onnx=best_stg2.onnx --saveEngine=best_stg2.engine --buildOnly --minShapes=images:1x3x640x640 --optShapes=images:16x3x640x640 --maxShapes=images:32x3x640x640  --workspace=1024 --fp16

问题:
目前按照上述方法导出的onnx模型与.pt模型结果一致,tensorrt模型与onnx结果不一致,tensorrt检测框超级多,GPT分析原因可能是nms模块没有导出到tensorrt,遇到同样问题并解决的小伙伴请留言告知,感谢~

问题记录:

1、安装tensorrt之后,训练时出现下面的报错:

Could not load library libcudnn_cnn_train.so.8. Error: /usr/local/cuda-12.1/lib64/libcudnn_cnn_train.so.8: undefined symbol: _ZN5cudnn3cnn5infer22queryClusterPropertiesERPhS3_, version libcudnn_cnn_infer.so.8

原因:
具体原因是安装cuda的时候,按照教程将cudnn也安装到了系统cuda路径中,然后在python拟环境中使用pip install torch时会自动安装一个cudnn,两个发生了冲突。
解决办法
首先激活虑拟环境,使用pip list查看:
在这里插入图片描述

里面确实安装了cudnn,解决办法也很简单,既然产生了冲突,要么把系统里面的cudnn去掉(不推荐,如果部署其他的,如Tensorrt时会出现问题,反而更麻烦)。要么把虚拟环境中的cudnn去掉(推荐),所以只需要执行如下命令:

 pip uninstall nvidia-cudnn-cu12
### DEIM模型训练方法与实现 #### 训练环境配置 为了成功运行DEIM模型,需确保安装了必要的依赖项。这些依赖项包括但不限于 `torch>=2.0.1`、`torchvision>=0.15.2`、`faster-coco-eval>=1.6.5`、`PyYAML`、`tensorboard`、`scipy` 和 `transformers`[^3]。 #### 数据准备 DEIM模型通常在MS-COCO数据集上进行训练和验证。该数据集提供了丰富的标注信息,适用于目标检测任务。因此,在开始训练之前,应下载并解压MS-COCO数据集,并按照官方文档中的说明设置好目录结构[^1]。 #### 主要改进技术 DEIM的核心创新在于其引入的技术组件——Dense O2O(One-to-One Dense Matching)以及匹配感知损失(Matching-Aware Loss, MAL)。 - **Dense O2O**: 这一机制通过优化密集预测中的样本分配策略来减少冗余计算,从而降低训练成本。 - **MAL (Matching-Aware Loss)**: 此损失函数能够动态调整惩罚权重,尤其针对低质量匹配给予更多关注,进而加速模型收敛并提升最终性能[^2]。 #### 训练流程概述 以下是关于如何构建完整的训练过程的关键要点: 1. **初始化超参数**:定义学习率、批量大小和其他重要超参。例如,可以采用初始学习率为0.01,并逐步衰减的学习率调度器。 2. **加载预处理后的数据**:利用已有的工具链读取图像及其对应的边界框标签,形成适合输入网络的数据批次。 3. **搭建神经网络架构**:基于YOLO或者DETR系列的基础设计扩展出支持上述两项关键技术的新版本模型实例。 4. **指定优化算法与评价指标**:选用AdamW作为默认优化器;同时记录mAP@IoU=[0.5:0.95]等常用评测分数用于监控进展状况。 5. **执行迭代更新操作**:在一个epoch内循环完成前向传播、反向梯度累积直至参数修正环节直到满足停止条件为止。 ```python import torch from deim_model import DEIM # 假设这是自定义模块路径下的类名 from dataset_loader import COCODatasetLoader from utils.losses import MatchingAwareLoss device = 'cuda' if torch.cuda.is_available() else 'cpu' # 初始化模型及相关对象 model = DEIM().to(device) criterion = MatchingAwareLoss() optimizer = torch.optim.AdamW(model.parameters(), lr=0.001) train_dataset = COCODatasetLoader('path/to/train/images', 'annotations.json') data_loader = torch.utils.data.DataLoader(train_dataset, batch_size=8, shuffle=True) for epoch in range(num_epochs): model.train() total_loss = 0 for images, targets in data_loader: images = list(image.to(device) for image in images) targets = [{k: v.to(device) for k, v in t.items()} for t in targets] optimizer.zero_grad() outputs = model(images) loss_dict = criterion(outputs, targets) losses = sum(loss for loss in loss_dict.values()) losses.backward() optimizer.step() total_loss += losses.item() avg_loss = total_loss / len(data_loader) print(f"Epoch {epoch}, Average Loss: {avg_loss}") ``` #### 性能表现 经过充分调优后,相较于传统实时目标检测方案如原始版YOLO或DETR家族成员而言,应用了前述提到特性的DEIM能够在保持较低推理延时的同时取得更高精度的结果^。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值