MMDetection中Pointpillars训练文件代码解读

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

本文主要介绍MMDetection中Pointpillars训练文件代码,文件名为
“mmdetection3d/configs/pointpillars/pointpillars_hv_secfpn_8xb6-160e_kitti-3d-3class.py”

一、原代码

# 模型配置文件的路径
_base_ = [
    '../_base_/models/pointpillars_hv_secfpn_kitti.py',
    '../_base_/datasets/kitti-3d-3class.py',
    '../_base_/schedules/cyclic-40e.py', '../_base_/default_runtime.py'
]

# 点云的范围定义
point_cloud_range = [0, -39.68, -3, 69.12, 39.68, 1]

# 数据集设置
data_root = 'data/kitti/'  # 数据集根目录
class_names = ['Pedestrian', 'Cyclist', 'Car']  # 类别名称
metainfo = dict(classes=class_names)  # 类别信息
backend_args = None  # 后端参数

# 数据采样策略定义
db_sampler = dict(
    data_root=data_root,  # 数据集的根目录
    info_path=data_root + 'kitti_dbinfos_train.pkl',  # 数据集信息文件的路径
    rate=1.0,  # 采样率,表示采样的比例,1.0 表示全部采样

    prepare=dict(
        filter_by_difficulty=[-1],  # 根据难度过滤样本的设置,这里的-1表示不进行难度过滤
        filter_by_min_points=dict(Car=5, Pedestrian=5, Cyclist=5)  # 根据最小点数过滤样本的设置,对不同类别的物体设置了最小点数要求
    ),

    classes=class_names,  # 类别名称列表
    sample_groups=dict(Car=15, Pedestrian=15, Cyclist=15),  # 不同类别的采样组数,这里每个类别都设置了采样15次

    points_loader=dict(
        type='LoadPointsFromFile',  # 加载点云数据的方式,这里是从文件加载
        coord_type='LIDAR',  # 点云的坐标类型,LIDAR 表示激光雷达坐标
        load_dim=4,  # 加载的点云维度
        use_dim=4,  # 使用的点云维度
        backend_args=backend_args  # 后端参数
    ),
    backend_args=backend_args  # 后端参数
)


# 训练数据处理流程
train_pipeline = [
    dict(
        type='LoadPointsFromFile',
        coord_type='LIDAR',
        load_dim=4,
        use_dim=4,
        backend_args=backend_args),
    dict(type='LoadAnnotations3D', with_bbox_3d=True, with_label_3d=True),
    dict(type='ObjectSample', db_sampler=db_sampler, use_ground_plane=True),
    dict(type='RandomFlip3D', flip_ratio_bev_horizontal=0.5),
    dict(
        type='GlobalRotScaleTrans',
        rot_range=[-0.78539816, 0.78539816],
        scale_ratio_range=[0.95, 1.05]),
    dict(type='PointsRangeFilter', point_cloud_range=point_cloud_range),
    dict(type='ObjectRangeFilter', point_cloud_range=point_cloud_range),
    dict(type='PointShuffle'),
    dict(
        type='Pack3DDetInputs',
        keys=['points', 'gt_labels_3d', 'gt_bboxes_3d'])
]

# 测试数据处理流程
test_pipeline = [
    dict(
        type='LoadPointsFromFile',
        coord_type='LIDAR',
        load_dim=4,
        use_dim=4,
        backend_args=backend_args),
    dict(
        type='MultiScaleFlipAug3D',
        img_scale=(1333, 800),
        pts_scale_ratio=1,
        flip=False,
        transforms=[
            dict(
                type='GlobalRotScaleTrans',
                rot_range=[0, 0],
                scale_ratio_range=[1., 1.],
                translation_std=[0, 0, 0]),
            dict(type='RandomFlip3D'),
            dict(
                type='PointsRangeFilter', point_cloud_range=point_cloud_range)
        ]),
    dict(type='Pack3DDetInputs', keys=['points'])
]

# 训练数据加载器配置
train_dataloader = dict(
    dataset=dict(dataset=dict(pipeline=train_pipeline, metainfo=metainfo)))

# 测试数据加载器配置
test_dataloader = dict(dataset=dict(pipeline=test_pipeline, metainfo=metainfo))
val_dataloader = dict(dataset=dict(pipeline=test_pipeline, metainfo=metainfo))

# 优化器配置
lr = 0.001  # 学习率
epoch_num = 80  # 训练轮数
optim_wrapper = dict(
    optimizer=dict(lr=lr), clip_grad=dict(max_norm=35, norm_type=2))  # 优化器配置

