Files
RoRD-Layout-Recognation/docs/NextStep.md
2025-09-25 22:05:39 +08:00

12 KiB
Raw Blame History

本地 TensorBoard 实验追踪方案

日期2025-09-25

目标

  • 在本地工作站搭建一套轻量、低成本的实验追踪与可视化管道,覆盖训练、评估和模板匹配流程。
  • 结合现有 YAML 配置体系,为后续扩展(自动化调参、远程同步)保留接口。

环境与前置准备

  1. 系统与软件
    • 操作系统Ubuntu 22.04 / Windows 11 / macOS 14任选其一
    • Python 环境:使用项目默认的 uv 虚拟环境(见 uv.lock / pyproject.toml)。
  2. 依赖安装
    uv add tensorboard tensorboardX
    
  3. 目录规划
    • 在项目根目录创建 runs/,建议按 runs/<experiment_name>/ 组织日志。
    • 训练与评估可分别输出到 runs/train/runs/eval/ 子目录。

集成步骤

1. 配置项扩展

  • configs/base_config.yaml 中添加:
    logging:
      use_tensorboard: true
      log_dir: "runs"
      experiment_name: "baseline"
    
  • 命令行新增 --log-dir--experiment-name 参数,默认读取配置,可在执行时覆盖。

2. 训练脚本 train.py

  1. 初始化 SummaryWriter
    from torch.utils.tensorboard import SummaryWriter
    
    log_dir = Path(args.log_dir or cfg.logging.log_dir)
    experiment = args.experiment_name or cfg.logging.experiment_name
    writer = SummaryWriter(log_dir=log_dir / "train" / experiment)
    
  2. 记录训练指标(每个 iteration
    global_step = epoch * len(train_dataloader) + i
    writer.add_scalar("loss/total", loss.item(), global_step)
    writer.add_scalar("loss/det", det_loss.item(), global_step)
    writer.add_scalar("loss/desc", desc_loss.item(), global_step)
    writer.add_scalar("optimizer/lr", scheduler.optimizer.param_groups[0]['lr'], global_step)
    
  3. 验证阶段记录
    • Epoch 结束后写入平均损失、F1 等指标。
    • 可视化关键点热力图、匹配示意图:writer.add_image()
  4. 资源清理
    • 训练结束调用 writer.close()

3. 评估脚本 evaluate.py

  1. 初始化 SummaryWriter(log_dir / "eval" / experiment)
  2. 收集所有验证样本的预测框 (boxes)、置信度 (scores) 与真实标注 (ground truth boxes)。
  3. 使用 sklearn.metrics.average_precision_scorepycocotools 计算每个样本的 Average Precision并汇总为 mAP
    from sklearn.metrics import average_precision_score
    ap = average_precision_score(y_true, y_scores)
    writer.add_scalar("eval/AP", ap, global_step)
    
  4. 在成功匹配IoU ≥ 阈值)后,从 match_template_multiscale 返回值中获取单应矩阵 H
  5. 使用 cv2.decomposeHomographyMat 或手动分解方法,将 H 提取为旋转角度、平移向量和缩放因子:
    _, Rs, Ts, Ns = cv2.decomposeHomographyMat(H, np.eye(3))
    rot_angle = compute_angle(Rs[0])
    trans_vec = Ts[0]
    scale = np.linalg.norm(Ns[0])
    
  6. 从标注文件中读取真实几何变换参数 (rotation_gt, trans_gt, scale_gt),计算误差:
    err_rot = abs(rot_angle - rotation_gt)
    err_trans = np.linalg.norm(trans_vec - trans_gt)
    err_scale = abs(scale - scale_gt)
    writer.add_scalar("eval/err_rot", err_rot, img_id)
    writer.add_scalar("eval/err_trans", err_trans, img_id)
    writer.add_scalar("eval/err_scale", err_scale, img_id)
    
  7. 使用 writer.add_histogram 记录误差分布,并通过 writer.add_image 可选地上传误差直方图:
    writer.add_histogram("eval/err_rot_hist", err_rot_list, epoch)
    
  8. 在 TensorBoard 的 Scalars、Histograms 和 Images 面板中分别查看指标曲线、误差分布及可视化结果。

