训练yolox_nano报错:AttributeError: ‘Exp‘ object has no attribute ‘perspective‘

刚刚我成功训练了yolox_nano模型,并且成功预测,但是现在要训练yolox_nano的时候又出现了问题,我的环境配置如下文章所示:
https://blog.csdn.net/ELSA001/article/details/120918082?spm=1001.2014.3001.5501
我的训练命令如下:

python tools/train.py -f exps/example/yolox_voc/yolox_voc_nano.py -d 1 -b 4 -c weights/yolox_nano.pth

报错信息如下:

AttributeError: 'Exp' object has no attribute 'perspective'

报错图片如下:
训练yolox_nano报错:AttributeError: ‘Exp‘ object has no attribute ‘perspective‘
完整报错信息如下:

2021-10-23 19:07:10 | ERROR    | yolox.core.launch:98 - An error has been caught in function 'launch', process 'MainProcess' (53772), thread 'MainThread' (52004):
Traceback (most recent call last):

  File "tools\train.py", line 125, in <module>
    launch(
    └ <function launch at 0x000001BC0A7A8550>

> File "e:\yolox\yolox\core\launch.py", line 98, in launch
    main_func(*args)
    │          └ (╒══════════════════╤════════════════════════════════════════════════════════════════════════════════════════════════════════...
    └ <function main at 0x000001BC0C7DF0D0>

  File "tools\train.py", line 110, in main
    trainer.train()
    │       └ <function Trainer.train at 0x000001BC0BB4FC10>
    └ <yolox.core.trainer.Trainer object at 0x000001BC04BF0F10>

  File "e:\yolox\yolox\core\trainer.py", line 70, in train
    self.before_train()
    │    └ <function Trainer.before_train at 0x000001BC0C7BC9D0>
    └ <yolox.core.trainer.Trainer object at 0x000001BC04BF0F10>

  File "e:\yolox\yolox\core\trainer.py", line 145, in before_train
    self.train_loader = self.exp.get_data_loader(
    │                   │    │   └ <function Exp.get_data_loader at 0x000001BC0C7FE430>
    │                   │    └ ╒══════════════════╤═════════════════════════════════════════════════════════════════════════════════════════════════════════...
    │                   └ <yolox.core.trainer.Trainer object at 0x000001BC04BF0F10>
    └ <yolox.core.trainer.Trainer object at 0x000001BC04BF0F10>

  File "E:\YOLOX\exps/example/yolox_voc\yolox_voc_nano.py", line 90, in get_data_loader
    perspective=self.perspective,
                └ ╒══════════════════╤═════════════════════════════════════════════════════════════════════════════════════════════════════════...

AttributeError: 'Exp' object has no attribute 'perspective'

yolox_nano.pth是我在官网上面下载的,应该没事问题。

yolox_voc_nano.py文件如下:

# encoding: utf-8
import os

import torch
import torch.distributed as dist
import torch.nn as nn

from yolox.data import get_yolox_datadir
from yolox.exp import Exp as MyExp


class Exp(MyExp):
    def __init__(self):
        super(Exp, self).__init__()
        self.num_classes = 1
        self.warmup_epochs = 1
 
        self.depth = 0.33
        self.width = 0.25
        
        self.input_size = (416, 416)
        self.random_size = (10, 20)
        self.mosaic_scale = (0.5, 1.5)
        self.test_size = (416, 416)
        self.mosaic_prob = 0.5
        self.enable_mixup = False
        self.exp_name = os.path.split(os.path.realpath(__file__))[1].split(".")[0]
        
    def get_model(self, sublinear=False):

        def init_yolo(M):
            for m in M.modules():
                if isinstance(m, nn.BatchNorm2d):
                    m.eps = 1e-3
                    m.momentum = 0.03
        if "model" not in self.__dict__:
            from yolox.models import YOLOX, YOLOPAFPN, YOLOXHead
            in_channels = [256, 512, 1024]
            # NANO model use depthwise = True, which is main difference.
            backbone = YOLOPAFPN(self.depth, self.width, in_channels=in_channels, depthwise=True)
            head = YOLOXHead(self.num_classes, self.width, in_channels=in_channels, depthwise=True)
            self.model = YOLOX(backbone, head)

        self.model.apply(init_yolo)
        self.model.head.initialize_biases(1e-2)
        return self.model

    def get_data_loader(self, batch_size, is_distributed, no_aug=False, cache_img=False):
        from yolox.data import (
            VOCDetection,
            TrainTransform,
            YoloBatchSampler,
            DataLoader,
            InfiniteSampler,
            MosaicDetection,
            worker_init_reset_seed,
        )
        from yolox.utils import (
            wait_for_the_master,
            get_local_rank,
        )
        local_rank = get_local_rank()

        with wait_for_the_master(local_rank):
            dataset = VOCDetection(
                data_dir=os.path.join(get_yolox_datadir(), "VOCdevkit"),
                #image_sets=[('2007', 'trainval'), ('2012', 'trainval')],
                image_sets=[('2007', 'trainval')],
                img_size=self.input_size,
                preproc=TrainTransform(
                    max_labels=50,
                    flip_prob=self.flip_prob,
                    hsv_prob=self.hsv_prob),
                cache=cache_img,
            )

        dataset = MosaicDetection(
            dataset,
            mosaic=not no_aug,
            img_size=self.input_size,
            preproc=TrainTransform(
                max_labels=120,
                flip_prob=self.flip_prob,
                hsv_prob=self.hsv_prob),
            degrees=self.degrees,
            translate=self.translate,
            mosaic_scale=self.mosaic_scale,
            mixup_scale=self.mixup_scale,
            shear=self.shear,
            perspective=self.perspective,
            enable_mixup=self.enable_mixup,
            mosaic_prob=self.mosaic_prob,
            mixup_prob=self.mixup_prob,
        )

        self.dataset = dataset

        if is_distributed:
            batch_size = batch_size // dist.get_world_size()

        sampler = InfiniteSampler(
            len(self.dataset), seed=self.seed if self.seed else 0
        )

        batch_sampler = YoloBatchSampler(
            sampler=sampler,
            batch_size=batch_size,
            drop_last=False,
            mosaic=not no_aug,
        )

        dataloader_kwargs = {"num_workers": self.data_num_workers, "pin_memory": True}
        dataloader_kwargs["batch_sampler"] = batch_sampler

        # Make sure each process has different random seed, especially for 'fork' method
        dataloader_kwargs["worker_init_fn"] = worker_init_reset_seed

        train_loader = DataLoader(self.dataset, **dataloader_kwargs)

        return train_loader

    def get_eval_loader(self, batch_size, is_distributed, testdev=False, legacy=False):
        from yolox.data import VOCDetection, ValTransform

        valdataset = VOCDetection(
            data_dir=os.path.join(get_yolox_datadir(), "VOCdevkit"),
            image_sets=[('2007', 'test')],
            img_size=self.test_size,
            preproc=ValTransform(legacy=legacy),
        )

        if is_distributed:
            batch_size = batch_size // dist.get_world_size()
            sampler = torch.utils.data.distributed.DistributedSampler(
                valdataset, shuffle=False
            )
        else:
            sampler = torch.utils.data.SequentialSampler(valdataset)

        dataloader_kwargs = {
            "num_workers": self.data_num_workers,
            "pin_memory": True,
            "sampler": sampler,
        }
        dataloader_kwargs["batch_size"] = batch_size
        val_loader = torch.utils.data.DataLoader(valdataset, **dataloader_kwargs)

        return val_loader

    def get_evaluator(self, batch_size, is_distributed, testdev=False, legacy=False):
        from yolox.evaluators import VOCEvaluator

        val_loader = self.get_eval_loader(batch_size, is_distributed, testdev, legacy)
        evaluator = VOCEvaluator(
            dataloader=val_loader,
            img_size=self.test_size,
            confthre=self.test_conf,
            nmsthre=self.nmsthre,
            num_classes=self.num_classes,
        )
        return evaluator
上一篇:Oracle下Mybatis Batch批量操作 vs JBCD 原生batch-prepared,及各写法效率测试。


下一篇:Softmax回归的简洁实现(softmax-regression-pytorch)