尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

扩展 Detectron2 默认行为:配置文件驱动、注册表机制与自定义数据管线的完整指南(OOTDiffusion 人体解析模块实战)

扩展 Detectron2 默认行为:配置文件驱动、注册表机制与自定义数据管线的完整指南(OOTDiffusion 人体解析模块实战) 扩展 Detectron2 默认行为配置文件驱动、注册表机制与自定义数据管线的完整指南OOTDiffusion 人体解析模块实战【免费下载链接】OOTDiffusion[AAAI 2025] Official implementation of OOTDiffusion: Outfitting Fusion based Latent Diffusion for Controllable Virtual Try-on项目地址: https://gitcode.com/GitHub_Trending/oo/OOTDiffusion本文以 detectron2 官方扩展指南 为核心骨架结合 OOTDiffusion 仓库内嵌的 detectron2 源码与人体解析humanparsing实际配置系统讲解如何在保留官方默认行为的前提下通过「配置文件cfg驱动」与「显式参数组件」两类接口以及configurable装饰器、注册表Registry、自定义数据集/数据加载器/训练循环等手段扩展 Detectron2最终落到 OOTDiffusion 虚拟试穿前处理管线中人体解析模型的自定义数据、推理配置与调用链。读完本文你将掌握一套可复制、可运行的 detectron2 二次开发方法论并能在 OOTDiffusion 仓库中直接定位到对应的实现证据。为什么需要扩展 Detectron2研究型工程天然存在一个张力一方面代码抽象要足够薄以便研究者随时打破既有抽象、用新方式替换另一方面抽象又要足够高让普通用户不必关心只有少数研究者才在意的细节。Detectron2 用两类接口共同化解了这个矛盾这也是 extend.md 开篇给出的核心论断取配置cfg作为参数的函数与类它们实现标准默认行为——从配置中读取自己所需的一切然后做标准的事。用户只需加载一份配置并到处传递它无需关心哪些参数被使用、各自含义是什么。参数定义清晰、显式的函数与类它们是整个系统的小积木需要用户具备专业知识去理解每个参数的含义拼接成更大系统需要更多功夫但拼接方式更灵活。当你要实现标准默认未覆盖的功能时这些组件可以被直接复用。实验性少数类使用configurable装饰器它们既可以接收一个 cfg也可以接收显式参数调用其显式参数接口目前标记为实验性、可能变化。这一设计直接体现在 OOTDiffusion 的虚拟试穿前处理链路中仓库在 preprocess/humanparsing/mhp_extension/detectron2 内嵌了一份完整可用的 detectron2用于人体解析模型的训练、微调与推理。理解上述两类接口是读懂这份内嵌代码的第一步。第一类接口cfg 驱动的标准默认核心思想配置即契约在 detectron2 中cfg一个CfgNode贯穿始终。用户拿到一份 YAML 配置后只需from detectron2.config import get_cfg cfg get_cfg() # 获取默认配置的副本 cfg.merge_from_file(path/to/your_config.yaml) # 合并自定义配置之后把cfg传给build_model(cfg)、build_detection_train_loader(cfg)等函数即可。用户不需要知道函数内部究竟消费了哪些键。在 config/config.py 中可以看到具体的实现支撑CfgNode继承自fvcore.common.config.CfgNode但做了两点定制默认使用不安全的 YAML 加载allow_unsafeTrue因此官方明确警告加载来自不可信来源的配置文件前必须人工检查内容并支持配置版本化——合并旧版配置时会通过upgrade_config/downgrade_config自动升级/降级到当前版本。get_cfg()返回_C.clone()保证每次调用拿到的是默认配置的独立副本修改互不影响。set_global_cfg(cfg)提供全局配置入口配合from detectron2.config import global_cfg可在任意位置读取配置值是官方明确定位的用于快速原型/研究探索的 hack 特性。配置版本化机制merge_from_file是 cfg 驱动的入口其流程值得注意对应 config/config.py断言配置文件存在用_CfgNode.load_yaml_with_base加载 YAML支持_BASE_继承比较loaded_ver与当前self.VERSION版本相同则直接merge_from_other_cfg版本较旧则先downgrade_config构造旧版完整配置、合并、再upgrade_config升级并打印提示日志。这意味着你在 OOTDiffusion 内嵌 detectron2 里写的配置文件即使版本较旧加载时也会被自动迁移无需手工改写。第二类接口显式参数的小积木当标准默认无法满足需求时第二类接口登场。典型例子是数据加载管线的组装在 data/build.py 中build_detection_train_loader(cfg, mapperNone)与build_detection_test_loader(cfg, dataset_name, mapperNone)均接受显式的mapper参数。其默认管线为根据配置中的数据集名如coco_2017_train从注册表取回轻量的list[dict]数据集项——此时图片尚未加载、增强尚未应用每个 dict 由mapper函数映射为模型可直接消费的格式读图、随机增强、转 torch Tensormapper 的输出被简单地 batch 成一个 list该 batch 即数据加载器输出通常就是model.forward()的输入。如需自定义转换最常见做法是传入自定义mapper详见下文自定义数据加载器。若需要更换采样/批处理逻辑则可完全自写一个迭代器形式的数据加载器只要产出模型接受的格式即可。configurable连接两类接口的实验性桥梁extend.md 中提到的configurable装饰器实验性源码位于 config/config.py。它允许类的__init__以三种方式被调用class A: configurable def __init__(self, a, b2, c3): pass classmethod def from_config(cls, cfg): # 返回要传给 __init__ 的 kwargs return {a: cfg.A, b: cfg.B} a1 A(a1, b2) # 常规显式构造 a2 A(cfg) # 用 cfg 构造 a3 A(cfg, b3, c4) # 用 cfg 构造并覆盖额外参数其实现要点同文件后续代码wrapped内部通过_called_with_cfg判断首个位置参数或cfg关键字是否为CfgNode实例决定走from_config还是直接显式构造from_config的第一个参数必须命名为cfg否则抛TypeError如果from_config不接受某些 kwargs如b3_get_args_from_config会把这些额外参数原样透传给__init__对 detectron2 内部的类官方强制要求configurable的__init__文档字符串中带有 experimental 字样否则断言失败——这是对实验性接口的强制标记。从源码结构可以推断configurable是cfg 驱动与显式参数两种风格之间的平滑过渡层特别适合组件既想开箱即用、又想支持深度定制的场景。扩展实战一注册自定义数据集如果只需官方标准行为getting_started.md 已足够需要扩展时官方给出以下路线图与 extend.md 的指引一一对应使用自定义数据集 → datasets.md编写自定义数据加载器 → data_loading.md覆盖模型行为 → models.md 与 write-models.md自定义训练循环 → training.md两步注册DatasetCatalog MetadataCatalog使用自定义数据集同时复用官方数据加载器需要两步注册数据集——告诉 detectron2 如何获取数据from detectron2.data import DatasetCatalog def my_dataset_function(): ... return list[dict] # 返回标准数据集 dict 列表 DatasetCatalog.register(my_dataset, my_dataset_function)注册在进程存活期间持续生效。返回的 dict 格式有两种选择标准数据集 dict与 COCO json 注解格式类似可自动对接 detectron2 大量内置功能官方推荐在够用时优先使用。字段包括file_name图片完整路径会按 EXIF 信息做旋转/翻转、height/width、image_id、annotations实例级标注列表其中bbox、bbox_mode、category_id必填bbox_mode须是BoxMode.XYXY_ABS或BoxMode.XYWH_ABS之一segmentation可为多边形列表或 COCO RLE 字典keypoints格式为[x1,y1,v1,...,xn,yn,vn]、iscrowd0/1等。空annotations的图片默认从训练中剔除可通过DATALOADER.FILTER_EMPTY_ANNOTATIONS改变。语义分割任务还需sem_seg_file_name。自定义 dict可为新任务返回任意自定义格式的 dict如为任务添加额外键但必须保证下游代码能正确处理通常需要配套编写自定义 mapper。注册元数据可选但推荐from detectron2.data import MetadataCatalog MetadataCatalog.get(my_dataset).thing_classes [person, dog]元数据是整个数据集共享的键值映射用于类别名/颜色、文件根目录等服务于增强、评估、可视化与日志。常用键包括thing_classes、thing_colors、stuff_classes、stuff_colors、keypoint_names、keypoint_flip_map、keypoint_connection_rules以及 COCO 评估相关的thing_dataset_id_to_contiguous_id、json_file、evaluator_type等。若数据集已是 COCO json 格式可一步到位from detectron2.data.datasets import register_coco_instances register_coco_instances(my_dataset, {}, json_annotation.json, path/to/image/dir)数据集的内置支持清单见 detectron2/data/datasets/README.md。为新数据集更新配置注册完成后把数据集名填进cfg.DATASETS.{TRAIN,TEST}并根据任务调整MODEL.ROI_HEADS.NUM_CLASSES/MODEL.RETINANET.NUM_CLASSESR-CNN 与 RetinaNet 的 thing 类别数MODEL.ROI_KEYPOINT_HEAD.NUM_KEYPOINTSKeypoint R-CNN 的关键点数评估还需TEST.KEYPOINT_OKS_SIGMASMODEL.SEM_SEG_HEAD.NUM_CLASSESSemantic FPN / Panoptic FPN 的 stuff 类别数Fast R-CNN 场景还需设置DATASETS.PROPOSAL_FILES_{TRAIN,TEST}。OOTDiffusion 中的实际案例CIHP 人体解析数据集在 configs/Misc/parsing_inference.yaml 中OOTDiffusion 的人体解析推理配置正是上述机制的落地_BASE_: cascade_mask_rcnn_X_152_32x8d_FPN_IN5k_gn_dconv.yaml MODEL: MASK_ON: True WEIGHTS: ./finetune_ouput/model_final.pth ROI_HEADS: NMS_THRESH_TEST: 0.95 SCORE_THRESH_TEST: 0.5 NUM_CLASSES: 1 SOLVER: IMS_PER_BATCH: 1 STEPS: (30000, 45000) MAX_ITER: 50000 BASE_LR: 0.02 INPUT: MIN_SIZE_TRAIN: (640, 864) MIN_SIZE_TRAIN_SAMPLING: range MAX_SIZE_TRAIN: 1440 CROP: ENABLED: True TEST: AUG: ENABLED: True DATASETS: TRAIN: (CIHP_trainval,) TEST: (CIHP_test,) OUTPUT_DIR: ./inference_output该配置通过_BASE_继承 Cascade Mask R-CNN 基线将NUM_CLASSES改为 1人体解析只关心人体一个实例类别并指定了训练/测试数据集与推理阈值。对应地微调配置 configs/Misc/parsing_finetune_cihp.yaml 与 CIHP 标注生成工具coco_style_annotation_creator 同级的human_to_coco.py、pycococreatortools.py等共同支撑了把 CIHP 人体解析数据转成 COCO 风格并训练检测器的完整流程——这正是注册自定义数据集 更新配置的仓库级证据。扩展实战二自定义数据加载器mapper默认管线四步build_detection_{train,test}_loader的内部逻辑data/build.py与 data_loading.md 所述一致取注册数据集 → mapper 映射 → 简单 batch → 交给模型。默认 mapper 是 DatasetMapper可通过mapper参数替换。自定义 mapper 示例当想对数据做自定义变换例如把 Mask R-CNN 训练图片统一缩放到固定尺寸时可仿照官方示例from detectron2.data import build_detection_train_loader from detectron2.data import transforms as T from detectron2.data import detection_utils as utils def mapper(dataset_dict): dataset_dict copy.deepcopy(dataset_dict) # 会被后续代码修改先深拷贝 image utils.read_image(dataset_dict[file_name], formatBGR) image, transforms T.apply_transform_gens([T.Resize((800, 800))], image) dataset_dict[image] torch.as_tensor(image.transpose(2, 0, 1).astype(float32)) annos [ utils.transform_instance_annotations(obj, transforms, image.shape[:2]) for obj in dataset_dict.pop(annotations) if obj.get(iscrowd, 0) 0 ] instances utils.annotations_to_instances(annos, image.shape[:2]) dataset_dict[instances] utils.filter_empty_instances(instances) return dataset_dict data_loader build_detection_train_loader(cfg, mappermapper)如果使用DefaultTrainer可通过覆写其build_{train,test}_loader方法来接入自定义加载器projects/DensePose/train_net.py 提供了范例如果自写训练循环则直接插入即可。扩展实战三用注册表替换模型组件write-models.md 指出大部分情况下不需要从零写整个模型而是通过注册机制覆盖标准模型内部组件的某些行为。例如新增一个 backbonefrom detectron2.modeling import BACKBONE_REGISTRY, Backbone, ShapeSpec BACKBONE_REGISTRY.register() class ToyBackBone(Backbone): def __init__(self, cfg, input_shape): self.conv1 nn.Conv2d(3, 64, kernel_size7, stride16, padding3) def forward(self, image): return {conv1: self.conv1(image)} def output_shape(self): return {conv1: ShapeSpec(channels64, stride16)}随后在配置中设置cfg.MODEL.BACKBONE.NAME ToyBackBonebuild_model(cfg)就会改而调用ToyBackBone。同理可通过ROI_HEADS_REGISTRY注册新的ROIHeads子类来扩展 Generalized R-CNN 的检测头能力。注册表本体位于 detectron2/utils/registry.py其实现直接复用fvcore.common.registry.Registry。这套机制在 OOTDiffusion 的 global_local_parsing 体系以及 configs/Misc 下的cascade_mask_rcnn_X_152_32x8d_FPN_IN5k_gn_dconv_parsing.yaml、parsing_finetune_cihp.yaml等解析专用配置中均有体现——人体解析模型正是在标准 Cascade R-CNN 之上通过配置与注册组合定制而来。扩展实战四自定义训练循环与指标日志training.md 提供了三个层次的训练定制方案自写训练逻辑PyTorch 本身足够灵活研究者可以完全掌控训练流程参考 tools/plain_train_net.pySimpleTrainer面向单损失、单优化器、单数据源的最小抽象DefaultTrainer内置学习率调度、日志、评估、断点续训等标准默认行为适合常规训练但官方也坦言它较难支持研究中的非标准行为。要定制训练循环两条路径与DefaultTrainer行为相近时子类化并覆写其方法tools/train_net.py 即如此需要全新逻辑时从plain_train_net.py出发自行实现。指标日志通过集中式EventStorage完成from detectron2.utils.events import get_event_storage # inside the model: if self.training: value # compute the value from inputs storage get_event_storage() storage.put_scalar(some_accuracy, value)指标随后由各类EventWriter写到不同目的地终端、tensorboard、json 等DefaultTrainer已默认启用若干 writer。OOTDiffusion 中的端到端证据从配置到人体解析输出回到 OOTDiffusion 本身上述扩展能力最终服务于虚拟试穿的前处理——人体解析。仓库通过 parsing_api.py即 preprocess/humanparsing/parsing_api.py把 detectron2 训练好的模型封装为可直接调用的 API其关键流程包括读取人体解析 logits通过np.argmax(logits_result, axis2)得到逐像素类别delete_irregular基于上衣类别 4与连衣裙类别 7轮廓的重心位置判定穿着类型dresses或cloth_pant并把不可能出现的类别 logits 置为 -1从而剔除不规则解析结果hole_fill / refine_mask / refine_hole用 floodFill 填充衣服区域空洞、按面积筛选轮廓并保留上衣与手臂之间的大面积补洞区域最终输出干净的人体解析 maskonnx_inference分别以 512×512 与 473×473 两个输入尺寸运行解析模型与颈部/嘴唇辅助模型把颈部类别18与手臂类别14/15等细节回填最后通过get_palette(19)生成带调色板的解析可视化图与face_mask。这套逻辑与parsing_inference.yaml中的_BASE_继承、单类别 R-CNN 设置形成了完整的闭环配置层cfg驱动决定了模型结构与数据源API 层显式参数的小积木负责把模型输出加工成下游试穿模块真正需要的解析 mask。若你需要在自己的项目里复用这套能力只需参考 run/run_ootd.py 与 run/gradio_ootd.py 的调用方式把parsing_api.py接到你的输入图片目录即可。扩展方法论小结回顾 extend.md 的原始骨架扩展 detectron2 的完整决策路径可以归纳为只用标准行为→ 阅读 getting_started.md加载配置、调用build_*系列即可换数据→ 注册数据集DatasetCatalogMetadataCatalog必要时用register_coco_instances并同步修改cfg.DATASETS.*与类别数配置换数据变换/加载逻辑→ 自定义mapper传入build_detection_{train,test}_loader或彻底重写数据加载器换模型组件→ 利用各类*_REGISTRY注册自定义 backbone、ROI heads 等换训练方式→ 子类化DefaultTrainer或从plain_train_net.py自写循环。两类接口cfg 驱动 显式参数加上实验性的configurable桥梁保证了标准路径易用、非常规路径可行。对 OOTDiffusion 这样以研究为目标的项目而言这份内嵌的 detectron2 既是人体解析模型的运行底座也是理解如何在不破坏官方默认能力的前提下做深度定制的最佳教材。【免费下载链接】OOTDiffusion[AAAI 2025] Official implementation of OOTDiffusion: Outfitting Fusion based Latent Diffusion for Controllable Virtual Try-on项目地址: https://gitcode.com/GitHub_Trending/oo/OOTDiffusion创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表