yolov8断点恢复训练及减少训练次数和增加训练次数

文章详细介绍了如何在YOLOv8模型训练过程中处理中断情况,包括两种恢复训练的方法:使用命令行工具和通过修改Python脚本。作者还分享了在代码层面如何修改`trainer.py`文件以实现断点恢复,并展示了如何减少或增加训练次数。此外,文章强调了训练完成后要将修改过的代码复原。
摘要由CSDN通过智能技术生成

1、在训练YOLOv8的时候常常可能遇到其他问题导致中断训练,由于yolov8的代码结构和yolov5有一定的差异,导致需要恢复训练和yolov5的有所不同。

第一种是按照官方给出的恢复训练代码,用yolo命令格式,这种情况必须是环境以安装了yolo和ultralytics两个包,以下是yolov8断点恢复训练:

yolo task=detect mode=train model=runs/detect/exp/weights/last.pt data=ultralytics/datasets/mydata.yaml epochs=100 save=True resume=True

第二种情况是没有安装上诉两个包,或者不用上诉两个包训练而使用python脚本训练。在ultralytics/yolo/cfg/default.yaml,把resume改成True发现并没有作用,其使用脚本恢复训练,需要更改:

from ultralytics import YOLO


model = YOLO('runs/detect/exp/weights/last.pt')
results = model.train(data="ultralytics/datasets/mydata.yaml", epochs=100, device='0', 
                      batch=8,save=True, resume=True
                     )  # 断点恢复训练模型

这样做我没有成功过,个人感觉应该是yolov8自身的bug。

2、在代码中更改达到恢复训练的效果

        2.1  在ultralytics/yolo/engine/trainer.py中找到check_resume和resume_training.

        注释check_resume中resume = self.args.resume,改成需要断点恢复的last.pt

        在resume_training里面添加一行ckpt的值

def check_resume(self):
        # resume = self.args.resume
        resume = 'runs/detect/exp/weights/last.pt';
        if resume:
            try:
                last = Path(
                    check_file(resume) if isinstance(resume, (str,
                                                              Path)) and Path(resume).exists() else get_latest_run())
                self.args = get_cfg(attempt_load_weights(last).args)
                self.args.model, resume = str(last), True  # reinstate
            except Exception as e:
                raise FileNotFoundError("Resume checkpoint not found. Please pass a valid checkpoint to resume from, "
                                        "i.e. 'yolo train resume model=path/to/last.pt'") from e
        self.resume = resume

    def resume_training(self, ckpt):
        ckpt = torch.load('runs/detect/exp/weights/last.pt')
        if ckpt is None:
            return
        best_fitness = 0.0
        start_epoch = ckpt['epoch'] + 1
        if ckpt['optimizer'] is not None:
            self.optimizer.load_state_dict(ckpt['optimizer'])  # optimizer
            best_fitness = ckpt['best_fitness']
        if self.ema and ckpt.get('ema'):
            self.ema.ema.load_state_dict(ckpt['ema'].float().state_dict())  # EMA
            self.ema.updates = ckpt['updates']
        if self.resume:
            assert start_epoch > 0, \
                f'{self.args.model} training to {self.epochs} epochs is finished, nothing to resume.\n' \
                f"Start a new training without --resume, i.e. 'yolo task=... mode=train model={self.args.model}'"
            LOGGER.info(
                f'Resuming training from {self.args.model} from epoch {start_epoch + 1} to {self.epochs} total epochs')
        if self.epochs < start_epoch:
            LOGGER.info(
                f"{self.model} has been trained for {ckpt['epoch']} epochs. Fine-tuning for {self.epochs} more epochs.")
            self.epochs += ckpt['epoch']  # finetune additional epochs
        self.best_fitness = best_fitness
        self.start_epoch = start_epoch

ps:查看博客有的说需要把ultralytics/yolo/engine/model.py中的self.trainer.model = self.model注释掉,其实不需要。因为原版的model.py没有这一句,原版是下面注释掉的三句,其原因是在运行训练脚本时如果不注释 if not overrides.get('resume') 语句会导致终端打印两次网络结构。

