昌江黎族自治县网站建设_网站建设公司_搜索功能_seo优化
2025/12/18 0:57:36 网站建设 项目流程

前言

博主导读
在上一篇文章 《Pointcept 框架详解:从 Config 到 Runner 的全流程执行机制》 中,我们像剥洋葱一样拆解了 Pointcept 的代码架构。明白了“配置驱动”的原理后,很多同学跃跃欲试,想要在自己的数据集上跑起来。然而,“道理我都懂,一改就报错”是很多人的真实写照。在实际魔改的过程中,大概率会遇到各种各样这种让人摸不着头脑的错误。
本文将从代码实现、配置修改、执行顺序三个维度,手把手教你如何在 Pointcept 中正确添加自定义数据增强,并完美避开“类型冲突”的深坑。


4. 实例说明:从命令行到代码底层

在了解了框架结构后,我们通过一个具体的实例,来看看 Pointcept 是如何把命令行参数一步步转化为Python 对象的。

通常情况下,我们推荐使用scripts/train.sh来启动训练。它是一个 Shell 包装器,负责环境配置和备份。

# 通用模板shscripts/train.sh -p${INTERPRETER_PATH}-g${NUM_GPU}-d${DATASET_NAME}-c${CONFIG_NAME}-n${EXP_NAME}
参数全称含义
-pPython Interpreter指定 Python 解释器路径 (如python/usr/bin/python)
-dDataset数据集名称 (决定去configs/下哪个子目录找配置)
-cConfig配置文件名称 (不带.py后缀)
-nExperiment Name实验名称 (决定exp/下的输出目录名)
-wWeight权重文件路径 (用于 Finetune 或 Test)
-rResume是否恢复训练 (断点续训),可选true/false
-gNum GPU使用的 GPU 数量
-mNum Machine机器数量 (用于多机多卡训练)

train.sh 脚本在解析完上述参数后,会将其打包,并最终调用 Python 入口文件。
上述的 Shell 命令等价于直接运行以下 Python 命令:

# 等价的 Python 调用方式 python tools/train.py \ --config-file configs/scannet/semseg-pt-v2m2-0-base.py \ --num-gpus 1 \ --options save_path=exp/scannet/semseg-base‘’

平时做实验用 Shell 方式更方便;但在 IDE (如 PyCharm, VSCode) 中 Debug 时,使用 Python 方式直接运行 tools/train.py 会更简单。

当程序启动后,Config 文件是如何实例化成具体的 Python 类的?我们以 ModelNet40 分类任务 为例。
配置文件 (Config):在 configs/modelnet40/cls-ptv2-v1m1-0-base.py 中,定义了一个字典

