9 Commits
Author SHA1 Message Date
Shaun ZhouandClaude Opus 5 29ff7a2c9b docs: 清掉失效的 train.py 引用与 ONNX 导出依赖组
仓库里从来没有 train.py / eval.py,入口是 classify.py 与 detect.py。

- README 的计算后端与 SwanLab 示例改用 classify.py,看板路径跟着 work_dir
  改为 runs/classify/swanlog。
- 删掉"train.py 的 train.restart_schedule 同理":restart_schedule 只在
  engine/simclr.py 里实现,分类训练没有这个选项。
- 目录表里 configs/ 的子目录(原写 model/ dataset/ train/ eval/)与 scripts/
  的描述改成实际内容;入口那行补上 detect.py。
- 导出走 OpenVINO,没有脚本用到 onnx/onnxscript,删掉 export 依赖组。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-08 14:57:11 +08:00
xzhou cc053a6e9c fix(deps): add label-studio dependency in pyproject.toml 2026-09-15 08:26:46 +00:00
Shaun ZhouandClaude Opus 5 8dc2fe6a2e feat(detect): 把弱监督框数据集链接到 data/ 并接上 YOLO 训练
第五步产出的框标签按类别分目录,便于人工核对;检测训练要的是 train/val
划分——类别写在标签第一列,不靠目录名。补上两个入口:

- scripts/prepare_yolo_dataset.py:拍平类别目录、按类别分层切分、硬链接到
  data/。分层是必需的,black 只有 53 张,随机切容易让小类在验证集里挂零。
  无框的图默认保留(检测训练里是压低误检的负样本);拍平后的同名冲突直接
  报错而不是静默覆盖。
- detect.py + configs/detect/film.yaml:包一层 ultralytics,沿用本仓库的
  配置继承、设备解析与 SwanLab 可视化。

选 YOLOv8 而不是 v11/v12:CLAUDE.md 限定只用 convolution 模型,YOLO11 骨架
里有 C2PSA、YOLO12 以注意力为主,只有 v8 的 C2f + SPPF 是纯卷积。
mosaic/mixup 关掉——每张图只有一个弱监督框,拼接后小目标被缩得更小,对
blackdot/whitedot 这类只占千分之几面积的类别是净伤害。

ultralytics 的 project 必须传绝对路径,相对路径会被它再拼到全局 settings
的 runs_dir 上,产出会跑到 runs/detect/runs/detect/<name> 去。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-11 12:05:50 +08:00
Shaun ZhouandClaude Opus 5 9aa87d31a6 feat(localization): SHAP Partition 定位方法,并把每图框数上限默认收紧为 1
新增基于 SHAP Partition explainer 的定位,与 Grad-CAM 形成互补对照:

- engine/shap_explain.py:对目标类别求 SHAP 归因(只保留正贡献),以及方框平滑。
  遮挡用数值 masker 而非教程里的 inpaint_telea——后者依赖 opencv,而我们的图已做过
  逐图标准化,用 0(即该图均值)遮挡语义更干净
- scripts/shap_boxes.py:按类别抽样生成标签,并输出「原图 | Grad-CAM | SHAP」并排图
- shap 放入可选依赖组:uv sync --group explain

实测(225 张,每类 15):SHAP 在小目标类别上明显更准,框面积占比
blackdot 0.019 vs 0.269(14 倍)、mosquito 0.030 vs 0.173、whitedot 0.076 vs 0.253。
原因是 Grad-CAM 受限于 8x8 特征图(每格 16x16 像素),几像素的黑点根本不可分辨。
代价是单张 0.55 秒,全量 11k 张约 1.7 小时,而 Grad-CAM 全量只要 2 分钟。

调参时发现的坑:SHAP 第一版全部出 0 框,因为沿用了给 8x8 调的
min_area_ratio=0.02(在 128x128 上等于 328 像素)。参数不能跨分辨率照搬,
SHAP 默认改为 0.002。

--max-boxes 两个脚本都默认改为 1(原为 2):一张裁片通常只对应一处缺陷。
库函数 cam_to_boxes 的默认值同步收紧,相关测试改为显式传参而不依赖默认值。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-10 16:10:50 +08:00
xzhou 703ba7076b fix(configs): update num_clusters and training parameters in film_simclr_resnet18.yaml 2026-09-04 13:41:41 +00:00
Shaun ZhouandClaude Opus 5 e4bd794025 feat(cluster): 输出簇分布图,直观展示簇间距离
在 preview 拼图的同级目录生成 cluster_scatter.png:
- 左:聚类空间的 PCA 二维投影,散点按簇着色 + 质心标记,标题标注两个主成分的方差占比
- 右:质心两两距离矩阵(在聚类空间里算,不是投影后),带数值标注

投影用 PCA 而不是 t-SNE/UMAP——后两者为了把簇拉开会扭曲簇间距离,
而这张图的目的就是看距离。

- ClusterResult 新增 points 字段,保留 KMeans 实际使用的空间供可视化复用,
  质心与散点用同一组主成分变换,避免质心飘到簇外
- summary.json 新增 centroid_distances
- 新增 scatter 配置块(enabled / max_points / point_size / alpha / figsize / dpi)
- 中文字体按 PingFang / Noto Sans CJK 等顺序探测,找不到自动退回英文标签,
  不会画成豆腐块
- 新增依赖 matplotlib

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 15:09:35 +08:00
xzhou a92d1125d4 fix: uv 换源至清华源 2026-09-04 06:26:16 +00:00
Shaun ZhouandClaude Opus 5 be6173c746 feat(simclr): 接入 SwanLab 可视化,并补上本地看板缺失的依赖
- SimCLRTrainer 记录 simclr/loss、loss_avg、lr(按 step)与 epoch_loss、
  epoch_seconds、gpu_mem_peak_mb(按 epoch),超参为完整 yaml 配置;
  正常结束与 KeyboardInterrupt 两条路径都会 finish()
- 配置新增 simclr.swanlab(字段同 train.swanlab),默认 mode: local,
  不需要登录,日志写到 <work_dir>/swanlog
- 依赖改为 swanlab[dashboard]:此前 `swanlab watch` 在干净环境里会报
  "Please install the swanboard package",README 里检测训练那节的看板命令
  同样受影响,现已随 uv sync 装好
- README 补齐本地看板/云端/离线补传三种用法与端口、局域网参数

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-03 09:24:39 +08:00
Shaun ZhouandClaude Opus 5 0645fc19f7 chore: 初始化 uv 项目配置与忽略规则
- pyproject.toml 采用 uv 应用模式(package = false),直接从仓库根运行入口脚本
- 依赖:torch / torchvision / numpy / pillow / pyyaml / swanlab
- dev 组含 pytest 与 ruff,export 组按需安装 onnx / onnxscript
- 忽略数据集本体、runs/ 训练产物、权重与 .DS_Store

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