yolov8逐步分解(7)_模型训练初始设置之优化器Optimizer及学习率调度器Scheduler初始化

yolov8逐步分解(1)--默认参数&超参配置文件加载

yolov8逐步分解(2)_DetectionTrainer类初始化过程

yolov8逐步分解(3)_trainer训练之模型加载

YOLOV8逐步分解(4)_模型的构建过程

YOLOV8逐步分解(5)_模型训练初始设置之混合精度训练AMP

YOLOV8逐步分解(6)_模型训练初始设置之image size检测batch预设及dataloder初始化

        接逐步分解(6),继续模型训练初始设置的讲解,本章将讲解优化器Optimizer及学习率调度器Scheduler的初始代码。

1.优化器Optimizer

关于优化器的介绍可以参考文章深度学习之优化器Optimizer介绍

        # Optimizer
        self.accumulate = max(round(self.args.nbs / self.batch_size), 1)  # accumulate loss before optimizing
        weight_decay = self.args.weight_decay * self.batch_size * self.accumulate / self.args.nbs  # scale weight_decay
        iterations = math.ceil(len(self.train_loader.dataset) / max(self.batch_size, self.args.nbs)) * self.epochs
        self.optimizer = self.build_optimizer(model=self.model,
                                              name=self.args.optimizer,
                                              lr=self.args.lr0,
                                              momentum=self.args.momentum,
                                              decay=weight_decay,
                                              iterations=iterations)

        设置优化器相关的参数。下面介绍每一行代码的作用:

1.1 self.accumulate = max(round(self.args.nbs / self.batch_size), 1):

        这一行计算梯度累积的步数。

        self.args.nbs 表示每次梯度更新前需要累积的批次数(Nominal Batch Size)。

        self.batch_size 是实际使用的批量大小。

        这个公式确保每次梯度更新前至少会累积 1 个批次。

1.2 weight_decay = self.args.weight_decay * self.batch_size * self.accumulate / self.args.nbs:

        这一行计算权重衰减(weight decay)的值。

        权重衰减是一种正则化方法,用于防止模型过拟合。

        这个公式将原始的权重衰减值 self.args.weight_decay 进行了缩放,使其与批量大小和梯度累积步数相关。

关于权重系数衰减可以参考文章深度学习之权重衰减(weight decay)介绍

1.3 iterations = math.ceil(len(self.train_loader.dataset) / max(self.batch_size, self.args.nbs)) * self.epochs:

        这一行计算总的训练迭代次数。

        它先计算每个 epoch 中的迭代次数,然后乘以总的 epoch 数。

        每个 epoch 中的迭代次数是通过将训练数据集的长度除以批量大小或 self.args.nbs 的最大值,并向上取整得到的。

1.4 self.optimizer = self.build_optimizer(model=self.model,                                        name=self.args.optimizer,  lr=self.args.lr0,                                        momentum=self.args.momentum,                                        decay=weight_decay,  iterations=iterations):

        这一行创建了优化器对象。

        它调用了 self.build_optimizer() 函数,传入了以下参数:

                model=self.model: 要优化的模型

                name=self.args.optimizer: 优化器的名称

                lr=self.args.lr0: 初始学习率

                momentum=self.args.momentum: 动量参数

                decay=weight_decay: 刚刚计算的权重衰减值

                iterations=iterations: 总的训练迭代次数

        这段代码的目的是根据一些超参数梯度累积步数,来计算出合适的权重衰减值和总的训练迭代次数,并使用这些参数创建一个优化器对象。

2. 学习率调度器Scheduler

关于学习率调度器的详细介绍可以查看文章:深度学习之学习率调度器Scheduler介绍

        # Scheduler
        if self.args.cos_lr:
            self.lf = one_cycle(1, self.args.lrf, self.epochs)  # cosine 1->hyp['lrf']
        else:
            self.lf = lambda x: (1 - x / self.epochs) * (1.0 - self.args.lrf) + self.args.lrf  # linear
        
        self.scheduler = optim.lr_scheduler.LambdaLR(self.optimizer, lr_lambda=self.lf)
        self.stopper, self.stop = EarlyStopping(patience=self.args.patience), False
        self.resume_training(ckpt) #恢复训练过程。ckpt 是一个检查点文件,用于加载之前保存的模型和训练状态。
        self.scheduler.last_epoch = self.start_epoch - 1  # do not move
        self.run_callbacks('on_pretrain_routine_end') #运行预训练过程结束时的回调函数。

