yolov7 训练 和 tensorrt 实现

在这里插入图片描述


git:https://github.com/WongKinYiu/yolov7


Train

  1. hyp.scratch.p5.yaml

    1. mosaic : mosaic 数据增强 默认1:< 0.8 : 4张拼接 > 0.8 & < 1: 9张拼接 0: 关闭. 根据训练集选择合适的值

          def __getitem__(self, index):
              index = self.indices[index]  # linear, shuffled, or image_weights
      
              hyp = self.hyp
              mosaic = self.mosaic and random.random() < hyp['mosaic']
              if mosaic:
                  # Load mosaic
                  if random.random() < 0.8:
                      img, labels = load_mosaic(self, index)
                  else:
                      img, labels = load_mosaic9(self, index)
                  shapes = None
      
                  # MixUp https://arxiv.org/pdf/1710.09412.pdf
                  if random.random() < hyp['mixup']:
                      if random.random() < 0.8:
                          img2, labels2 = load_mosaic(self, random.randint(0, len(self.labels) - 1))
                      else:
                          img2, labels2 = load_mosaic9(self, random.randint(0, len(self.labels) - 1))
                      r = np.random.beta(8.0, 8.0)  # mixup ratio, alpha=beta=8.0
                      img = (img * r + img2 * (1 - r)).astype(np.uint8)
                      labels = np.concatenate((labels, labels2), 0)
      
    2. scale : (1 - scale) - (1+ scale): 随机缩放 根据训练集选择合适的值

          # Rotation and Scale
          R = np.eye(3)
          a = random.uniform(-degrees, degrees)
          # a += random.choice([-180, -90, 0, 90])  # add 90deg rotations to small rotations
          s = random.uniform(1 - scale, 1.1 + scale)
          # s = 2 ** random.uniform(-scale, scale)
          R[:2] = cv2.getRotationMatrix2D(angle=a, center=(0, 0), scale=s)
    
    1. anchor_t: 选取正样本 长宽比阈值
  2. data/xx.yaml 配置训练集、验证集、测试集、类别、类别名

    train: ./coco/train2017.txt  # 118287 images
    val: ./coco/val2017.txt  # 5000 images
    test: ./coco/test-dev2017.txt  # 20288 of 40670 images, submit to https://competitions.codalab.org/competitions/20794
    
    # number of classes
    nc: 80
    
    # class names
    names: [ "", ""]
    
  3. cfg/trainning/yolov7.yaml 修改nc

  4. train.py 修改对应的cfg,data, batch-size等等

  5. 模型默认保存在 run/train 下


重参化

  1. 训练后的模型,一定要重参, 否则 后期 tensorrt 推理的结果是不正确的。

  2. 官方的模型是重参后的模型,所以当后期使用tensorrt推理时,你会发现使用官方的模型,推理的结果是正确的,使用自己训练的模型,推理的结果就不正确. 我就在这挣扎了好几天,一度让我怀疑人生了。

  3. 参考:

    1. https://www.iotword.com/2642.html
    2. https://github.com/WongKinYiu/yolov7/blob/main/tools/reparameterization.ipynb
    from copy import deepcopy
    import torch.utils.data
    from models.yolo import Model
    from utils.torch_utils import select_device, is_parallel
    
    nc = 80
    anchors = 3
    device = select_device('0', batch_size=1)
    ckpt = torch.load('weights/best.pt', map_location=device)
    # reparameterized model in cfg/deploy/*.yaml
    model = Model('cfg/deploy/yolov7.yaml', ch=3, nc=5).to(device)
    # print(model)
    
    # copy intersect weights
    state_dict = ckpt['model'].float().state_dict()
    exclude = []
    intersect_state_dict = {k: v for k, v in state_dict.items() if
                            k in model.state_dict() and not any(x in k for x in exclude) and v.shape == model.state_dict()[
                                k].shape}
    model.load_state_dict(intersect_state_dict, strict=False)
    model.names = ckpt['model'].names
    model.nc = ckpt['model'].nc
    
    for i in state_dict:
        print(i)
    # print(intersect_state_dict)
    
    # reparametrized YOLOR  将yolor头部的权重赋值
    for i in range((model.nc + 5) * anchors):
        model.state_dict()['model.105.m.0.weight'].data[i, :, :, :] *= state_dict['model.105.im.0.implicit'].data[:, i,
                                                                       ::].squeeze()
        model.state_dict()['model.105.m.1.weight'].data[i, :, :, :] *= state_dict['model.105.im.1.implicit'].data[:, i,
                                                                       ::].squeeze()
        model.state_dict()['model.105.m.2.weight'].data[i, :, :, :] *= state_dict['model.105.im.2.implicit'].data[:, i,
                                                                       ::].squeeze()
    model.state_dict()['model.105.m.0.bias'].data += state_dict['model.105.m.0.weight'].mul(
        state_dict['model.105.ia.0.implicit']).sum(1).squeeze()
    model.state_dict()['model.105.m.1.bias'].data += state_dict['model.105.m.1.weight'].mul(
        state_dict['model.105.ia.1.implicit']).sum(1).squeeze()
    model.state_dict()['model.105.m.2.bias'].data += state_dict['model.105.m.2.weight'].mul(
        state_dict['model.105.ia.2.implicit']).sum(1).squeeze()
    model.state_dict()['model.105.m.0.bias'].data *= state_dict['model.105.im.0.implicit'].data.squeeze()
    model.state_dict()['model.105.m.1.bias'].data *= state_dict['model.105.im.1.implicit'].data.squeeze()
    model.state_dict()['model.105.m.2.bias'].data *= state_dict['model.105.im.2.implicit'].data.squeeze()
    
    # model to be saved
    ckpt = {'model': deepcopy(model.module if is_parallel(model) else model).half(),
            'optimizer': None,
            'training_results': None,
            'epoch': -1}
    
    # save reparameterized model
    torch.save(ckpt, 'weights/best_reparam.pt')
    
  4. 关于REP模块

    1. REP模块分为两个,一个是train,也就是训练,一个deploy,也就是推理。
      1. 训练模块,它有三个分支。最上面的分支是3x3的卷积,用于特征提取。中间的分支是1x1的卷积,用于平滑特征。最后分支是一个Identity,不做卷积操作,直接移过来。最后把它们相加在一起。
      2. 推理模块,包含一个3x3的卷积,stride(步长为1)。是由训练模块重参数化转换而来。
        在训练模块中,因为第一层是一个3x3的卷积,第二层是一个1x1的卷积,最后层是一个Identity。在模型从参数化的时候,需要把1x1的卷积啊,转换成3x3的卷积,把Identity也转换成3x3的卷积,然后进行一个矩阵的一个加法,也就是一个矩阵融合过程。
        然后最后将它的权重进行相加,就得到了一个3x3的卷积,也就是说,这三个分支就融合成了一条线,里面只有一个3x3的卷积。它们的权重是三个分支的叠加结果,矩阵,也是三个分支的叠加结果。

    在这里插入图片描述
    2. 详细参考:

    1. https://blog.csdn.net/qq128252/article/details/126673493
    2. https://blog.csdn.net/qq_41580422/article/details/126316738