# 学习率调整策略
param_scheduler = [
    dict(
        type='CosineAnnealingLR',
        T_max=epoch_num * 0.4,
        eta_min=lr * 10,
        begin=0,
        end=epoch_num * 0.4,
        by_epoch=True,
        convert_to_iter_based=True),
    dict(
        type='CosineAnnealingLR',
        T_max=epoch_num * 0.6,
        eta_min=lr * 1e-4,
        begin=epoch_num * 0.4,
        end=epoch_num * 1,
        by_epoch=True,
        convert_to_iter_based=True),
    dict(
        type='CosineAnnealingMomentum',
        T_max=epoch_num * 0.4,
        eta_min=0.85 / 0.95,
        begin=0,
        end=epoch_num * 0.4,
        by_epoch=True,
        convert_to_iter_based=True),
    dict(
        type='CosineAnnealingMomentum',
        T_max=epoch_num * 0.6,
        eta_min=1,
        begin=epoch_num * 0.4,
        end=epoch_num * 1,
        convert_to_iter_based=True)
]

# 训练配置
train_cfg = dict(by_epoch=True, max_epochs=epoch_num, val_interval=2)
val_cfg = dict()
test_cfg = dict()

二、概述

这段代码涉及到训练深度学习模型的一些重要配置,下面我将逐一详细解释每个部分的含义和作用:

  1. lr = 0.001

    • lr 是学习率(learning rate)的缩写。
    • 学习率是用于控制模型参数更新步长的超参数,它决定了每次参数更新的大小。
    • 在这里,学习率被设置为0.001,表示在每次参数更新时,每个参数的值都会按照0.001倍的步长进行更新。
  2. epoch_num = 80

    • epoch_num 表示训练的轮数(epochs)。
    • 一个轮是指整个训练数据集被完整地输入到模型中一次。
    • 在这里,训练被设置为总共进行80轮。
  3. optim_wrapper = dict(optimizer=dict(lr=lr), clip_grad=dict(max_norm=35, norm_type=2))

    • optim_wrapper 是一个包含优化器相关设置的字典。
    • optimizer 字段表示优化器的配置,这里使用了一个带有学习率设置的优化器。
    • clip_grad 字段表示梯度裁剪(gradient clipping)的配置,用于防止梯度爆炸问题。
      • max_norm 表示梯度的最大范数(norm)值,如果梯度的范数超过这个值,就会进行梯度裁剪。
      • norm_type 表示使用的范数类型,这里是L2范数。
  4. param_scheduler

    • param_scheduler 是一个包含学习率和动量(momentum)调整策略的列表。
    • 这里使用了四个不同的调整策略,它们会随着训练的进行动态地改变学习率和动量。
    • 每个调整策略是一个字典,包含以下字段:
      • type:调整策略的类型,可以是学习率调整或动量调整。
      • T_max:调整的周期,即在多少个训练轮次之后重新开始调整。
      • eta_min:学习率或动量的最小值。
      • beginend:指定调整的开始和结束轮次。
      • by_epoch:指定是否按照轮次进行调整。
      • convert_to_iter_based:指定是否将调整策略转换为基于迭代次数的策略。

这段代码中的 lrepoch_numoptim_wrapperparam_scheduler 配置了训练深度学习模型所需的学习率、训练轮数、优化器和学习率/动量调整策略等重要参数,以帮助训练过程更好地收敛和优化模型。不同的学习率和调整策略可以对模型的性能产生重要影响,需要根据具体问题和数据集进行调整和优化。

三、根据难度和最小点数过滤样本

“根据难度和最小点数过滤样本” 是一种在目标检测和物体识别任务中常用的数据预处理策略。这个策略的目的是在训练数据集中选择适合模型训练的样本,同时排除那些难以处理或质量不佳的样本。下面详细解释这两个过滤条件的含义:

  1. 根据难度过滤样本

    在目标检测任务中,通常会将样本按照难度分为不同级别,例如简单、中等和困难。这个难度级别可以根据不同数据集的定义而有所不同,但通常与物体的大小、遮挡程度、姿态等因素有关。

    • 简单样本:通常指那些容易检测的物体,例如大型、无遮挡、正立的物体。
    • 中等样本:具有一定难度的样本,可能有一些遮挡或非常小的物体。
    • 困难样本:指那些非常具有挑战性的样本,可能存在严重遮挡、极小的物体或非常复杂的姿态等情况。

    通过根据难度过滤样本,可以选择训练集中特定难度级别的样本,以确保模型能够适应不同难度级别的场景。

  2. 根据最小点数过滤样本

    在点云数据中,每个物体通常由一组点云表示。样本的质量和可用性与点云的密度和数量有关。根据最小点数过滤样本的策略旨在排除那些点云数量太少的样本,因为这样的样本可能难以有效地用于训练。

    例如,如果目标检测任务中,要求每个物体至少包含一定数量的点云,比如5个点云点,那么根据最小点数过滤样本的策略会排除那些点云数量少于5的物体,以确保训练样本的质量和可用性。

