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>
This commit is contained in:
co-authored by
Claude Opus 5
parent
6e746b7351
commit
ddd77653b5
@@ -16,6 +16,41 @@ from engine.detection import Box
|
||||
from engine.tiling import tiled_predict
|
||||
|
||||
|
||||
def training_imgsz(model) -> int | None:
|
||||
"""权重里记录的训练输入尺寸;读不到返回 None。
|
||||
|
||||
ultralytics 把训练参数存在 checkpoint 里,推理时可以取回来核对。
|
||||
"""
|
||||
for source in (
|
||||
getattr(model, "ckpt", None) or {},
|
||||
getattr(model, "overrides", None) or {},
|
||||
):
|
||||
value = source.get("train_args", source).get("imgsz") if isinstance(source, dict) else None
|
||||
if isinstance(value, int):
|
||||
return value
|
||||
return None
|
||||
|
||||
|
||||
def check_size_matches(model, size: int, logger=None) -> str | None:
|
||||
"""推理尺寸与训练尺寸不一致时给出警告文本(一致或读不到则返回 None)。
|
||||
|
||||
这一条是有代价换来的:用 640 整图训练的模型去跑 160 的切片推理,结果**看起来正常**
|
||||
——照样出框、照样有置信度,但类别系统性地错(实测 mosquito 全部变成 blackdot,
|
||||
TP 为 0)。不主动核对的话,这种结果会被当成模型退化去查很久。
|
||||
"""
|
||||
trained = training_imgsz(model)
|
||||
if trained is None or size <= 0 or trained == size:
|
||||
return None
|
||||
message = (
|
||||
f"权重是按 imgsz={trained} 训练的,现在按 {size} 切片推理——两者不一致,"
|
||||
f"结果不可信(会照常出框,但类别系统性地错)。"
|
||||
f"要么换成按 {size} 训练的权重,要么用 --tile-size 0 退回整图推理"
|
||||
)
|
||||
if logger is not None:
|
||||
logger.warning("%s", message)
|
||||
return message
|
||||
|
||||
|
||||
def predict_image(
|
||||
model,
|
||||
image: np.ndarray,
|
||||
|
||||
Reference in New Issue
Block a user