如下:

    def train(self, **kwargs):
        """
        Trains the model on a given dataset.

        Args:
            **kwargs (Any): Any number of arguments representing the training configuration.
        """
        self._check_is_pytorch_model()
        if self.session:  # Ultralytics HUB session
            if any(kwargs):
                LOGGER.warning('WARNING ⚠️ using HUB training arguments, ignoring local training arguments.')
            kwargs = self.session.train_args
        check_pip_update_available()
        overrides = self.overrides.copy()
        overrides.update(kwargs)
        if kwargs.get('cfg'):
            LOGGER.info(f"cfg file passed. Overriding default params with {kwargs['cfg']}.")
            # overrides = yaml_load(check_yaml(kwargs['cfg']))
            overrides = yaml_load(check_yaml(kwargs['cfg']), append_filename=False) ################
        overrides['mode'] = 'train'
        if not overrides.get('data'):
            raise AttributeError("Dataset required but missing, i.e. pass 'data=coco128.yaml'")
        if overrides.get('resume'):
            overrides['resume'] = self.ckpt_path
        self.task = overrides.get('task') or self.task
        self.trainer = TASK_MAP[self.task][1](overrides=overrides, _callbacks=self.callbacks)
        # if not overrides.get('resume'):  # manually set model only if not resuming
        #     self.trainer.model = self.trainer.get_model(weights=self.model if self.ckpt else None, cfg=self.model.yaml)
        #     self.model = self.trainer.model
        ############################
        self.trainer.model = self.model
        #############################
        self.trainer.hub_session = self.session  # attach optional HUB session
        self.trainer.train()
        # Update model and cfg after training
        if RANK in (-1, 0):
            self.model, _ = attempt_load_one_weight(str(self.trainer.best))
            self.overrides = self.model.args
            self.metrics = getattr(self.trainer.validator, 'metrics', None)  # TODO: no metrics returned by DDP

        2.2 完成上诉两个地方,直接运行python训练脚本就行,比如我这里直接运行之前的训练脚本:

from ultralytics import YOLO


model = YOLO('ultralytics/models/v8/yolov8s.yaml')

results = model.train(data="ultralytics/datasets/mydata.yaml", epochs=200, device='0', 
                      batch=8,
                     )  # 训练模型

运行结果如下:

Resuming training from runs/detect/exp/weights/last.pt from epoch 96 to 200 total epochs
Image sizes 640 train, 640 val
Using 8 dataloader workers
Logging results to runs/detect/exp
Starting training for 200 epochs...

      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size
     96/200      5.39G     0.7552     0.4572      1.052         52        640: 100%|██████████| 605/605 [01:47<00:00,  5.61it/s]
                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 76/76 [00:09<00:00,  7.78it/s]
                   all       1209      13079      0.893      0.899      0.954      0.793

      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size
     97/200      4.29G     0.7519     0.4552      1.058        169        640:  12%|█▏        | 75/605 [00:11<01:24,  6.26it/s]^C

3、改变yolov8的训练次数

        3.1 减少训练次数

        在ultralytics/yolo/engine/trainer.py中找到self.epochs = self.args.epochs,把self.epochs 给成自己需要的次数。如下是把原本的200次训练减少到100次训练。

        self.batch_size = self.args.batch
        # self.epochs = self.args.epochs
        self.epochs = 100
        self.start_epoch = 0
        if RANK == -1:
            print_args(vars(self.args))

        # Device
        if self.device.type == 'cpu':
            self.args.workers = 0  # faster CPU training as time dominated by inference, not dataloading

        然后再根据上诉2中恢复训练的步骤,运行训练脚本即可,self.epochs减少到100次训练结果如下:

Resuming training from runs/detect/exp/weights/last.pt from epoch 97 to 100 total epochs
Image sizes 640 train, 640 val
Using 8 dataloader workers
Logging results to runs/detect/orange6000_small
Starting training for 100 epochs...

      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size
     97/100      5.39G     0.7219      0.428      1.032         52        640: 100%|██████████| 605/605 [01:49<00:00,  5.52it/s]
                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 76/76 [00:09<00:00,  7.64it/s]
                   all       1209      13079      0.893      0.897      0.952      0.792

      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size
     98/100      5.13G     0.7404       0.44      1.041         75        640: 100%|██████████| 605/605 [01:50<00:00,  5.49it/s]
                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 76/76 [00:09<00:00,  7.95it/s]
                   all       1209      13079      0.898      0.893      0.953      0.791

      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size
     99/100       4.6G      0.728     0.4323       1.04        110        640: 100%|██████████| 605/605 [01:48<00:00,  5.57it/s]
                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 76/76 [00:09<00:00,  7.74it/s]
                   all       1209      13079      0.898      0.894      0.953      0.793

      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size
    100/100       6.1G     0.7311     0.4284      1.033        112        640: 100%|██████████| 605/605 [01:47<00:00,  5.61it/s]
                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 76/76 [00:17<00:00,  4.40it/s]
                   all       1209      13079      0.898      0.894      0.954      0.793