4. 模板匹配调试 match.py

  • 新增参数 --tb-log-matches(布尔值)。
  • 启用后将关键点分布、Homography 误差统计写入 runs/match/<experiment>/

可视化与使用

  1. 启动 TensorBoard
    tensorboard --logdir runs --port 6006
    
    • 浏览器访问 http://localhost:6006
    • 若需局域网共享可加 --bind_all
  2. 推荐面板布局
    • Scalars损失曲线、学习率、评估指标。
    • Images关键点热力图、模板匹配结果。
    • Histograms描述子分布、梯度范数可选
    • Text记录配置摘要、Git 提交信息。

版本控制与组织

  • 实验命名建议采用 YYYYMMDD_project_variant,方便检索。
  • 使用 writer.add_text() 保存关键配置和 CLI 参数,形成自描述日志。
  • 可开发 tools/export_tb_summary.py 导出曲线数据供文档或汇报使用。

进阶扩展

  1. 自动化脚本:在 Makefile / tasks.json 中增加命令,一键启动训练 + TensorBoard。
  2. 远程访问:通过 ssh -Lngrok 转发端口,注意访问权限控制。
  3. 对比实验:利用 TensorBoard Compare Runs 功能或统一父目录对比多次实验。
  4. CI 集成:在持续集成流程中生成日志,作为构建工件保存。

验证与维护

  • 功能自测:运行 12 个 epoch确认日志生成并正确展示。
  • 存储监控:定期清理或压缩旧实验,避免磁盘占满。
  • 备份策略:重要实验可打包日志或同步至远程仓库。
  • 团队培训:在 README 中补充使用说明,组织示例演示。

下一步

  • 修改配置和脚本,接入 SummaryWriter。
  • 准备示例 Notebook/文档,展示 TensorBoard 面板截图。
  • 后续评估是否需要接入 W&B、MLflow 等更高级平台。

推理与匹配改造计划FPN + NMS

日期2025-09-25

目标

  • 将当前的“图像金字塔 + 多次推理”的匹配流程,升级为“单次推理 + 特征金字塔 (FPN)”以显著提速。
  • 在滑动窗口提取关键点后增加去重NMS/半径抑制),降低冗余点与后续 RANSAC 的计算量。
  • 保持与现有 YAML 配置、TensorBoard 记录和命令行接口的一致性;以 uv 为包管理器管理依赖和运行。

