yolov4项目模型的一些bug修改方法

yolo v4的模型所面临的一些bug和方法

项目地址
https://github.com/Tianxiaomo/pytorch-YOLOv4

yolov4_new all processes
下面是可能遇到的各种问题
当然现在还有一些问题需要解决


模型需要的训练和测试的标注文件不是json,而是txt文件,文件格式在上面的项目中有介绍,作者也提供了一个代码tool/dataset.py 把yolo转txt

  • 根据转好的txt文件,需要修改cfg.py大约59行的代码使其对应到标注文件
  • 注意模型的训练权重文件会默认保存在base_dir下的checkpoints中
Cfg.train_label = os.path.join(_BASE_DIR, 'train_yolov4_4_355.txt')
Cfg.val_label = os.path.join(_BASE_DIR, 'train_yolov4_4_355.txt')

  • 为了更好的修改,我们需要在cfg目录下新建yolov4_{dataset}.py文件夹,复制cfg/yolov4.cfg
  • ctrl+r 把所有的classes=80 改为classes={your_dataset_classes_nums}
classes=4

  • 在cfg.py中,需要修改大约第20行的代码,否则会报错维度问题
    shape [1,3,29,76,76] is invalid for input of size 1472880
Cfg.use_darknet_cfg = False

  • 在dataset.py中,需要插入一行新代码,大概在141行,hsv创建出来后是一个tuple,不能进行修改,所以需要转list
hsv=list(hsv)
hsv[1] *= dsat
hsv[2] *= dexp
hsv[0] += 179 * dhue

  • 为了加入fusion_factor,只需要把models.py中Neck部分forward函数中每一个up变量*0.5,up出现两次所以要做两次如下操作
up = self.upsample1(x7, downsample4.size(), self.inference) * 0.5

  • 转om模型 后无法测试,需要改变models.py中line 400代码Yolov4Head-forward()如下(注释的是原本的)
  • 需要注意的是这一步代码改变后模型将不能使用pytorch测试,所以请在最后转onnx前改一下即可,然后再改回来
  • 由于pytorch无法测试,所以转onnx前必须把demo_pytorch2onnx.py line81行的——detect(session,image_src,name_file)注释
        if self.inference:
            # y1 = self.yolo1(x2)
            # y2 = self.yolo2(x10)
            # y3 = self.yolo3(x18)
            #
            # return get_region_boxes([y1, y2, y3])
            return [x18, x10, x2]
        else:
            return [x2, x10, x18]

  • 之前模型是每一轮都测试,这非常浪费时间,按照如下修改train.py line416行左右,具体的修改步骤是把测试的一些东西放在if下面
  • 为了给模型传入interval参数,需要修改train.py get_args(**kwargs) parser.add_argument('-interval', dest='interval', type=int, default=10, help='interval between train and val')
            if (epoch + 1) % config.interval == 0:
                if cfg.use_darknet_cfg:
                    eval_model = Darknet(cfg.cfgfile, inference=True)
                else:
                    eval_model = Yolov4(cfg.pretrained, n_classes=cfg.classes, inference=True)
                # eval_model = Yolov4(yolov4conv137weight=None, n_classes=config.classes, inference=True)
                if torch.cuda.device_count() > 1:
                    eval_model.load_state_dict(model.module.state_dict())
                else:
                    eval_model.load_state_dict(model.state_dict())
                eval_model.to(device)

                evaluator = evaluate(eval_model, val_loader, config, device)
                del eval_model

                stats = evaluator.coco_eval['bbox'].stats
                writer.add_scalar('train/AP', stats[0], global_step)
                writer.add_scalar('train/AP50', stats[1], global_step)
                writer.add_scalar('train/AP75', stats[2], global_step)
                writer.add_scalar('train/AP_small', stats[3], global_step)
                writer.add_scalar('train/AP_medium', stats[4], global_step)
                writer.add_scalar('train/AP_large', stats[5], global_step)
                writer.add_scalar('train/AR1', stats[6], global_step)
                writer.add_scalar('train/AR10', stats[7], global_step)
                writer.add_scalar('train/AR100', stats[8], global_step)
                writer.add_scalar('train/AR_small', stats[9], global_step)
                writer.add_scalar('train/AR_medium', stats[10], global_step)
                writer.add_scalar('train/AR_large', stats[11], global_step)

  • train.py line 211 .contiguous() to make view not lead to error
