7 Commits
Author SHA1 Message Date
Shaun ZhouandClaude Opus 5 ddd77653b5 fix(detect): 推理尺寸与训练尺寸不一致时报警
用 640 整图训练的权重跑 160 切片推理,结果看起来完全正常——照常出框、照常有置信度,
但类别系统性地错:实测 mosquito 的 TP 归零,760 张里 599 张被判成 blackdot,
而同一权重整图推理时 mosquito 有 92% 判对。这种错误不会自己暴露。

从 checkpoint 里读训练时的 imgsz,与当前切片尺寸不符就警告。三个调用点都接上:
可视化、批量推送预测、ML backend 加载权重时。visualize 的 summary.json 也补上
tile_size / tile_overlap,免得事后分不清某次产出是怎么跑的。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-24 15:33:41 +08:00
Shaun ZhouandClaude Opus 5 474b7b50a0 feat(detect): 推理侧改为切片,与固定 160 输入一致
训练数据已经是固定边长的片,推理还把整图交给 ultralytics 就会被 letterbox 缩放,
与模型见过的形态不符。三个调用方(可视化、批量推送预测、ML backend)统一改成
切片推理再拼回原图。

- engine/tiling.merge_tiles / tiled_predict:映射回原图、裁掉镜像填充区的框、跨片去重。
  推理框架留在调用方,几何部分可单测。
- engine/detection.nms:标准 NMS,另加按包含比例抑制。缺陷被切割线切开时,相邻片
  只看到一角,给出的小残框与完整框 IoU 很小(面积悬殊),光靠 IoU 压不掉。
- engine/tiled_inference:ultralytics 的接线,内部分批,避免片数多时 OOM。
- 三处调用点加 --tile-size / --tile-overlap(后端为 YOLO_TILE_SIZE / YOLO_TILE_OVERLAP),
  默认 160 / 32;设 0 退回整图推理,仅用于和旧模型对比。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-23 15:12:35 +08:00
Shaun ZhouandClaude Opus 5 154677032f Revert "约束预测框互不重叠"(eba533a、9439cbb)
去掉强制非重叠:detect.py 不再给 DetectionValidator.postprocess 打补丁,
配置里移除 train.max_overlap 与 agnostic_nms,可视化脚本恢复为直接使用模型原始输出,
engine/detection 里的 suppress_overlaps / filter_overlapping_outputs 一并移除。

约束会把 mAP50 从 0.555 压到 0.483(precision 0.536->0.612),代价是按置信度抑制时
高分错框会压掉本可命中的低分框。需要时用 git revert 这次提交即可取回。

按类别分目录的可视化产出结构(36fff98)保留。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 15:34:13 +08:00
Shaun ZhouandClaude Opus 5 36fff984b7 refactor(detect): 可视化产出改为按类别分目录,与 generate_boxes 一致
原先按 split 和结果类型(ok/missed/extra/none)分目录,层级太深。改成
<类别>/<图名>.png,与 runs/boxes_shap 的结构一致。类别取真值里框最多的那个;
负样本没有真值框,按文件名前缀归类(<类别>_<序号> 是 prepare_label_studio 的命名),
认不出来放 background/。

split 与结果类型仍记在 index.csv 的列里,排序筛选即可。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 15:06:13 +08:00
Shaun ZhouandClaude Opus 5 eba533a5b2 feat(detect): 约束预测框互不重叠
人工标注的真值里一处缺陷只有一个框:11211 张图、151 张多框图,重叠框对为 0。
而模型预测在验证集上有 6.9% 的图存在重叠框——NMS 只在同类内、按固定 IoU 阈值抑制,
压不掉两类情况:同一处缺陷被两个类别各框一次(实测 IoU 高达 0.99),以及 IoU 低于
NMS 阈值的同类重叠(grease 66 对、wrinkle 45 对)。

- engine/detection.suppress_overlaps:按置信度贪心保留互不重叠的框,可设允许的
  最大 IoU;另可丢弃被大框完全包住的小框(面积悬殊时 IoU 很小,但显然是重复表达)。
- visualize_detections 默认 --max-overlap 0(与真值一致),并放出 --nms-iou 与
  类别无关 NMS 开关;--max-overlap -1 可看模型原始输出。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 11:19:47 +08:00
Shaun ZhouandClaude Opus 5 43c8c4a179 fix(detect): 可视化推理自己按批切分,避免 CUDA OOM
model.predict 不理会传入的 batch 参数,把整个图片列表当成一个 batch,8969 张图在
16 GiB 显卡上直接 OOM(单次要分配 10.27 GiB)。改成自己按 --batch 切片调用。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 21:47:44 +08:00
Shaun ZhouandClaude Opus 5 788bc36ab8 feat(detect): 全量推理可视化,预测框与真值框画在一起
scripts/visualize_detections.py:在整个数据集上推理,绿=真值、蓝=命中的预测、
红=没对上真值的预测,按结果类型分目录(ok / missed / extra / none),再配一份
index.csv(逐图的真值数、预测数、命中数、最高置信度)与 summary.json(逐类 TP/FP/FN)。
--only errors 只输出有问题的图。

匹配逻辑放在 engine/detection.py:按置信度贪心、IoU 阈值、类别需一致,与 mAP 的规则
一致,所以图上看到的漏检误检和指标算的是同一回事。same_class=False 可以单看定位准不准
——定位对但分类错,和完全没找到是两种问题。

train 与 val 分开放:训练集的图模型见过,那部分结果不能当泛化能力看。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 21:47:02 +08:00