4 epochs completed in 0.136 hours.

        3.2 增加训练次数

        如果需要增加训练次数把self.epochs改成自己需要的次数,比如以下是200次恢复训练,需要提高到300次。

Resuming training from runs/detect/orange6000/weights/last.pt from epoch 4 to 200 total epochs
Image sizes 640 train, 640 val
Using 8 dataloader workers
Logging results to runs/detect/orange6000_small
Starting training for 200 epochs...

      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size
      4/200      5.39G       2.45      2.368      2.909         52        640: 100%|██████████| 605/605 [02:55<00:00,  3.44it/s]
                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 76/76 [00:17<00:00,  4.29it/s]
                   all       1209      13079       0.65      0.658       0.69       0.41

      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size
      5/200      3.36G      1.691      1.489      1.941        163        640:   1%|          | 7/605 [00:01<01:57,  5.09it/s]^C

        把self.epochs改成self.epochs=300即可,结果如下:

Resuming training from runs/detect/orange6000/weights/last.pt from epoch 5 to 300 total epochs
Image sizes 640 train, 640 val
Using 8 dataloader workers
Logging results to runs/detect/orange6000_small
Starting training for 300 epochs...

      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size
      5/300       4.9G      3.447      4.066      4.216        112        640:  14%|█▍        | 86/605 [00:25<02:31,  3.43it/s]^C

最后,重要的事说3遍。

训练完成后把ultralytics/yolo/engine/trainer.py代码复原!!!
训练完成后把ultralytics/yolo/engine/trainer.py代码复原!!!
训练完成后把ultralytics/yolo/engine/trainer.py代码复原!!!

### 回答1: yolov5 last.pt和best.pt是YOLOv5模型训练过程中保存的两个模型文件。其中last.pt是最后一次训练的模型文件,而best.pt则是在训练过程中表现最好的模型文件。这两个文件可以用于模型的推理和继续训练。 ### 回答2: YOLOv5模型训练过程中,通常会生成两个重要的模型参数文件:last.pt和best.pt。这两个文件对于模型的迭代和性能提升都有很大的帮助。 首先,last.pt文件是指训练最后一步(最新的)的模型参数。这个文件通常是在完整训练期间或者从上次训练恢复时生成的。因为YOLOv5是一个迭代的过程,每个epoch会对模型进行一次更新,从而不断提高模型的性能。因此,last.pt支持我们从上次训练的checkpoint开始,继续训练模型。 接下来,best.pt文件则是指在训练过程中性能最好的模型参数。训练过程中,模型在验证集上的表现会被不断地评估,如果表现更好,就会保存该模型的参数为best.pt。这个文件可以用于后续的fine-tuning或者在实际应用中进行推断。 总的来说,last.pt和best.pt文件都是非常重要的模型参数文件。它们提供了保存模型训练状态的机制,并能够在下一轮迭代和fine-tuning中继续训练模型。同时,best.pt文件也是能够提供最佳模型参数的参考,对于实际应用中的推断任务更为重要。 ### 回答3: yolov5模型是一种目标检测模型,其主要特点是使用单阶段检测(One-Stage Detection)的方法,在速度和准确性上均有较好的表现。在训练yolov5模型的过程中,我们使用的是深度学习框架PyTorch,同时选择了一些标准的数据集,如COCO和Pascal VOC等,来训练模型。 在yolov5模型的训练过程中,我们会得到两个重要的检测权重文件,即last.pt和best.pt。这两个文件都包含了训练好的模型参数,可以用于后续的模型推理和测试。 last.pt文件是指最后一次训练所保存下来的权重文件。这个文件记录了模型最后一次的训练结果,可以说是模型训练的最新状态。因为我们在训练过程中通常会进行多次迭代,每次迭代都会得到新的权重,所以last.pt文件保存的是最后一次迭代的权重,它可能还没有收敛到最优的状态,但是可以用于继续训练或者进行模型推理。 best.pt文件是指整个训练过程中保存下来的最佳权重文件。在训练过程中,我们会通过监测模型在验证集上的表现,来决定保存当前训练过程中表现最好的模型权重。best.pt文件包含了模型在整个训练过程中表现最好的权重,它通常被用于最终的模型测试和部署。 在使用yolov5模型进行目标检测时,我们可以选择使用last.pt或者best.pt文件作为模型的权重。如果我们需要继续进行模型训练,就可以使用last.pt文件。如果我们需要进行模型测试或者部署,就可以使用best.pt文件。
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值