ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

MMSegmentation 1.x 特征图与分割结果可视化:WandbVisBackend 配置与实战

MMSegmentation 1.x 特征图与分割结果可视化:WandbVisBackend 配置与实战 MMSegmentation 1.x 特征图与分割结果可视化WandbVisBackend 配置与实战【免费下载链接】mmsegmentationOpenMMLab Semantic Segmentation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmsegmentationMMSegmentation 1.x 提供了 Weights Biaseswandb后端支持用于对语义分割模型的测试结果、真实标注GT以及网络前向过程中的特征图进行统一的可视化与管理。本文以官方用户指南为骨架结合mmseg/visualization/local_visualizer.py的源码实现完整讲解 wandb 环境配置、SegLocalVisualizer的使用原理、特征图录制与绘制脚本的逐段拆解以及可复制的命令行运行方式帮助你在一套脚本内完成「预测结果 特征图 GT 掩码」的 wandb 云端记录。一、Wandb 环境配置Weights Biases 是模型实验跟踪与可视化管理平台。安装与登录过程可参考官方快速入门文档核心步骤只有两步pip install wandb wandb loginpip install wandb安装 wandb Python 客户端库wandb login交互式登录会引导你输入 API Key可在 wandb 账户设置页获取登录成功后即可将实验数据上传到个人/团队项目空间。在配置文件中添加 WandbVisBackendMMSegmentation 的可视化后端vis backend通过vis_backends列表统一声明。以仓库默认运行时配置 configs/base/default_runtime.py 为例其默认内容为vis_backends [dict(typeLocalVisBackend)] visualizer dict( typeSegLocalVisualizer, vis_backendsvis_backends, namevisualizer)可见默认只启用了本地后端LocalVisBackend。要同时把可视化结果上传到 wandb只需在vis_backends中追加WandbVisBackendvis_backends [ dict(typeLocalVisBackend), dict(typeTensorboardVisBackend), dict(typeWandbVisBackend) ]按上述方式修改后SegLocalVisualizer在调用add_datasample/add_image时会把绘制结果同时分发给所有已注册的后端本地保存、TensorBoard 记录、wandb 上传。这也解释了为什么官方示例代码里只用了一个WandbVisBackend就能在 wandb 账户中看到结果——可视化后端是插拔式的按需组合即可。二、可视化原理SegLocalVisualizer 与 vis_backend 机制SegLocalVisualizer是 MMSegmentation 提供的语义分割专用可视化器继承自 MMEngine 的Visualizer类注册于 mmseg/visualization/local_visualizer.py 并通过 mmseg/visualization/init.py 对外导出。从源码可以看到它的核心能力set_dataset_meta设置classes与palette元信息默认回退到cityscapes数据集当dataset_name未指定时并断言类别数与调色板数量一致_draw_sem_seg把像素级分割图按类别调色板着色叠加到原图上alpha控制透明度文档示例取0.5源码默认0.8可选绘制类别文字标签add_datasample统一的绘制入口同时支持gt_sem_seg与pred_sem_seg以及gt_depth_map/pred_depth_map当 GT 与预测同时绘制时左右拼接展示draw_featmap特征图绘制方法继承自 MMEngineVisualizer支持channel_reduction如select_max等通道压缩策略源码中_draw_depth_map也复用了它。在训练或推理配置中visualizer字段的完整形态见 configs/base/default_runtime.py为visualizer dict( typeSegLocalVisualizer, vis_backendsvis_backends, namevisualizer)训练过程中框架会自动实例化该可视化器并记录日志而离线推理场景下我们可以在脚本中手动创建SegLocalVisualizer实例并显式传入vis_backends[dict(typeWandbVisBackend)]。三、完整示例推理结果与特征图录制脚本官方指南提供了一段完整的脚本原文档建议保存为feature_map_visual.py核心思路是用 PyTorch forward hook 记录指定中间层的前向输出作为特征图推理完成后统一交给SegLocalVisualizer绘制并上传 wandb。首先准备示例数据与权重Cityscapes 的一张图像、对应的 GT 标签图、以及 ANN 模型在 Cityscapes 上训练得到的检查点wget https://user-images.githubusercontent.com/24582831/189833109-eddad58f-f777-4fc0-b98a-6bd429143b06.png --output-document aachen_000000_000019_leftImg8bit.png wget https://user-images.githubusercontent.com/24582831/189833143-15f60f8a-4d1e-4cbb-a6e7-5e2233869fac.png --output-document aachen_000000_000019_gtFine_labelTrainIds.png wget https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r50-d8_512x1024_40k_cityscapes/ann_r50-d8_512x1024_40k_cityscapes_20200605_095211-049fc292.pth3.1 Recorder用 forward hook 录制特征图Recorder类实现了一个极简的「上下文管理器 hook 回调」class Recorder: record the forward output feature map and save to data_buffer. def __init__(self) - None: self.data_buffer list() def __enter__(self, ): self._data_buffer list() def record_data_hook(self, model: nn.Module, input: Type, output: Type): self.data_buffer.append(output) def __exit__(self, *args, **kwargs): passdata_buffer以列表保存每次前向的中间输出record_data_hook标准 PyTorch forward hook 签名(module, input, output)把output追加进缓冲__enter__/__exit__实现上下文管理器协议配合with recorder:使用方便控制录制的生命周期。录制时不修改模型任何参数仅通过module.register_forward_hook(recorder.record_data_hook)挂接回调这是理解该脚本「零侵入录制特征图」的关键。3.2 visualize把结果、特征图与 GT 绘制到 wandbvisualize函数负责创建可视化器并完成三类内容的绘制def visualize(args, model, recorder, result): seg_visualizer SegLocalVisualizer( vis_backends[dict(typeWandbVisBackend)], save_dirtemp_dir, alpha0.5) seg_visualizer.dataset_meta dict( classesmodel.dataset_meta[classes], palettemodel.dataset_meta[palette]) image mmcv.imread(args.img, color) seg_visualizer.add_datasample( namepredict, imageimage, data_sampleresult, draw_gtFalse, draw_predTrue, wait_time0, out_fileNone, showFalse) # add feature map to wandb visualizer for i in range(len(recorder.data_buffer)): feature recorder.data_buffer[i][0] # remove the batch drawn_img seg_visualizer.draw_featmap( feature, image, channel_reductionselect_max) seg_visualizer.add_image(ffeature_map{i}, drawn_img) if args.gt_mask: sem_seg mmcv.imread(args.gt_mask, unchanged) sem_seg torch.from_numpy(sem_seg) gt_mask dict(datasem_seg) gt_mask PixelData(**gt_mask) data_sample SegDataSample() data_sample.gt_sem_seg gt_mask seg_visualizer.add_datasample( namegt_mask, imageimage, data_sampledata_sample, draw_gtTrue, draw_predFalse, wait_time0, out_fileNone, showFalse) seg_visualizer.add_image(image, image)逐段说明实例化可视化器vis_backends[dict(typeWandbVisBackend)]指定 wandb 后端save_dirtemp_dir作为本地缓存目录alpha0.5控制分割掩码叠加透明度注入数据集元信息直接复用模型加载时携带的model.dataset_meta包含classes与palette保证类别名与配色与训练时一致。这一赋值操作在 local_visualizer.py 的set_dataset_meta中完成未指定dataset_name时默认使用cityscapes绘制预测结果add_datasample(namepredict, ...)draw_gtFalse, draw_predTrue表示只画预测。传入的data_sample是inference_model返回的SegDataSample其pred_sem_seg字段会被 add_datasample 内部处理并着色绘制特征图遍历recorder.data_buffer取recorder.data_buffer[i][0]去掉 batch 维度调用继承自 MMEngine 的draw_featmap(feature, image, channel_reductionselect_max)将高维特征压缩绘制为可读图像再以feature_map{i}为名上传绘制 GT 掩码可选--gt_mask传入时用mmcv.imread(args.gt_mask, unchanged)读取标签图封装为PixelData并挂到SegDataSample.gt_sem_seg上再通过add_datasample(namegt_mask, draw_gtTrue, draw_predFalse)绘制记录原图最后add_image(image, image)把输入图像一并上传便于与预测、特征图对照查看。3.3 main初始化模型、选择目标层并注册 hookmain函数串起了整个流程def main(): parser ArgumentParser( descriptionDraw the Feature Map During Inference) parser.add_argument(img, helpImage file) parser.add_argument(config, helpConfig file) parser.add_argument(checkpoint, helpCheckpoint file) parser.add_argument(--gt_mask, defaultNone, helpPath of gt mask file) parser.add_argument(--out-file, defaultNone, helpPath to output file) parser.add_argument( --device, defaultcuda:0, helpDevice used for inference) parser.add_argument( --opacity, typefloat, default0.5, helpOpacity of painted segmentation map. In (0, 1] range.) parser.add_argument( --title, defaultresult, helpThe image identifier.) args parser.parse_args() register_all_modules() # build the model from a config file and a checkpoint file model init_model(args.config, args.checkpoint, deviceargs.device) if args.device cpu: model revert_sync_batchnorm(model) # show all named module in the model and use it in source list below for name, module in model.named_modules(): print(name) source [ decode_head.fusion.stages.0.query_project.activate, decode_head.context.stages.0.key_project.activate, decode_head.context.bottleneck.activate ] source dict.fromkeys(source) count 0 recorder Recorder() # registry the forward hook for name, module in model.named_modules(): if name in source: count 1 module.register_forward_hook(recorder.record_data_hook) if count len(source): break with recorder: # test a single image, and record feature map to data_buffer result inference_model(model, args.img) visualize(args, model, recorder, result)关键点命令行参数位置参数img图像路径、config配置文件、checkpoint权重文件可选参数--gt_mask、--out-file、--device默认cuda:0、--opacity默认0.5取值范围(0, 1]、--title默认result模型构建init_model(args.config, args.checkpoint, deviceargs.device)从配置与权重构建分割模型若指定 CPU 设备用revert_sync_batchnorm把 SyncBN 还原为普通 BN避免 CPU 推理出错模块枚举model.named_modules()打印全部子模块名方便你替换source列表选择自己想要观察的中间层例如 ANN 解码头中的 query/key 投影与 bottleneck动态注册 hook只对source中出现的模块调用register_forward_hook全部命中即提前退出循环上下文录制with recorder:包裹inference_model(model, args.img)保证只有这次推理的前向输出被收集随后交给visualize绘制。其中source里出现的decode_head.fusion/decode_head.context结构来自 ANNAsymmetric Non-local Neural Networks解码头设计在 configs/base/models/ann_r50-d8.py 中可以看到ANNHead的query_scales(1,)、key_pool_scales(1, 3, 6, 8)等配置其融合fusion与上下文context分支正是特征图可视化的典型观察对象。四、运行方式与命令行示例将脚本保存为feature_map_visual.py后通用执行格式为python feature_map_visual.py ${图像} ${配置文件} ${检查点文件} [可选参数]官方示例使用 ANN R50-D8 Cityscapes 配置并同时给出 GT 掩码python feature_map_visual.py \ aachen_000000_000019_leftImg8bit.png \ configs/ann/ann_r50-d8_4xb2-40k_cityscapes-512x1024.py \ ann_r50-d8_512x1024_40k_cityscapes_20200605_095211-049fc292.pth \ --gt_mask aachen_000000_000019_gtFine_labelTrainIds.png其中配置文件 configs/ann/ann_r50-d8_4xb2-40k_cityscapes-512x1024.py 由四部分_base_组合而成模型、Cityscapes 数据集、默认运行时、40k 调度并指定crop_size (512, 1024)_base_ [ ../_base_/models/ann_r50-d8.py, ../_base_/datasets/cityscapes.py, ../_base_/default_runtime.py, ../_base_/schedules/schedule_40k.py ] crop_size (512, 1024) data_preprocessor dict(sizecrop_size) model dict(data_preprocessordata_preprocessor)运行结束后以下内容会出现在 wandb 账户对应项目中predict语义分割预测结果叠加图feature_map0、feature_map1、feature_map2source中三个目标层的特征图select_max通道压缩后gt_mask真实标注可视化传入--gt_mask时image原始输入图像。五、注意事项与扩展建议选择目标层source列表需与当前模型的模块名精确匹配。不同模型FCN、PSPNet、UPerNet 等的 decode_head 结构不同建议先运行脚本打印named_modules()再挑选具体层名填入CPU 推理--device cpu时必须经过revert_sync_batchnorm否则 SyncBN 在单机 CPU 环境可能报错通道压缩策略draw_featmap的channel_reduction除select_max外还可按 MMEngineVisualizer支持的其他策略调整便于观察不同语义通道的激活区域离线保存若希望同时输出到本地可在vis_backends中同时加入LocalVisBackend或在add_datasample中指定out_file脚本已预留--out-file参数接口后端组合WandbVisBackend、TensorboardVisBackend、LocalVisBackend可任意组合训练阶段的日志与图像记录同样遵循 configs/base/default_runtime.py 中vis_backends的配置。通过本文的配置与脚本你可以在不改动任何模型源码的前提下把一次推理的预测结果、多个中间层特征图和真实标注一次性同步到 wandb为模型调试、注意力机制分析和论文实验记录提供完整的可视化证据链。【免费下载链接】mmsegmentationOpenMMLab Semantic Segmentation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmsegmentation创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表