经过几天的研究,kpconvx网络已经研究的差不多了,接下来我将按各个功能和如何调整这个神经网络找到对应的的代码区域并做修改,形成大体的框架
数据处理,类别划分,数据集划分,网络输入部分,可能需要针对数据调整的参数
数据处理
- 首先我们要保证输入的数据是这种格式的
具体的如何将一个原始的点云数据逐步转化为这种格式我将会在另一边csdn介绍
类别划分
- 然后是类别划分,就是S3DIS数据集要划分成多少个类别
注意:这里数据集处理的时候的类别编号顺序要和模型设置的一致
显然这一部分在我们的dataset里
具体位置在kpconvx/experiments/S3DIS/S3DIS_rooms.py中
只需要在这里设置需要的类别就好了,其他的可以不用管,
数据集划分
- 我们按照S3DIS的数据集格式划分出来各个area,接下来就需要选定哪些area用于训练,哪些用于验证了
具体位置同样在kpconvx/experiments/S3DIS/S3DIS_rooms.py的S3DIR_files函数
在这里设置好数据集的划分,注意如果只有一个后面要加,保持数组的格式
网络输入部分
== 这里我们能看到,在参数设置部分,输入维度是5,
他的这个输入维度具体在哪呢 ==
- 网络输入部分
同样,还是在kpconvx/experiments/S3DIS/S3DIS_rooms.py的load_scene_file函数中
可以看到,这里是选择是否读取normal,也就是法线数据,根据需要来决定是否注释即可
注意:这个可能也需要改,根据是否有法向量
注意:真实输入模型的并不是这五个.npy,在其他函数中,还对这些点进行了下采样生成.ply,并生成KDTree,还生成了全部点与下采样点之间的对应关系
可以看到这个才是输入的数据
可能需要调整的参数
这些训练参数是跟数据集有关的,取决于你的点云稀疏性和点云的大小,如果想识别微小特征的话,如果下采样的值和核点卷积的值过大很可能导致神经网络根本看不到这些特征
同样的较小的下采样也可能导致计算效率下降,计算时间增加
训练参数,验证数据查看
训练参数
大部分都有注释,我直接贴在这里
// An highlighted block
cfg = init_cfg()
# 网络参数
# ------------------
# cfg.model.layer_blocks = (3, 3, 9, 12, 3) # KPNetX-S
# cfg.model.layer_blocks = (4, 4, 12, 20, 4) # KPNetX-L
# cfg.model.layer_blocks = (2, 2, 2, 8, 2) # KPConvX-S
cfg.model.layer_blocks = (3, 3, 9, 12, 3) # KPConvX-L
cfg.model.norm = 'batch' # batch(批量归一化), layer(层归一化)
cfg.model.init_channels = 64 # 初始通道数(48, 64, 80, 96)
cfg.model.channel_scaling = 1.41 # 通道缩放因子(2或√2等)
cfg.model.kp_mode = 'kpconvx' # 选择卷积类型:
# ['kpconv', 'kpdef', 'kpinv', 'kpinvx']
# ['inv_v1', 'inv_v2', 'inv_v3', 'inv_v4', 'transformer']
# ['kpconv-mod', 'kpdef-mod', 'kpconv-geom'] 调制类型
# ['kpconv-depth'] 深度卷积(分组数=输入通道=输出通道)
# ['kpnext'] 改进版KPConv
# ['kpmini', 'kpminix'] 轻量级KPConv
# ['kptran', 'kpminimod'] KP注意力机制
# ['kpconvd', 'kpconvx'] CVPR投稿新模块
cfg.model.shell_sizes = [1, 14, 28] # 卷积核的壳层尺寸
cfg.model.kp_radius = 1 # 卷积核半径
cfg.model.kp_influence = 'linear' # 影响函数类型:'constant'(常量), 'linear'(线性), 'gaussian'(高斯)
cfg.model.kp_aggregation = 'nearest' # 聚合方式:'sum'(求和), 'nearest'(最近邻)
cfg.model.conv_groups = -1 # 分组卷积参数:-1为深度卷积,1为普通卷积
cfg.model.share_kp = True # 是否在层间共享卷积核
cfg.data.init_sub_size = 0.05 # 初始点云下采样尺寸(负数表示不进行初始下采样),点云稀疏化的体素大小
cfg.data.init_sub_mode = 'grid' # 初始下采样模式(体素网格下采样,划分成3d网格,还有fps和random
cfg.model.in_sub_size = 0.05 # 输入下采样尺寸(需与train.in_radius匹配)(输入到模型中点的密度)
cfg.model.in_sub_mode = 'grid' # 输入下采样模式
cfg.model.radius_scaling = 1 # 卷积半径缩放因子
cfg.model.kpx_upcut = False # 是否使用上切割操作
cfg.model.grid_pool = True # 是否使用纯网格池化(类似PointTransformer v2)
cfg.model.decoder_layer = True # 解码器是否添加额外层(类似PointTransformer v2)
cfg.model.upsample_n = 3 # 上采样时的最近邻数量(grid_pool启用时忽略)
cfg.model.drop_path_rate = 0.3 # DropPath的随机深度比率
cfg.model.input_channels = 5 # 必须与数据集输入特征维度匹配
# cfg.model.neighbor_limits = [10, 12, 12, 12, 12] # Use empty list to let calibration get the values
# cfg.model.neighbor_limits = [12, 14, 16, 16, 16] # Use empty list to let calibration get the values
# cfg.model.neighbor_limits = [16, 17, 18, 18, 18] # Use empty list to let calibration get the values
# cfg.model.neighbor_limits = [35, 40, 50, 50, 50] # Use empty list to let calibration get the values
# cfg.model.neighbor_limits = [16, 16, 16, 16, 16] # List for point_transformer
cfg.model.neighbor_limits = [12, 16, 20, 20, 20] # List for point_transformer
# cfg.model.neighbor_limits = [] # Use empty list to let calibration get the values
# 专用于Involution和Transformer的参数
cfg.model.use_strided_conv = True # 对跨步层使用普通卷积代替Involution
cfg.model.first_inv_layer = 1 # 从该层开始使用Involution(层索引从0开始)
cfg.model.inv_groups = 4 # Involution分组数(负值表示按通道分组)
cfg.model.inv_grp_norm = True # 是否对Involution分组进行归一化
cfg.model.inv_act = 'sigmoid' # Involution激活函数:'none', 'sigmoid', 'softmax', 'tan
# Specific parameters for kpinv
cfg.model.kpinv_reduc = 1 # KPInv的降维因子 。这个参数的作用是控制数据在进行点云卷积前的降维程度,通常用于减少计算量,特别是在高维数据处理时。
cfg.model.kpx_expansion = 4 # KPConvX的通道扩展倍数 个卷积核的通道数会扩展为原始通道数的 8 倍。这个扩展操作能够增加卷积层的容量,从而提升模型在复杂任务中的表现。但这也意味着参数量和计算量会显著增加,可能导致训练和推理速度变慢,但通常能够提高模型的表现力。
# 训练参数
# -------------------
# 输入线程数
cfg.train.num_workers = 10
# 输入形状类型(球体/立方体/圆柱体/立方圆柱体)
cfg.data.use_cubes = False # 是否使用立方体输入
cfg.data.cylindric_input = False # 是否使用圆柱坐标系
#我们如何对输入元素(球体或立方体)进行采样(每个step中batch中采样的方式)
cfg.train.data_sampler = 'c-random' # 数据采样方式,可选 'random'(随机采样)、'A-random' 或 'c-random'(类别平衡随机采样)
# 输入球体的半径。需要与 model.in_sub_size 进行适配,尽量保持大约 50 的比例
cfg.train.in_radius = 1 # 如果值为负数,则表示按照输入点的数量确定半径。使用负数可以用于不同模型的对比实验
# 批次相关参数
cfg.train.batch_size = 2 # 目标批次大小(直接设置train.batch_limit可跳过校准)
cfg.train.accum_batch = 3 # 梯度累积步数(有效批次大小 = batch_size * accum_batch)
cfg.train.steps_per_epoch = 100 # 每个epoch的迭代步数
# Training length
cfg.train.max_epoch = 100 # 100
# Deformations
# 可变形卷积参数
cfg.train.deform_loss_factor = 0.1 # 可变形损失权重(降低可减少形变对特征的影响) deform_loss_factor = 0.1:表示形变损失的影响较小,模型主要专注于特征学习。增大该值(例如 0.5 或 1.0)会让形变对损失的贡献增大,模型会更倾向于学习形变。
cfg.train.deform_lr_factor = 1.0 # Higher so that deformation are learned faster (especially if deform_loss_factor is low)
# 可变形参数学习率倍数(加快形变学习)
#。如果你希望模型更好地适应形变或非刚性物体,可能需要调大这两个参数的值;如果形变不重要或不希望其对最终结果影响过大,可以调小这两个参数的值
# 优化器
cfg.train.optimizer = 'AdamW' # 优化器类型
cfg.train.adam_b = (0.85, 0.999) # Adam的beta参数#对于微小特征,通常不会需要对 beta1 和 beta2 进行大幅调整。因为小区域的特征通常难以学习,过高的 beta1 或 beta2 可能会导致优化过于“平滑”,无法快速响应微小特征的变化。如果你希望提高模型对微小特征的敏感度,可以适当调低 beta1,如设为 0.85 或更低。这样可以加速模型对微小梯度变化的响应。
cfg.train.adam_eps = 1e-08 # Adam的epsilon参数
cfg.train.weight_decay = 0.4 # 权重衰减(KPConv适用值)#对于微小特征学习,尤其是当特征较为稀疏或难以捕捉时,较高的权重衰减可能会使模型过于平滑,导致对细节的学习能力下降。你可以尝试减小权重衰减的值,例如 0.001 或 0.0001,以便模型能够更好地适应微小特征的细节。减小权重衰减:有助于模型更好地拟合微小特征,避免过度正则化。增大权重衰减:有助于防止过拟合,尤其是当数据集较小或特征过于复杂时。
# cfg.train.weight_decay = 0.0001 # Transformer适用值
# # 循环学习率
cfg.train.cyc_lr0 = 1e-5 # 初始学习率
cfg.train.cyc_lr1 = 1e-4 # 最大学习率
cfg.train.cyc_raise_n = 40 # 学习率上升周期数(每周期乘以10)
cfg.train.cyc_decrease10 = 80 # 学习率下降周期数(每周期除以10)
cfg.train.cyc_plateau = 5 # 最大学习率平台期周期数
# import matplotlib.pyplot as plt
# fig = plt.figure('lr')
# y = [init_lr]
# for i in range(cfg.train.max_epoch):
# y.append(y[-1])
# if str(i) in cfg.train.lr_decays:
# y[-1] *= cfg.train.lr_decays[str(i)]
# plt.plot(y)
# plt.xlabel('epochs')
# plt.ylabel('lr')
# plt.yscale('log')
# ax = fig.gca()
# ax.grid(linestyle='-.', which='both')
# plt.show()
# a = 1/0
# 数据增强配置(训练)
cfg.augment_train.anisotropic = True # 各向异性缩放
cfg.augment_train.scale = [0.95, 1.05] # 缩放范围 #该参数控制缩放的幅度,数值越大,变形幅度越大。对少数类别的影响:少数类别可能在训练数据中被缩放后丢失一些微小的特征。因此,过大的缩放范围可能会对少数类别的识别不利。建议:为了更好地保持少数类别的特征,建议稍微减小缩放范围,如 [0.95, 1.05] 或更小。这会让数据增强效果更温和,避免过度放大或缩小导致特征失真。
cfg.augment_train.flips = [0.5, 0, 0] # 翻转概率(x,y,z轴)
cfg.augment_train.rotations = 'vertical' # 旋转方式(绕垂直轴)
cfg.augment_train.jitter = 0.005 # 坐标抖动强度
cfg.augment_train.color_drop = 0.2 # 颜色通道丢失概率
cfg.augment_train.chromatic_contrast = True # 颜色对比度增强
cfg.augment_train.chromatic_all = False # 是否对所有颜色通道增强
cfg.augment_train.chromatic_norm = True # 颜色归一化
cfg.augment_train.height_norm = False # 高度归一化
cfg.augment_train.pts_drop_p = 0.1 # 点丢弃概率(负数表示禁用)
cfg.augment_train.mix3D = -1.0 # 3D混合增强(0.8启用)
# Test parameters
# ---------------
# How do we sample the input elements (spheres or cubes)
# How do we sample the input elements (spheres or cubes)
cfg.test.in_radius = 300.0 # 测试时输入半径(覆盖整个房间)100
cfg.test.data_sampler = 'regular' # 测试采样方式:'regular'(规则采样)
cfg.test.max_steps_per_epoch = 100 # 验证阶段最大步数
cfg.test.batch_limit = 1 # 测试批次限制
cfg.test.batch_size = 1 # 测试批次大小
cfg.test.val_momentum = 0.9 # 验证阶段动量参数
# 数据增强配置(测试)
cfg.augment_test.anisotropic = False # 测试时不使用各向异性缩放
cfg.augment_test.scale = [0.99, 1.01] # 测试缩放范围(微小扰动)
cfg.augment_test.flips = [0.5, 0, 0] # 测试翻转概率
cfg.augment_test.rotations = 'vertical' # 测试旋转方式
cfg.augment_test.jitter = 0 # 测试无坐标抖动
cfg.augment_test.color_drop = 0.0 # 测试不丢失颜色通道
cfg.augment_test.chromatic_contrast = False # 测试无颜色对比度增强
cfg.augment_test.pts_drop_p = -1.0 # 测试不丢弃点
return cfg
接下来是验证数据查看
== 这里他的逻辑是train_S3DIS调tasks里的trainval函数,然后trainval函数调training和validation,==
1.混淆矩阵的查看
具体代码在这里,但是其实不用太动,因为这个如果选了saving,后面saving代码里都保存了,而且每个类别的iou都是有的,如果一定要查看的话,那就用test。py里的代码,稍微修改一下这里就能查看每个点的预测值
- loss查看
他validation没有给出loss,所以我们要自己加,位置很好找,找到cloud_segmentation_validation中的outputs= net(batch)在后面加就行
自己加就行,什么方式计算loss也是自行决定