设计概览

  • FPNmodels/rord.py 中,从骨干网络多层提取特征(例如 VGG 的 relu2_2/relu3_3/relu4_3通过横向 1x1 卷积与自顶向下上采样构建 P2/P3/P4 金字塔特征;为每个尺度共享或独立地接上检测头与描述子头,导出同维度描述子。
  • 匹配路径:match.py 新增 FPN 路径,单次前向获得多尺度特征,逐层与模板进行匹配与几何验证;保留旧路径(图像金字塔)作为回退,通过配置开关切换。
  • 去重策略:在滑窗聚合关键点后,基于“分数优先 + 半径抑制 (radius NMS)”进行去重;半径和分数阈值配置化。

配置变更YAML

configs/base_config.yaml 中新增/扩展:

model:
   fpn:
      enabled: true            # 开启 FPN 推理
      out_channels: 256        # 金字塔特征通道数
      levels: [2, 3, 4]        # 输出层级,对应 P2/P3/P4
      norm: "bn"              # 归一化类型bn/gn/none

matching:
   use_fpn: true              # 使用 FPN 路径false 则沿用图像金字塔
   nms:
      enabled: true
      radius: 4                # 半径抑制像素半径
      score_threshold: 0.5     # 关键点保留的最低分数
   # 其余已有参数保留,如 ransac_reproj_threshold/min_inliers/inference_window_size...

注意:所有相对路径依旧使用 utils.config_loader.to_absolute_path 以配置文件所在目录为基准解析。

实施步骤

  1. 基线分支与依赖
  • 新开分支保存改造:
    git checkout -b feature/fpn-matching
    uv sync
    
  • 目前不引入新三方库,继续使用现有 torch/opencv/numpy
  1. 模型侧改造(models/rord.py
  • 提取多层特征:在骨干网络中暴露中间层输出(如 C2/C3/C4
  • 构建 FPN
    • 使用 1x1 conv 降维对齐通道;
    • 自顶向下上采样并逐级相加;
    • 3x3 conv 平滑,得到 P2/P3/P4
    • 可选归一化BN/GN
  • 头部适配:复用或复制现有检测头/描述子头到每个 P 层,输出:
    • det_scores[L]B×1×H_L×W_L
    • descriptors[L]B×D×H_L×W_LD 与现有描述子维度一致)
  • 前向接口:
    • 训练模式:维持现有输出以兼容训练;
    • 匹配/评估模式:支持 return_pyramid=True 返回 {P2,P3,P4} 的 det/desc。
  1. 匹配侧改造(match.py
  • 配置读取:根据 matching.use_fpn 决定走 FPN 或旧图像金字塔路径。
  • FPN 路径:
    • 对 layout 与 template 各做一次前向,获得 {det, desc}×L
    • 对每个层级 L
      • 从 det_scores[L] 以 score_threshold 抽取关键点坐标与分数;
      • 半径 NMS 去重(见步骤 4
      • 使用 desc[L] 在对应层做特征最近邻匹配(可选比值测试)并估计单应性 H_LRANSAC
    • 融合多个层级的候选:选取内点数最多或综合打分最佳的实例;
    • 将层级坐标映射回原图坐标;输出 bbox 与 H。
  • 旧路径保留:若 use_fpn=false,继续使用当前图像金字塔多次推理策略,便于回退与对照实验。
  1. 关键点去重NMS/半径抑制)
  • 输入:关键点集合 K = {(x, y, score)}。
  • 算法:按 score 降序遍历,若与已保留点的欧氏距离 < radius 则丢弃,否则保留。
  • 复杂度O(N log N) 排序 + O(N·k) 检查k 为邻域个数,可通过网格划分加速)。
  • 参数:matching.nms.radiusmatching.nms.score_threshold
  1. TensorBoard 记录(扩展)
  • Scalars
    • match_fpn/level_L/keypoints_before_nmskeypoints_after_nms
    • match_fpn/level_L/inliersbest_instance_inliers
    • match_fpn/instances_foundruntime_ms
  • Text/Image
    • 关键点可视化(可选),最佳实例覆盖图;
    • 记录使用的层级与最终选中尺度信息。
  1. 兼容性与回退
  • 通过 YAML matching.use_fpn 开关控制路径;
  • 保持 CLI 不变,新增可选 --fpn-off(等同 use_fpn=false仅作为临时调试
  • 若新路径异常可快速回退旧路径,保证生产可用性。

开发里程碑与工时预估

  • M10.5 天):配置与分支、占位接口、日志钩子。
  • M21.5 天FPN 实现与前向接口;单图 smoke 测试。
  • M31 天):match.py FPN 路径、尺度回映射与候选融合。
  • M40.5 天NMS 实现与参数打通;
  • M50.5 天TensorBoard 指标与可视化;
  • M60.5 天):对照基线的性能与速度评估,整理报告。

质量门禁与验收标准

  • 构建:uv sync 无错误;python -m compileall 通过;
  • 功能:在 23 张样例上FPN 路径输出的实例数量与旧路径相当或更优;
  • 速度相同输入FPN 路径总耗时较旧路径下降 ≥ 30%
  • 稳定性:无异常崩溃;在找不到匹配时能优雅返回空结果;
  • 指标TensorBoard 中关键点数量、NMS 前后对比、内点数、总实例数与运行时均可见。

快速试用(命令)

# 同步环境
uv sync

# 基于 YAML 启用 FPN 匹配(推荐)
uv run python match.py \
   --config configs/base_config.yaml \
   --layout /path/to/layout.png \
   --template /path/to/template.png \
   --tb_log_matches

# 临时关闭 FPN对照实验
# 可通过把 configs 中 matching.use_fpn 设为 false或后续提供 --fpn-off 开关

# 打开 TensorBoard 查看匹配指标
uv run tensorboard --logdir runs

风险与回滚

  • FPN 输出与原检测/描述子头的维度/分布不一致,需在实现时对齐通道与归一化;
  • 多层融合策略(如何选取最佳实例)可能影响稳定性,可先以“内点数最大”作为启发式;
  • 如出现精度下降或不稳定,立即回退 matching.use_fpn=false,保留旧流程并开启数据记录比对差异。