综合来看,“根据难度和最小点数过滤样本” 是一种在数据预处理阶段,根据物体的难度级别和点云的数量,筛选出符合条件的样本,以构建用于训练深度学习模型的训练集。这样的策略有助于提高模型的鲁棒性和泛化能力,因为它允许模型在各种不同难度级别和点云密度下进行训练。筛选过程可以根据具体任务和数据集的要求进行调整。

四、余弦退火部分(学习率lr,动量Momentum)

代码如下:

# 学习率设置,控制参数更新的步长
lr = 0.001

# 训练轮数,一个轮表示整个训练数据集被完整输入模型一次
epoch_num = 80

# 优化器配置,包含学习率设置和梯度裁剪配置
optim_wrapper = dict(
    optimizer=dict(lr=lr),  # 学习率设置为0.001
    clip_grad=dict(max_norm=35, norm_type=2)  # 梯度裁剪配置,防止梯度爆炸
)

# 学习率和动量调整策略列表
param_scheduler = [
    dict(
        type='CosineAnnealingLR',  # 学习率调整策略类型:余弦退火
        T_max=epoch_num * 0.4,  # 调整周期为总轮数的40%
        eta_min=lr * 10,  # 最小学习率设为初始学习率的10倍
        begin=0,  # 开始轮数
        end=epoch_num * 0.4,  # 结束轮数
        by_epoch=True,  # 按轮数调整
        convert_to_iter_based=True),  # 转换为基于迭代次数的策略

    dict(
        type='CosineAnnealingLR',
        T_max=epoch_num * 0.6,
        eta_min=lr * 1e-4,
        begin=epoch_num * 0.4,
        end=epoch_num * 1,
        by_epoch=True,
        convert_to_iter_based=True),

    dict(
        type='CosineAnnealingMomentum',  # 动量调整策略类型:余弦退火
        T_max=epoch_num * 0.4,
        eta_min=0.85 / 0.95,
        begin=0,
        end=epoch_num * 0.4,
        by_epoch=True,
        convert_to_iter_based=True),

    dict(
        type='CosineAnnealingMomentum',
        T_max=epoch_num * 0.6,
        eta_min=1,
        begin=epoch_num * 0.4,
        end=epoch_num * 1,
        convert_to_iter_based=True)
]

动量调整是深度学习优化算法中的一种技巧,通常用于随机梯度下降(SGD)和其变种的优化器中,如带动量的随机梯度下降(Momentum SGD)或带动量的Adam优化器(Adam with Momentum)等。

在梯度下降中,每次更新参数时,会根据当前梯度的方向和大小来移动参数,以尽量减小损失函数的值。然而,在复杂的损失曲面上,存在很多局部极小值和平原区域,这可能导致梯度下降收敛速度较慢或陷入局部最小值。动量调整的目的是加速模型参数的更新,并帮助模型跳出局部极小值和平原区域。

动量调整的核心思想是引入一个动量项(momentum),该项表示前几次梯度更新的累积方向和大小。这样做的好处是,即使当前梯度指向局部极小值或平原区域,动量也可以帮助模型在一定程度上继续前进,直到找到更陡峭的下降方向。

通常,动量调整的计算公式如下:

v(t+1) = beta * v(t) + learning_rate * gradient
parameter(t+1) = parameter(t) - v(t+1)

其中:

  • v(t) 是在时间步 t 的动量(velocity)。
  • beta 是动量系数,通常取值在0到1之间,控制了动量的积累程度。较大的 beta 表示更多的动量积累。
  • learning_rate 是学习率,控制了每次参数更新的步长。
  • gradient 是当前时间步的梯度。

总的来说,动量调整允许模型在梯度更新方向上积累速度,从而加速收敛过程,并提高了模型跳出局部最小值的可能性。这使得训练深度神经网络更加稳定和高效。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值