学习率调度器(Scheduler)的设置。下面介绍每一行代码的作用:

2.1 if self.args.cos_lr: 和 else::

        这里根据 self.args.cos_lr 的值来决定使用余弦学习率衰减还是线性学习率衰减。

        self.lf = one_cycle(1, self.args.lrf, self.epochs) 和 self.lf = lambda x: (1 - x / self.epochs) * (1.0 - self.args.lrf) + self.args.lrf:

        这两行分别定义了两种不同的学习率调整函数 self.lf。

        第一个函数是使用 "one cycle" 策略,其中学习率从 1 逐渐降到 self.args.lrf。

        第二个函数是使用线性衰减,学习率从 1.0 逐渐降到 self.args.lrf。

2.2 self.scheduler = optim.lr_scheduler.LambdaLR(self.optimizer, lr_lambda=self.lf):

        这一行创建了一个 PyTorch 的学习率调度器对象 self.scheduler。

        它使用刚才定义的 self.lf 函数来动态调整学习率。

2.3 self.stopper, self.stop = EarlyStopping(patience=self.args.patience), False:

        这一行创建了一个 "Early Stopping" 对象 self.stopper。

        self.args.patience 是提前停止训练的等待轮数,如果验证集指标在这么多轮内都没有提升,则停止训练。

        self.stop 标志位用于指示是否应该停止训练。

2.4 self.resume_training(ckpt):

        这一行恢复之前保存的训练状态,包括模型参数和优化器状态等。

        ckpt 是一个检查点文件,包含了之前保存的训练状态。

2.5 self.scheduler.last_epoch = self.start_epoch - 1:

        这一行设置学习率调度器的当前 epoch 为上一个 epoch,因为后续训练会从 self.start_epoch 开始。

2.6 self.run_callbacks('on_pretrain_routine_end'):

        这一行运行预训练过程结束时的回调函数。

        回调函数可以用于在训练过程的不同阶段执行自定义操作。

        总的来说,这段代码设置了学习率调度器和提前停止机制,并恢复了之前保存的训练状态,最后运行了预训练过程结束时的回调函数。这些设置都是为了提高训练的效率和性能。

  • 47
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果你的代码采用了类似于`def train_one_epoch`和`def train`这样的结构,你可以在`train`函数中通过以下方式来设置动态学习率: 1. 在初始化optimizer时,设置初始学习率为一个变量,比如`init_lr`。 ```python optimizer = optim.Adam(model.parameters(), lr=init_lr, weight_decay=1e-4) ``` 2. 在每个epoch开始时,根据当前epoch的值动态更新学习率。 ```python scheduler.step(epoch) ``` 这里的`scheduler`可以使用PyTorch中的`lr_scheduler`模块中的任意一种学习率调度,比如`MultiStepLR`、`StepLR`等,它们的用法都非常相似。`epoch`表示当前训练的epoch数,每个epoch结束后,它会自动加1。 完整的代码如下: ```python def train(args, model, train_loader, test_loader, boardio, textio, checkpoint): init_lr = args.lr optimizer = optim.Adam(model.parameters(), lr=init_lr, weight_decay=1e-4) scheduler = torch.optim.lr_scheduler.MultiStepLR(optimizer, milestones=[50, 100, 150], gamma=0.1) if checkpoint is not None: min_loss = checkpoint['min_loss'] optimizer.load_state_dict(checkpoint['optimizer']) best_test_loss = np.inf best_test_mse_ab = np.inf best_test_rmse_ab = np.inf best_test_mae_ab = np.inf best_test_r_mse_ab = np.inf best_test_r_rmse_ab = np.inf best_test_r_mae_ab = np.inf best_test_t_mse_ab = np.inf best_test_t_rmse_ab = np.inf best_test_t_mae_ab = np.inf for epoch in range(args.epochs): # 动态更新学习率 scheduler.step(epoch) train_loss, train_mse_ab, train_mae_ab, train_rotations_ab, train_translations_ab, train_rotations_ab_pred, \ train_translations_ab_pred, train_eulers_ab, = train_one_epoch(args.device, model, train_loader, optimizer) test_loss, test_mse_ab, test_mae_ab, test_rotations_ab, test_translations_ab, test_rotations_ab_pred, \ test_translations_ab_pred, test_eulers_ab = test_one_epoch(args.device, model, test_loader) # 记录最佳结果 ... ``` 这样,你就可以在训练过程中动态地调整学习率了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值