Tensorrt

  1. tensorrt 实现参考: https://github.com/QIANXUNZDL123/tensorrtx-yolov7
  2. 自己训练的模型,要使用重参后的模型生成wts

END
  1. 主要记录下训练和tensorrt实现过程遇到的一些问题。
  2. 最后感谢各位大佬的杰作,respect.

在这里插入图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 首先,你需要安装 TensorRT 和其他必要的软件包。然后,按照以下步骤进行转换: 1. 将 YOLOv7 模型转换为 ONNX 格式。 2. 使用 TensorRT 的 `import_onnx_file` 函数将 ONNX 文件导入 TensorRT。 3. 使用 TensorRT 的 `create_engine` 函数将 ONNX 模型转换为 TensorRT 引擎。 4. 使用 TensorRT 引擎进行推理。 有关详细信息,请参阅 TensorRT 文档: https://docs.nvidia.com/deeplearning/tensorrt/index.html 或者你也可以参考我们的博客: https://www.leiphone.com/news/202605/a2Xs4s4x8uKjq3yG.html 希望这能帮到你。 ### 回答2: 将YOLOv7模型转化为TensorRT模型的步骤如下: 1. 准备环境:安装TensorRT和相应的依赖项,例如CUDNN、CUDA等。 2. 导出ONNX模型:使用YOLOv7模型将训练好的权重参数导出为ONNX模型。可以使用Python中的torch.onnx.export函数来实现。 3. 优化ONNX模型:使用TensorRT提供的python库trtexec来优化ONNX模型。该库可以使用命令行进行调用,根据模型的要求选择合适的优化参数。例如,可以指定精度,选择插值方式等。运行该命令后,将得到一个优化后的TensorRT模型。 4. 加载模型:使用TensorRT库将优化后的TensorRT模型加载到Python代码中。可以使用TensorRT的Python API来读取模型。 5. 创建TensorRT引擎:使用TensorRT的Python API,根据优化后的模型创建一个TensorRT引擎。引擎可以通过以下步骤创建:首先,创建一个TensorRT的builder对象;然后,使用builder对象创建一个TensorRT的network对象;最后,使用network对象创建一个TensorRT的engine对象。 6. 运行推理:使用TensorRT引擎进行推理。首先,将输入数据传递给TensorRT引擎;然后,执行推理操作;最后,从引擎中获取输出结果。 7. 后处理:根据需要,对输出结果进行后处理。例如,可以对检测结果进行过滤、解码、绘制边界框等操作。 注意:上述步骤仅为一般的转换过程,并且可能因实际情况而有所不同。具体的步骤和细节可能需要根据模型、框架和需求进行调整和修改。 ### 回答3: 将YOLOv7模型转化为TensorRT模型的步骤如下: 1. 首先,需要将YOLOv7的模型权重文件转换为TensorRT可读取的格式。可以使用YOLOv7官方提供的脚本将权重文件转化为ONNX格式或TensorRT的可读取格式。 2. 接下来,使用TensorRT提供的API加载转换后的模型。可以使用TensorRT的Python API,通过导入TensorRT库并加载模型。 3. 在加载模型后,需要指定网络的输入和输出。YOLOv7模型的输入是图像,输出是边界框的位置、类别和置信度。 4. 然后,需要为TensorRT模型设置优化器和引擎参数。可以根据应用的需求设置计算和内存资源的限制。 5. 在设置完参数后,可以开始构建TensorRT的引擎。引擎的构建过程会将模型优化为TensorRT能够高效运行的格式。 6. 构建完成后,可以将引擎持久化到磁盘上,以便以后直接加载使用。可以使用TensorRT提供的API将引擎保存为文件。 7. 最后,加载并运行TensorRT模型。通过导入TensorRT库并加载引擎,可以加载模型并对图像进行推理,得到检测结果。 总结起来,YOLOv7模型转化为TensorRT模型的主要步骤包括模型转换、加载模型、设置参数、构建引擎和存储引擎,最后加载并运行TensorRT模型进行推理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值