实际工作流是:simclr 训练 -> 聚类 -> 人工归类 -> 分类训练 -> GradCAM/SHAP 生成
热力图与 box。据此移除不参与其中的检测/定位链路,共 31 个文件、约 2600 行:
- 模型:defect_net、postprocess、necks/、heads/center_head
- 数据:film_defect(YOLO 读取端)、target_encoder
- 引擎:trainer、evaluator、losses
- 入口:train.py、eval.py
- 脚本:convert_annotations、split_dataset、export_onnx、profile_inference
- 配置:configs/{train,eval,model,dataset}
- utils/labels(多类/单类标签模式,仅检测分类头使用)
共享模块按实际用量瘦身:engine/metrics 只留 AverageMeter(检测指标随之移除);
datasets/yolo 只留写出侧(IMAGE_SUFFIXES 与 write_data_yaml)——第 5 步产出的
YOLO 标签是给外部检测训练用的交换格式,读取端不再需要。
裁剪过程中修掉一个真 bug:generate_boxes 的 --stage 默认 6(layer3)对 tiny_conv
这类非 nn.Sequential 骨架直接抛异常。现在自动退回骨架最终输出并警告,
另加 --stage -1 显式选择最终输出。
五步工作流已端到端实跑验证(simclr 1 轮 -> 聚类 -> 导出 -> 分类 1 轮 ->
gradcam 与 shap 两种方法各生成一遍)。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
48 lines
1.2 KiB
Python
48 lines
1.2 KiB
Python
"""YOLO 数据集格式的共用定义。
|
|
|
|
工作流里只用到"写出"这一侧:scripts/generate_boxes.py 产出的
|
|
`labels/<类别>/<图名>.txt` 与 `data.yaml` 是给外部检测训练用的交换格式。
|
|
|
|
标注文件每行一个目标,坐标相对图像宽高归一化到 [0, 1],中心点格式:
|
|
|
|
```
|
|
<class_id> <cx> <cy> <w> <h>
|
|
```
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from collections.abc import Sequence
|
|
from pathlib import Path
|
|
|
|
IMAGE_SUFFIXES = (".png", ".jpg", ".jpeg", ".bmp", ".tif", ".tiff", ".webp")
|
|
|
|
|
|
def write_data_yaml(
|
|
path: str | Path,
|
|
classes: Sequence[str],
|
|
root: str | Path = ".",
|
|
train: str = "images/train",
|
|
val: str = "images/val",
|
|
) -> Path:
|
|
"""写一个 YOLO 风格的 data.yaml,字段与 ultralytics 通用。"""
|
|
import yaml
|
|
|
|
path = Path(path)
|
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
path.write_text(
|
|
yaml.safe_dump(
|
|
{
|
|
"path": str(root),
|
|
"train": train,
|
|
"val": val,
|
|
"nc": len(classes),
|
|
"names": dict(enumerate(classes)),
|
|
},
|
|
allow_unicode=True,
|
|
sort_keys=False,
|
|
),
|
|
encoding="utf-8",
|
|
)
|
|
return path
|