diff --git a/README.md b/README.md index 59be879..0629073 100644 --- a/README.md +++ b/README.md @@ -470,7 +470,7 @@ view_transforms: # 生成两个视图的随机增强 #### 换一个骨架 -**仓库自带 resnet18 / resnet50 的现成配置**,直接用: +**仓库自带 resnet18 / resnet50 / resnet101 的现成配置**,直接用: ```bash uv run python scripts/cluster_unlabeled.py --config configs/cluster/film_simclr_resnet18.yaml \ @@ -478,6 +478,9 @@ uv run python scripts/cluster_unlabeled.py --config configs/cluster/film_simclr_ uv run python scripts/cluster_unlabeled.py --config configs/cluster/film_simclr_resnet50.yaml \ --work-dir runs/simclr_r50 --set simclr.epochs=40 + +uv run python scripts/cluster_unlabeled.py --config configs/cluster/film_simclr_resnet101.yaml \ + --work-dir runs/simclr_r101 --set simclr.epochs=40 ``` 两者在 Apple MPS 上的实测开销(14,579 张,128×128 双视图): @@ -486,6 +489,7 @@ uv run python scripts/cluster_unlabeled.py --config configs/cluster/film_simclr_ | --- | --- | --- | --- | --- | | resnet18 | 11.2M | 384 | 约 93 秒 | 1024 可用 | | resnet50 | 23.5M | 1536 | 约 155 秒 | **1024 会 OOM**(需 18.7 GiB),配置里用 256 | +| resnet101 | 42.5M | 1536 | 未实测 | 配置里用 128(按规模比例保守取值) | resnet50 每 epoch 的耗时与 batch 基本无关(算力受限),所以显存不够时往下调 batch 不花额外时间, 只是 NT-Xent 的负样本变少。 @@ -508,7 +512,8 @@ resnet18 参数量是 tiny_conv 的 37 倍(11.2M vs 0.3M),1 个 epoch 远 | --- | --- | --- | --- | | `tiny_conv` | — | 256(可调) | 自研深度可分离卷积,默认,最轻 | | `torchvision` | `resnet18` / `resnet34` | 512 | 通用基线 | -| `torchvision` | `resnet50` | 2048 | 最强也最重,MPS 上注意 batch | +| `torchvision` | `resnet50` | 2048 | 更强也更重,MPS 上注意 batch | +| `torchvision` | `resnet101` | 2048 | 最深,首次使用会下载约 171 MB 权重 | | `torchvision` | `mobilenet_v3_small` / `_large` | 576 / 960 | 面向实时部署 | | `torchvision` | `shufflenet_v2_x1_0` | 1024 | 同上 | diff --git a/configs/cluster/film_simclr_resnet101.yaml b/configs/cluster/film_simclr_resnet101.yaml new file mode 100644 index 0000000..fd8ea0e --- /dev/null +++ b/configs/cluster/film_simclr_resnet101.yaml @@ -0,0 +1,40 @@ +# 用 resnet101 做域内自监督(SimCLR)再聚类。 +# +# 与 film_simclr_resnet18/50 的区别只有骨架和 batch_size,其余超参保持一致, +# 方便横向对比三个骨架。 +# +# 用法: +# uv run python scripts/cluster_unlabeled.py --config configs/cluster/film_simclr_resnet101.yaml \ +# --work-dir runs/simclr_r101 --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: resnet101 + pretrained: true # 首次使用会下载 ImageNet 权重(约 171 MB);改 false 则随机初始化 + in_channels: 3 + + # torchvision 的 features 是 nn.Sequential,可以取中间层(4~7 = layer1~4)。 + # 沿用 resnet18 上的实测结论:layer2+3 明显优于 layer4,缺陷差异主要在纹理层面。 + # resnet101 的 layer2+3 是 512+1024=1536 维,与 resnet50 相同(都是 Bottleneck 结构), + # 差别在深度:resnet101 的 layer3 有 23 个 block,resnet50 只有 6 个。 + feature_stages: [5, 6] + + # 三个骨架的规模对比:resnet18 11.2M / resnet50 23.5M / resnet101 42.5M。 + # batch_size 取 128 是保守值——Apple MPS 上实测 resnet50 在 batch 1024 就 OOM(要 18.7 GiB), + # resnet101 约重 1.8 倍,故再降一档。 + # 注意上面的数字来自 MPS;在 16 GB 独显(如 RTX 4080 SUPER)上可以往上调, + # NT-Xent 的负样本越多下界越紧,显存够就尽量开大。 + batch_size: 128 + + epochs: 2500 + optimizer: {name: adamw, lr: 0.0001, weight_decay: 0.00001} diff --git a/models/backbones/resnet.py b/models/backbones/resnet.py index 105371f..119067b 100644 --- a/models/backbones/resnet.py +++ b/models/backbones/resnet.py @@ -12,6 +12,7 @@ _SUPPORTED = { "resnet18": 512, "resnet34": 512, "resnet50": 2048, + "resnet101": 2048, "mobilenet_v3_small": 576, "mobilenet_v3_large": 960, "shufflenet_v2_x1_0": 1024,