From 5f31ed0a92e3a6cb224222ae617d65b5b04c55b2 Mon Sep 17 00:00:00 2001 From: Shaun Zhou Date: Mon, 7 Sep 2026 11:07:55 +0800 Subject: [PATCH] =?UTF-8?q?feat(configs):=20=E6=96=B0=E5=A2=9E=20resnet50?= =?UTF-8?q?=20=E7=9A=84=E8=87=AA=E7=9B=91=E7=9D=A3=E8=81=9A=E7=B1=BB?= =?UTF-8?q?=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 仿照 film_simclr_resnet18.yaml,只改骨架与 batch_size,其余超参保持一致以便对比。 batch_size 取 256 而非照抄 resnet18 的 1024:实测 resnet50 在 Apple MPS 上 batch 1024 直接 OOM(需 18.7 GiB),batch 128 时 604 MB。每 epoch 耗时与 batch 基本无关(约 155 秒,算力受限),所以调小 batch 不花额外时间,只是负样本变少。 配置注释里记下了实测数据与降级路径(显存不够继续调到 128 / 64), 并说明 resnet50 的 layer2+3 是 1536 维(resnet18 为 384 维)。 Co-Authored-By: Claude Opus 5 --- README.md | 15 +++++++- configs/cluster/film_simclr_resnet50.yaml | 46 +++++++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 configs/cluster/film_simclr_resnet50.yaml diff --git a/README.md b/README.md index a00aafa..de5e1e0 100644 --- a/README.md +++ b/README.md @@ -422,13 +422,26 @@ view_transforms: # 生成两个视图的随机增强 #### 换一个骨架 -**仓库自带 resnet18 的现成配置**,直接用: +**仓库自带 resnet18 / resnet50 的现成配置**,直接用: ```bash uv run python scripts/cluster_unlabeled.py --config configs/cluster/film_simclr_resnet18.yaml \ --work-dir runs/simclr_r18 --set simclr.epochs=40 + +uv run python scripts/cluster_unlabeled.py --config configs/cluster/film_simclr_resnet50.yaml \ + --work-dir runs/simclr_r50 --set simclr.epochs=40 ``` +两者在 Apple MPS 上的实测开销(14,579 张,128×128 双视图): + +| 骨架 | 参数量 | layer2+3 维度 | 每 epoch | batch 上限 | +| --- | --- | --- | --- | --- | +| resnet18 | 11.2M | 384 | 约 93 秒 | 1024 可用 | +| resnet50 | 23.5M | 1536 | 约 155 秒 | **1024 会 OOM**(需 18.7 GiB),配置里用 256 | + +resnet50 每 epoch 的耗时与 batch 基本无关(算力受限),所以显存不够时往下调 batch 不花额外时间, +只是 NT-Xent 的负样本变少。 + 注意默认的 `method: pretrained` 用的**也是 resnet18**(ImageNet 权重,不训练,约 51 秒出结果); 上面这个配置是在 `data/film` 上自监督训练它。两者实测对比(14,579 张,k=4): diff --git a/configs/cluster/film_simclr_resnet50.yaml b/configs/cluster/film_simclr_resnet50.yaml new file mode 100644 index 0000000..2c274c3 --- /dev/null +++ b/configs/cluster/film_simclr_resnet50.yaml @@ -0,0 +1,46 @@ +# 用 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 + optimizer: {name: adamw, lr: 0.0001, weight_decay: 0.00001} + + # 投影头沿用 base 的 256 隐藏维。SimCLR 原文给 resnet50 用的是 2048->2048->128, + # 想更贴近原设置可以改成 {hidden_channels: 2048, out_channels: 128}—— + # 实测这一项不是显存瓶颈,但对聚类质量的影响本仓库尚未测过。