feat(cluster): 加 --train-only,自监督训练与聚类可分两步跑

engine/simclr.py 与 engine/cluster.py 本来就互不引用,唯一接口是
simclr_backbone.pth;耦合只在 CLI——method=simclr 会训练完直接聚类。
此前"只聚类"可以用 simclr.checkpoint 做到,"只训练"没有办法。

- --train-only:训练存完权重即退出,不抽特征也不聚类,并打印下一步的聚类命令
- 与 method=pretrained / simclr.checkpoint / --sweep-k 组合时立刻报错说明原因,
  而不是跑完才发现没有产出
- 典型用法:GPU 机器上 --train-only 跑几十小时,之后拿权重反复调 k,每次约 1 分钟

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Shaun Zhou
2026-09-07 11:38:59 +08:00
co-authored by Claude Opus 5
parent 5d395b7c25
commit 0f5bb4a5c0
3 changed files with 149 additions and 1 deletions
+22
View File
@@ -359,6 +359,28 @@ uv run python scripts/cluster_unlabeled.py --config configs/cluster/film.yaml \
> **`checkpoint`** = 有权重就**跳过训练**直接聚类(要 `simclr_backbone.pth`)。
> 拿 `simclr_backbone.pth` 去 `resume` 会报错,因为它不含投影头和优化器状态。
#### 训练与聚类分开跑
自监督训练和聚类在代码上本来就是解耦的(`engine/simclr.py` 与 `engine/cluster.py`
互不引用,唯一接口是 `simclr_backbone.pth`),只是默认一条命令串起来跑。
需要分两步时——比如在 GPU 机器上专心训练几十小时,之后在别处反复调 k——用
`--train-only` 断开:
```bash
# 第一步:只训练,存完权重就退出,不抽特征也不聚类
uv run python scripts/cluster_unlabeled.py --config configs/cluster/film_simclr_resnet18.yaml \
--work-dir runs/simclr_r18 --train-only --set simclr.epochs=40
# 第二步:只聚类,想换几次 k 就跑几次,每次约 1 分钟
uv run python scripts/cluster_unlabeled.py --config configs/cluster/film_simclr_resnet18.yaml \
--work-dir runs/simclr_r18_k4 \
--set simclr.checkpoint=runs/simclr_r18/simclr_backbone.pth --num-clusters 4
```
第一步只产出 `simclr_backbone.pth` 与 `simclr_last.pth`,没有 `assignments.csv` 之类。
`--train-only` 遇到 `method=pretrained`(没东西可训)、`simclr.checkpoint`(会跳过训练)
或 `--sweep-k`(要靠聚类才能扫)都会直接报错,不会跑完才发现什么都没产出。
#### 第二步:复用权重重新聚类
想换簇数或改聚类参数时**不必重训**——把权重路径填进 `simclr.checkpoint` 就会跳过训练