pred_ious = bboxes_iou(pred[b].contiguous().view(-1, 4), truth_box, xyxy=False)

  • 这里推荐把train.py中大概500行get_args(**kwargs)中的parser.add_argument(‘-val_label_path’, dest=‘val_label’, type=str, default=‘train.txt’)给注释掉,这样就默认使用我们前面修改的yolov4_{dataset}.cfg中的训练和测试标注
  • train.py line 326 add val label path这样还能看到测试集
    logging.info(f'''Starting training:
        Epochs:          {
      
      epochs}
        Batch size:      {
      
      config.batch}
        Subdivisions:    {
      
      config.subdivisions}
        Learning rate:   {
      
      config.learning_rate}
        Training size:   {
      
      n_train}
        Validation size: {
      
      n_val}
        Checkpoints:     {
      
      save_cp}
        Device:          {
      
      device.type}
        Images size:     {
      
      config.width}
        Optimizer:       {
      
      config.TRAIN_OPTIMIZER}
        Dataset classes: {
      
      config.classes}
        Train label path:{
      
      config.train_label}
        
        Val label path:  {
      
      config.val_label}
        
        Pretrained:
    ''')

  • 代码中提供的保存模型的方法是错误的,需要train.py line 454 model.module.state_dict() to save torch.nn.DataParallel model
                if isinstance(model, torch.nn.DataParallel):
                    torch.save(model.module.state_dict(), save_path)
                else:
                    torch.save(model.state_dict(), save_path)

  • 在train.py main函数中,添加一个读取模型权重的代码(你能信这玩意作者居然没写?)
  • 为了实现这个功能,需要在get_args(**kwargs) 中添加 parser.add_argument('-f', '--load', dest='load', type=str, default=None, help='Load model from a .pth file')
    if cfg.use_darknet_cfg:
        model = Darknet(cfg.cfgfile)
    else:
        model = Yolov4(cfg.pretrained, n_classes=cfg.classes)
	####################### 就是这er
    if cfg.load is not None:
        model.load_state_dict(torch.load(cfg.load))


  • 记得创一个新环境,我之前用的mmdetction就报错了cuDDN error
  • 怎么配置环境就不写了,pip install -r requirements.txt ,其他报错缺啥补啥

  • 记住,无论如何,做一个小的数据集(40张),来测试你的代码是否能跑训练和测试,不要跑完一轮训练了,才发现测试有bug

  • 我自己的gta数据集模型结果,仅供参考。

Average Precision (AP) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.107
Average Precision (AP) @[ IoU=0.50 | area= all | maxDets=100 ] = 0.269
Average Precision (AP) @[ IoU=0.75 | area= all | maxDets=100 ] = 0.057
Average Precision (AP) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.107
Average Precision (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = -1.000
Average Precision (AP) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = -1.000
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 1 ] = 0.032
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 10 ] = 0.106
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.151
Average Recall (AR) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.151
Average Recall (AR) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = -1.000
Average Recall (AR) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = -1.000

训练配置:

python train.py -l 0.001 -g 0,1 -pretrained pth/yolov4.conv.137.pth -classes 4 -dir . -interval 10

mmdeploy的项目地址,知乎的一些使用介绍

项目地址(项目地址里面有介绍文档)
但是大多数都是转成tensorrt等,而不是转成onnx这一种中间格式
github.com/open-mmlab/mmdeploy

转成onnx中间格式的方法在:
https://github.com/open-mmlab/mmdeploy/blob/master/tools/torch2onnx.py
里面有这么一句代码:
parser.add_argument(‘deploy_cfg’, help=‘deploy config path’)
这一段需要输入的是configs里面的文件
mmdeploy需要转换目标模型环境(比如转换mmdetection模型就要相应的环境)

知乎介绍和解读(共六篇,里面说的很详尽)
https://zhuanlan.zhihu.com/p/486914187

猜你喜欢

转载自blog.csdn.net/fei_YuHuo/article/details/126715254