# 用 resnet50 做域内自监督(SimCLR)再聚类。 # # 与 film_simclr_resnet18.yaml 的区别只有骨架和 batch_size,其余超参保持一致, # 方便直接对比两个骨架的效果。 # # 用法: # uv run python scripts/cluster_unlabeled.py --config configs/cluster/film_simclr_resnet50.yaml \ # --work-dir runs/simclr_r50 --set simclr.epochs=40 _base_: - ./film.yaml method: simclr num_clusters: 5 simclr: backbone: # _replace_ 必须保留:不加的话 base 里 tiny_conv 的 widths/depths/block 会残留, # 传给 TorchvisionBackbone 直接报错。见 utils/config.py::deep_merge _replace_: true name: torchvision arch: resnet50 pretrained: true # 从 ImageNet 权重起步再自监督微调;改 false 则从随机初始化开始 in_channels: 3 # torchvision 的 features 是 nn.Sequential,可以取中间层(4~7 = layer1~4)。 # 沿用 resnet18 上的实测结论:layer2+3 明显优于 layer4,缺陷差异主要在纹理层面。 # 注意 resnet50 的 layer2+3 是 512+1024=1536 维(resnet18 只有 128+256=384 维), # 后续 PCA 仍降到 pca_dim=32,所以下游开销不变。 feature_stages: [5, 6] # resnet50 比 resnet18 重一倍(23.5M vs 11.2M),显存吃得多得多。 # 实测(Apple MPS,128x128 双视图): # batch 1024 -> ❌ OOM,需要 18.7 GiB # batch 128 -> ✅ 604 MB,每 epoch 约 155 秒 # batch 64 -> ✅ 483 MB,每 epoch 约 155 秒 # 每 epoch 耗时与 batch 基本无关(算力受限而非带宽受限),所以调小 batch 不花额外时间, # 只是 NT-Xent 的负样本变少、InfoNCE 下界略松。显存不够就继续往下调到 128 / 64。 batch_size: 256 epochs: 2500 projection: {hidden_channels: 2048, out_channels: 128} optimizer: {name: adamw, lr: 0.001, weight_decay: 0.0001} # 投影头沿用 base 的 256 隐藏维。SimCLR 原文给 resnet50 用的是 2048->2048->128, # 想更贴近原设置可以改成 {hidden_channels: 2048, out_channels: 128}—— # 实测这一项不是显存瓶颈,但对聚类质量的影响本仓库尚未测过。