fix(cluster): 配置层级写错不再静默忽略,并始终打印生效的超参
聚类配置里 optimizer/epochs 等键都在 `simclr:` 段下。写到顶层会被完全忽略、 不报任何错——用户改了 lr 却毫无反应,极难排查。同样的坑还有:改了基类 configs/cluster/film.yaml 的 simclr.optimizer,但运行的是子配置 film_simclr_resnet18.yaml,子配置里的同名键会盖掉基类的修改。 - 顶层出现 optimizer / scheduler / epochs / temperature / projection / save_interval / resume / checkpoint / log_interval 时警告并给出正确写法 - method != simclr 却写了 simclr: 段时提示该段不会生效 - SimCLRTrainer 初始化时无条件打印实际生效的 epochs / temperature / optimizer / scheduler,不再只在续训时才打印 - 修掉一处假差异:旧存档没有 scheduler_cfg 字段时会误报 "scheduler None -> cosine", 那是"不知道"而非"当时没有调度器" 已验证 --set 覆盖、直接改 yaml、旧格式存档三条路径下 lr/weight_decay 均正常生效。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
105cb38831
commit
506fde0290
@@ -489,6 +489,57 @@ def _cluster_argv(work_dir, image_dir, *extra):
|
||||
]
|
||||
|
||||
|
||||
def test_warns_when_simclr_keys_are_at_top_level(tiny_image_dir, caplog):
|
||||
"""顶层写 optimizer 会被静默忽略,必须警告——否则"改了配置没反应"极难排查。"""
|
||||
import logging
|
||||
|
||||
sys.path.insert(0, "scripts")
|
||||
import cluster_unlabeled as cu
|
||||
|
||||
cfg = {
|
||||
"dataset": {"name": "unlabeled", "root": str(tiny_image_dir)},
|
||||
"optimizer": {"name": "adamw", "lr": 0.9}, # ← 应该放在 simclr: 下
|
||||
"epochs": 100, # ← 同上
|
||||
"simclr": {"epochs": 2},
|
||||
}
|
||||
with caplog.at_level(logging.WARNING, logger="mte"):
|
||||
cu.warn_misplaced_keys(cfg, "simclr")
|
||||
|
||||
assert "optimizer" in caplog.text and "epochs" in caplog.text
|
||||
assert "simclr" in caplog.text
|
||||
|
||||
|
||||
def test_no_warning_when_keys_are_correctly_nested(tiny_image_dir, caplog):
|
||||
import logging
|
||||
|
||||
sys.path.insert(0, "scripts")
|
||||
import cluster_unlabeled as cu
|
||||
|
||||
cfg = {"dataset": {"name": "unlabeled", "root": str(tiny_image_dir)},
|
||||
"simclr": {"optimizer": {"lr": 0.9}, "epochs": 2}}
|
||||
with caplog.at_level(logging.WARNING, logger="mte"):
|
||||
cu.warn_misplaced_keys(cfg, "simclr")
|
||||
assert "会被忽略" not in caplog.text
|
||||
|
||||
|
||||
def test_effective_hyperparams_are_logged_on_every_run(tiny_image_dir, tmp_path, caplog):
|
||||
"""不只是续训时——每次训练开始都要打印实际生效的超参。"""
|
||||
import logging
|
||||
|
||||
trainer = _make_trainer(
|
||||
tiny_image_dir, tmp_path / "run", epochs=1,
|
||||
optimizer={"name": "adamw", "lr": 0.00042, "weight_decay": 0.007},
|
||||
)
|
||||
del trainer
|
||||
with caplog.at_level(logging.INFO, logger="mte"):
|
||||
_make_trainer(
|
||||
tiny_image_dir, tmp_path / "run2", epochs=1,
|
||||
optimizer={"name": "adamw", "lr": 0.00042, "weight_decay": 0.007},
|
||||
)
|
||||
assert "SimCLR 超参" in caplog.text
|
||||
assert "0.00042" in caplog.text
|
||||
|
||||
|
||||
def test_train_only_stops_before_clustering(tiny_image_dir, tmp_path, monkeypatch):
|
||||
"""--train-only 只训练存权重,不抽特征也不聚类。"""
|
||||
sys.path.insert(0, "scripts")
|
||||
|
||||
Reference in New Issue
Block a user