model = dict( type="DefaultClassifier", # <--- 【关键】这就是 Registry 中的 Key num_classes=40, # <--- 参数 1 backbone_embed_dim=256, # <--- 参数 2 # ... 其他参数 )

源码定义 (Source Code):在 pointcept/models/default.py 中,我们可以找到对应的类定义

from pointcept.models import MODELS @MODELS.register_module() # <--- 【关键】把这个类注册到 MODELS 名录里 class DefaultClassifier(nn.Module): # 注意:这里的参数名,和 Config 字典里的 Key 是一模一样的! def __init__(self, num_classes, backbone_embed_dim, backbone, criteria, ...): super().__init__() self.num_classes = num_classes # ...

连接过程:运行时发生的“魔法”:当你运行代码时,Pointcept 的 build 函数在后台执行了类似下面的逻辑,将字符串变成了对象

# 伪代码:解释 build 函数内部发生了什么 def build_model(config_dict): # 1. 拿出名字 (Key) # 此时 class_name = "DefaultClassifier" # config_dict 剩下了 {num_classes: 40, ...} class_name = config_dict.pop("type") # 2. 找到对应的类 (Class) # 去全局字典 MODELS 里查表,找到了 DefaultClassifier 这个类 TargetClass = MODELS.get(class_name) # 3. 实例化 (Instantiation) # 把剩下的 dict 当作 **kwargs 传进去 # 等价于: DefaultClassifier(num_classes=40, backbone_embed_dim=256, ...) obj = TargetClass(**config_dict) return obj

这就是 Pointcept “配置驱动” 的核心奥义:Config 里的 Key 对应init的参数名,type 对应类名。 掌握了这个规律,你就可以随心所欲地修改参数了。

5. 数据增强之随机旋转

根据 Pointcept 的设计规范,所有的数据增强类都位于pointcept/datasets/transform.py。我们需要在这里实现一个基于NumPy的旋转类。
原始代码给出的是围绕着某一个轴进行旋转,现在我们改为随机旋转,并进行使用。

特别注意是NumPy类!!!

5.1 源码注入

请打开pointcept/datasets/transform.py,加入以下代码。别忘了加上@TRANSFORMS.register_module(),这是让 Config 能找到它的关键!

@TRANSFORMS.register_module()classRandomRotate(object):def__init__(self,angle=None,center=None,axis="z",always_apply=False,p=0.5):# 初始化参数:角度范围、旋转轴、中心点、概率self.angle=[-1,1]ifangleisNoneelseangle self.axis=axis self.always_apply=always_apply self.p=pifnotself.always_applyelse1self.center=centerdef__call__(self,data_dict):# 1. 概率判断:决定本次是否执行增强ifrandom.random()>self.p:returndata_dict# 2. 计算旋转矩阵 (Rotation Matrix)# 这里的 angle 范围是 [-1, 1] * pi,即 -180度 到 +180度angle=np.random.uniform(self.angle[0],self.angle[1])*np.pi rot_cos,rot_sin=np.cos(angle),np.sin(angle)ifself.axis=="z":# 绕 Z 轴旋转矩阵 (最常用)rot_t=np.array([[rot_cos,-rot_sin,0],[rot_sin,rot_cos,0],[0,0,1]])elifself.axis=="y":rot_t=np.array([[rot_cos,0,rot_sin],[0,1,0],[-sin_y,0,rot_cos]])elifself.axis=="x":rot_t=np.array([[1,0,0],[0,rot_cos,-rot_sin],[0,rot_sin,rot_cos]])else:raiseNotImplementedError("目前只支持单轴旋转,若需任意旋转请修改代码")# 3. 执行几何变换if"coord"indata_dict.keys():# 自动计算几何中心ifself.centerisNone:x_min,y_min,z_min=data_dict["coord"].min(axis=0)x_max,y_max,z_max=data_dict["coord"].max(axis=0)center=[(x_min+x_max)/2,(y_min+y_max)/2,(z_min+z_max)/2]else:center=self.center# 核心步骤:移回原点 -> 旋转 -> 移回原位# 注意:这里的 coord 是 NumPy 数组data_dict["coord"]-=center data_dict["coord"]=np.dot(data_dict["coord"],np.transpose(rot_t))data_dict["coord"]+=center# 4. 同步旋转法向量 (Normal)if"normal"indata_dict.keys():data_dict["normal"]=np.dot(data_dict["normal"],np.transpose(rot_t))returndata_dict

5.2 配置Config 方案

打开你的配置文件(如configs/modelnet40/cls-ptv2-base.py),修改 data 部分:

data=dict(num_classes=40,ignore_index=-1,names=class_names,# 训练集配置train=dict(type=dataset_type,split="train",data_root=data_root,transform=[dict(type="NormalizeCoord"),# ✅ 正确位置:在 ToTensor 之前# p=1.0 表示每个样本都旋转;angle=[-1, 1] 表示 360 度随机dict(type="RandomRotate",angle=[-1,1],axis="z",center=[0,0,0],p=1.0),dict(type="RandomScale",scale=[0.7,1.5],anisotropic=True),dict(type="RandomShift",shift=((-0.2,0.2),(-0.2,0.2),(-0.2,0.2))),# GridSample 会进行体素化采样,通常建议先做几何变换,再做采样dict(type="GridSample",grid_size=0.01,hash_type="fnv",mode="train",return_grid_coord=True),dict(type="ShufflePoint"),dict(type="ToTensor"),# <--- 分界线:这之后的数据全是 Tensordict(type="Collect",keys=("coord","grid_coord","category"),feat_keys=["coord","normal"]),],test_mode=False,),# 验证集配置val=dict(type=dataset_type,split="test",data_root=data_root,transform=[dict(type="NormalizeCoord"),# 验证集通常不需要旋转,除非你想做 TTA (Test Time Augmentation)dict(type="GridSample",grid_size=0.01,hash_type="fnv",mode="train",return_grid_coord=True),dict(type="ToTensor"),dict(type="Collect",keys=("coord","grid_coord","category"),feat_keys=["coord","normal"]),],test_mode=False,),)

这里你需要注意:dict(type="ToTensor"), # <— 分界线:这之后的数据全是 Tensor,大多数数据预处理是使用的numpy,这是需要放在分界线之前的,否则你会遇到报错:
TypeError: unsupported operand type(s) for -=: ‘Tensor’ and ‘list’
File “…/pointcept/datasets/transform.py”, line 293, incall
data_dict[“coord”] -= center

6. 总结与预告 (Conclusion)

通过这次实战,我们不仅学会了如何添加数据增强,更重要的是理解了 Pointcept 数据流的底层逻辑。Registry 是桥梁:@TRANSFORMS.register_module() 将 Python 类映射到 Config 字符串。顺序是关键:Config 列表中的顺序就是代码执行的顺序。基于 NumPy 的操作必须放在 ToTensor 之前。

掌握了这套“配置驱动 (Config-Driven)”的开发模式,你不仅能玩转 Pointcept,以后上手 MMDetection、Detectron2 等工业级框架也将易如反掌。


📚 附录:点云网络系列导航

本专栏致力于用“人话”解读 3D 视觉领域的硬核论文与源码,从原理到代码逐行拆解。
🔥 欢迎订阅专栏,不错过每一篇干货:【深度学习-论文讲解】持续更新中…


💬互动话题
你在配置环境时候遇到了什么问题?
你还有什么流程无法理解的部分?
欢迎在评论区留言分享你的“踩坑”经历,我们一起避雷!


🌟 如果这篇文章对你有帮助,请 点赞 👍、收藏 ⭐、关注 🚩 支持博主!
你的三连是我持续更新的最大动力!

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询