yolov5训练部分

简易版

# 开始训练轮次
    for epoch in range(start_epoch,epochs):
        # 回调函数
        callbacks.run('on_train_epoch_start')
        # 设置模型为训练模式,这样模型会启用dropout和batchnormlization等训练特有的层
        model.train()
        # 初始化损失
        mloss=torch.zeros(3,device=device)

        # 清0优化器梯度
        optimizer.zero_grad()
        pbar=enumerate(train_loader)
        # 遍历每个批次
        for i,(imgs,targets,paths,_) in pbar:
            callbacks.run('on_train_batch_start')
            # 图像处理
            imgs=imgs.to(device,non_blocking=True).float()/255


        # forward
        # 上下文管理器 启用自动混合精度
        with torch.cuda.amp.autocast(amp):
            # 模型前向传播
            pred=model(imgs)
            # 计算损失
            loss,loss_items=compute_loss(pred,targets.to(device))

        # backward
        # 使用scaler 对损失值进行缩放
        scaler.scale(loss).backward()
        
        # optimizer
        # ni:当前的训练步骤 上次优化的步骤  设置的累计步数
        # 是否达到了梯度累计的标准
        if ni-last_opt_step>=accumulate:
            # 梯度从缩放状态转化为原始状态
            scaler.unscale_(optimizer)
            # 进行梯度裁剪,防止梯度爆炸 max_norm=10.0:裁剪的阈值
            torch.nn.utils.clip_grad_norm_(model.parameters(),max_norm=10.0)
            # 优化步骤
            scaler.step(optimizer)
            # 更新
            scaler.update()
            # 梯度清0,以准备下一次前向和反向传播
            optimizer.zero_grad()

日志记录表头信息

LOGGER.info(('\n' + '%11s' * 7) % ('Epoch', 'GPU_mem', 'box_loss', 'obj_loss', 'cls_loss', 'Instances', 'Size'))

(‘%11s’ * 7) 创建了一个格式字符串,表示每个字符串占 11 个字符的位置,并且重复了 7 次。

分布式训练准备

LOCAL_RANK = int(os.getenv('LOCAL_RANK', -1))  # https://pytorch.org/docs/stable/elastic/run.html
RANK = int(os.getenv('RANK', -1))
WORLD_SIZE = int(os.getenv('WORLD_SIZE', 1))
GIT_INFO = check_git_info()

断点训练Resume

def train(hyp, opt, device, callbacks):  # hyp is path/to/hyp.yaml or hyp dictionary
    save_dir, epochs, batch_size, weights, single_cls, evolve, data, cfg, resume, noval, nosave, workers, freeze = \
        Path(opt.save_dir), opt.epochs, opt.batch_size, opt.weights, opt.single_cls, opt.evolve, opt.data, opt.cfg, \
        opt.resume, opt.noval, opt.nosave, opt.workers, opt.freeze
    callbacks.run('on_pretrain_routine_start')

    # Directories
    w = save_dir / 'weights'  # weights dir
    # 如果目录已存在则不会报错(exist_ok=True),mkdir 创建目录
    (w.parent if evolve else w).mkdir(parents=True, exist_ok=True)  # make dir
    last, best = w / 'last.pt', w / 'best.pt'

    # Hyperparameters
    if isinstance(hyp, str):
        with open(hyp, errors='ignore') as f:
            hyp = yaml.safe_load(f)  # load hyps dict
    LOGGER.info(colorstr('hyperparameters: ') + ', '.join(f'{
     
     k}={
     
     v}' for k, v in hyp.items()))
    # 将超参数的副本存储在 opt.hyp 中,以便在检查点中保存
    opt.hyp = hyp.copy()  # for saving hyps to checkpoints

    # Save run settings
    if not evolve:
        yaml_save(save_dir / 'hyp.yaml', hyp)
        yaml_save(save_dir / 'opt.yaml', vars(opt))

    # Loggers
    data_dict = None
    # 如果当前进程是主进程(RANK 为 -1 或 0),则实例化日志记录器 Loggers,并传入保存目录、权重、选项、超参数和日志记录器
    if RANK in {
   
   -1, 0}:
        loggers = Loggers(save_dir, weights, opt, hyp, LOGGER)  # loggers instance

        # Register actions
        # 遍历 loggers 中的方法,并将这些方法注册为回调动作,以便在训练过程中能够调用它们
        for k in methods(loggers):
            callbacks.register_action(k, callback=getattr(loggers, k))

        # Process custom dataset artifact link
        # 从 loggers 中获取远程数据集的信息。
        data_dict = loggers.remote_dataset
        if resume:  # If resuming runs from remote artifact
            weights, epochs, hyp, batch_size = opt.weights, opt.epochs, opt.hyp, opt.batch_size

    # Config
    # plots 变量用于决定是否生成训练过程中的可视化图表。只有在不进行超参数进化且没有禁用绘图时,plots 才会为 True。
    plots = not evolve and not opt.noplots  # create plots
    cuda = device.type != 'cpu'
    # 初始化随机种子,以确保训练的可重复性。种子是根据传入的种子加上 RANK(进程标识符)生成的,deterministic=True 确保所有操作都是确定性的。
    init_seeds(opt.seed + 1 + RANK, deterministic=True)
    # 使用 torch_distributed_zero_first 上下文管理器确保在分布式训练中,只有主进程(LOCAL_RANK 为 0)会调用 check_dataset 函数检查数据集。如果 data_dict 是 None,则调用 check_dataset 来验证数据集的有效性。
    with torch_distributed_zero_first(LOCAL_RANK):
        data_dict = data_dict or check_dataset(data)  # check if None
    # 从 data_dict 中提取训练和验证数据集的路径
    train_path, val_path = data_dict['train'], data_dict['val']
    # 根据 single_cls 的值设置类别数量。如果是单类别(single_cls 为 True),则类别数量为 1;否则从 data_dict 中获取
    nc = 1 if single_cls else int(data_dict['nc'])  # number of classes
    # 如果是单类别并且 data_dict 中的名称数量不是 1,则将名称设置为 {0: 'item'};否则使用 data_dict 中的名称列表。
    names = {
   
   0: 'item'} if single_cls and len(data_dict['names'
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值