TorchVision RegNet 模型完全指南:网络设计空间与预训练权重实战
2026/9/21 2:41:00 网站建设 项目流程

TorchVision RegNet 模型完全指南:网络设计空间与预训练权重实战

【免费下载链接】visionDatasets, Transforms and Models specific to Computer Vision项目地址: https://gitcode.com/gh_mirrors/vi/vision

本文基于当前仓库(GitHub 加速计划 / vi / vision)中的官方模型文档与源码,系统讲解 TorchVision 中 RegNet 系列图像分类模型。读者将掌握 RegNetX / RegNetY 两种设计空间族共 15 个模型构建器的用法、BlockParams参数化设计原理、多版本预训练权重(含 SWAG 迁移权重)的选取与推理预处理,以及基于references/classification训练配方的复现命令。

RegNet 是什么

RegNet(Regular Networks)源自论文Designing Network Design Spaces(arXiv:2003.13678),其核心思想是用可量化的参数直接定义网络架构,而不是像 ResNet、EfficientNet 那样依靠人工堆叠 stage 与通道数。论文作者通过一个简化的 AnyNet 设计空间逐步约束出 RegNet 设计空间,从而得到一系列在计算量(FLOPs)与精度之间取得良好平衡的网络。

在 TorchVision 中,RegNet 归属于图像分类模型家族,与 ResNet、EfficientNet 等并列于 models.rst 的 Classification 分类下(见 models.rst 中的 toctree 引用models/regnet)。当前仓库提供RegNetX(无 SE 模块)与 RegNetY(含 SE 模块)两个设计空间族,涵盖从 400MF 到 128GF 共 15 个不同计算量的变体。

模型构建器总览

官方文档 regnet.rst 明确说明:以下 15 个模型构建器均可用于实例化 RegNet 模型,支持或不支持预训练权重,且所有构建器内部都依赖torchvision.models.regnet.RegNet基类

设计空间族模型构建器
RegNetY(含 SE)regnet_y_400mfregnet_y_800mfregnet_y_1_6gfregnet_y_3_2gfregnet_y_8gfregnet_y_16gfregnet_y_32gfregnet_y_128gf
RegNetX(无 SE)regnet_x_400mfregnet_x_800mfregnet_x_1_6gfregnet_x_3_2gfregnet_x_8gfregnet_x_16gfregnet_x_32gf

名称中的后缀(如400mf1_6gf32gf)表示该网络的目标计算量:mf为百万 FLOPs(MFLOPs),gf为十亿 FLOPs(GFLOPs)。这些构建器都通过 @register_model() 注册到torchvision.models命名空间,可直接从torchvision.models导入使用。

在 test/test_models.py 中,这些构建器被列入_model_impls之类的模型枚举清单参与测试;其中regnet_y_128gf因为参数量高达约 6.45 亿(见下文权重表),在 Windows CPU/CUDA 环境下被排除在默认测试之外(见 test/test_models.py),同样也被 test/test_extended_models.py 排除在扩展模型测试的批量实例化之外。

架构源码剖析

RegNet 的实现位于 torchvision/models/regnet.py,整体由 stem、trunk(多个 stage)与分类头三部分组成。RegNet类的forward流程为:stem → trunk_output → avgpool → flatten → fc(见 regnet.py)。

Stem:SimpleStemIN

class SimpleStemIN(Conv2dNormActivation): """Simple stem for ImageNet: 3x3, BN, ReLU."""

即一个kernel_size=3, stride=2的卷积 + BatchNorm + ReLU 组合(见 regnet.py),将 3 通道输入下采样到stem_width(默认 32)通道。它复用了 torchvision/ops/misc.py 中的Conv2dNormActivation容器。

BottleneckTransform:核心变换

每个残差块内部的变换为1x1 → 3x3(分组卷积)→ [SE] → 1x1结构(见 regnet.py):

  • 第一个1x1卷积将通道数缩窄到w_b = round(width_out * bottleneck_multiplier)
  • 中间3x3卷积以groups = w_b // group_width分组卷积(这正是 RegNet 区别于普通 ResNet 的关键:通过group_width控制每个分组的宽度);
  • 若设置了se_ratio,则插入SqueezeExcitation通道注意力模块,其压缩通道数为round(se_ratio * width_in)
  • 最后一个1x1卷积恢复/扩展到width_out,且不带激活函数activation_layer=None)。

ResBottleneckBlock:残差连接

should_proj = (width_in != width_out) or (stride != 1) if should_proj: self.proj = Conv2dNormActivation(width_in, width_out, kernel_size=1, stride=stride, ...) self.f = BottleneckTransform(...)

当输入输出通道数不同或 stride 不为 1 时,自动添加 1x1 投影跳跃连接(见 regnet.py),前向计算x = proj(x) + f(x)后再过激活函数。

AnyStage:同宽度的块序列

一个 stage 由多个输出 shape 相同的块组成(见 regnet.py):stage 内第一个块使用 stage 的 stride 并接收上一 stage 的输出宽度,其余块 stride 为 1 且输入输出宽度相同。块命名形如block1-0block1-1

权重初始化

RegNet.__init__末尾执行 ResNet 风格初始化(见 regnet.py):卷积层按std=sqrt(2 / fan_out)的 Kaiming 正态初始化(BN 存在故无 bias),BatchNorm 的 weight 置 1、bias 置 0,全连接层按std=0.01初始化。

BlockParams:从 5 个参数生成整个网络

RegNet 的精髓在于用极少的超参数程序化地推导出每一层的宽度与深度,这一逻辑全部封装在BlockParams.from_init_params类方法中(见 regnet.py),其核心入参:

参数含义约束(源码校验)
depth总块数(所有 stage 块数之和)正整数
w_0起始块宽度w_0 > 0w_0 % 8 == 0
w_a宽度增长斜率w_a >= 0
w_m对数空间中的宽度步进w_m > 1
group_width分组卷积的组宽度正整数
bottleneck_multiplier瓶颈压缩倍数默认1.0
se_ratioSE 压缩比例默认None(RegNetX 不用,RegNetY 用0.25

其计算分两步:

  1. 对数空间宽度量化(见 regnet.py):先按widths_cont = arange(depth) * w_a + w_0得到连续宽度序列,再在 log 空间按block_capacity = round(log(w / w_0) / log(w_m))分桶,最后block_widths = round(w_0 * w_m^capacity / 8) * 8量化为8 的倍数(源码常量QUANT = 8)。w_a是宽度递增斜率,w_0是初始宽度,w_m控制宽度在对数空间的阶梯大小——这正是文档注释中所说的log(block_width) = log(w_0) + w_m * block_capacity
  2. 按宽度突变切分 stage:宽度发生变化的相邻块之间即 stage 分界,随后把每个 stage 的 stride 统一设为 2(源码常量STRIDE = 2),并调用_adjust_widths_groups_compatibilty保证 stage 宽度与分组宽度兼容(见 regnet.py)。

如果w_a < 0 or w_0 <= 0 or w_m <= 1 or w_0 % 8 != 0,会直接抛出ValueError("Invalid RegNet settings")(见 regnet.py)。

各变体的实际参数

每个构建器都通过BlockParams.from_init_params(...)传入论文给出的具体超参数,例如:

构建器depthw_0w_aw_mgroup_widthse_ratio源码位置
regnet_y_400mf164827.892.0980.25regnet.py
regnet_y_800mf145638.842.40160.25regnet.py
regnet_y_1_6gf274820.712.65240.25regnet.py
regnet_y_3_2gf218042.632.66240.25regnet.py
regnet_y_8gf1719276.822.19560.25regnet.py
regnet_y_16gf18200106.232.481120.25regnet.py
regnet_y_32gf20232115.892.532320.25regnet.py
regnet_y_128gf27456160.832.522640.25regnet.py
regnet_x_400mf222424.482.5416regnet.py
regnet_x_800mf165635.732.2816regnet.py
regnet_x_1_6gf188034.012.2524regnet.py
regnet_x_3_2gf258826.312.2548regnet.py
regnet_x_8gf238049.562.88120regnet.py
regnet_x_16gf2221655.592.10128regnet.py
regnet_x_32gf2332069.862.00168regnet.py

可见 RegNetX 全部不设se_ratio(无 SE 模块),而 RegNetY 统一使用se_ratio=0.25——这是两者唯一的本质区别。从bottleneck_multiplier默认 1.0 来看,当前实现采用单倍瓶颈宽度。

预训练权重体系

遵循 TorchVision 自 v0.13 起的 Multi-weight support API,每个 RegNet 构建器都对应一个WeightsEnum权重枚举类(如RegNet_Y_400MF_WeightsRegNet_X_32GF_Weights),可通过weights=关键字显式选取权重版本,默认weights=None表示随机初始化(见 regnet.py 的 docstring 说明)。

权重版本类型

从源码可以归纳出以下权重来源:

  • IMAGENET1K_V1:使用简单的训练配方复现论文结果(recipe指向references/classification的 small / medium / large 模型章节);
  • IMAGENET1K_V2:基于 TorchVision 新版训练配方(含 FixRes 类策略,RegNetX 各版本注明new-recipe-with-fixres)训练,精度全面超越 V1,且DEFAULT均指向 V2;
  • IMAGENET1K_SWAG_E2E_V1:对 SWAG 自监督预训练权重在 ImageNet-1K 上端到端微调得到,仅在regnet_y_16gfregnet_y_32gfregnet_y_128gf三个大模型上提供
  • IMAGENET1K_SWAG_LINEAR_V1:冻结 SWAG trunk + 在 ImageNet-1K 上训练线性分类头,同样只在大模型上提供。

SWAG 系权重的预处理与普通版本不同:E2E 版使用crop_size=384, resize_size=384, interpolation=BICUBIC,LINEAR 版使用crop_size=224, resize_size=224, interpolation=BICUBIC(见 regnet.py)。普通版本 V1 仅用crop_size=224,V2 则增加resize_size=232的 FixRes 式预处理。

ImageNet-1K 精度与算量表

以下数据全部来自 regnet.py 中各Weights_metrics/_ops/num_params元数据(单 crop 评估,单位为 %,GFLOPs):

构建器权重版本Acc@1 / Acc@5GFLOPs参数量文件大小 (MB)
regnet_y_400mfV174.046 / 91.7160.4024,344,14416.806
regnet_y_400mfV275.804 / 92.7420.4024,344,14416.806
regnet_y_800mfV176.420 / 93.1360.8346,432,51224.774
regnet_y_800mfV278.828 / 94.5020.8346,432,51224.774
regnet_y_1_6gfV177.950 / 93.9661.61211,202,43043.152
regnet_y_1_6gfV280.876 / 95.4441.61211,202,43043.152
regnet_y_3_2gfV178.948 / 94.5763.17619,436,33874.567
regnet_y_3_2gfV281.982 / 95.9723.17619,436,33874.567
regnet_y_8gfV180.032 / 95.0488.47339,381,472150.701
regnet_y_8gfV282.828 / 96.3308.47339,381,472150.701
regnet_y_16gfV180.424 / 95.24015.91283,590,140319.49
regnet_y_16gfV282.886 / 96.32815.91283,590,140319.49
regnet_y_16gfSWAG_E2E86.012 / 98.05446.73583,590,140319.49
regnet_y_16gfSWAG_LINEAR83.976 / 97.24415.91283,590,140319.49
regnet_y_32gfV180.878 / 95.34032.28145,046,770554.076
regnet_y_32gfV283.368 / 96.49832.28145,046,770554.076
regnet_y_32gfSWAG_E2E86.838 / 98.36294.826145,046,770554.076
regnet_y_32gfSWAG_LINEAR84.622 / 97.48032.28145,046,770554.076
regnet_y_128gfSWAG_E2E88.228 / 98.682374.57644,812,8942461.564
regnet_y_128gfSWAG_LINEAR86.068 / 97.844127.518644,812,8942461.564
regnet_x_400mfV172.834 / 90.9500.4145,495,97621.258
regnet_x_400mfV274.864 / 92.3220.4145,495,97621.257
regnet_x_800mfV175.212 / 92.3480.87,259,65627.945
regnet_x_800mfV277.522 / 93.8260.87,259,65627.945
regnet_x_1_6gfV177.040 / 93.4401.6039,190,13635.339
regnet_x_1_6gfV279.668 / 94.9221.6039,190,13635.339
regnet_x_3_2gfV178.364 / 93.9923.17715,296,55258.756
regnet_x_3_2gfV281.196 / 95.4303.17715,296,55258.756
regnet_x_8gfV179.344 / 94.6867.99539,572,648151.456
regnet_x_8gfV281.682 / 95.6787.99539,572,648151.456
regnet_x_16gfV180.058 / 94.94415.94154,278,536207.627
regnet_x_16gfV282.716 / 96.19615.94154,278,536207.627
regnet_x_32gfV180.622 / 95.24831.736107,811,560412.039
regnet_x_32gfV283.014 / 96.28831.736107,811,560412.039

值得注意的规律:同等算力下 RegNetY 精度普遍高于 RegNetX(SE 模块带来的增益),而 RegNetY 的参数量也相应更大;regnet_y_128gf是唯一不提供 V1/V2 标准权重、只提供 SWAG 迁移权重的变体,且其DEFAULT指向 SWAG_E2E(见 regnet.py)。

快速上手:加载预训练模型做推理

推荐的做法是使用weights.transforms()自动获取对应权重版本的正确预处理,避免因预处理不匹配导致精度下降。参考 models.rst 中分类模型的通用推理流程,以下给出 RegNet 专属示例:

import torch from torchvision.io import decode_image from torchvision.models import regnet_y_8gf, RegNet_Y_8GF_Weights # Step 1: 用 DEFAULT 权重(即 IMAGENET1K_V2)实例化模型 weights = RegNet_Y_8GF_Weights.DEFAULT model = regnet_y_8gf(weights=weights) model.eval() # 切换 BN 到评估模式 # Step 2: 初始化该权重对应的推理预处理(含 resize 到 232、crop 到 224 等) preprocess = weights.transforms() # Step 3: 读取并预处理图片(以仓库内的测试图片为例) img = decode_image("test/assets/encode_jpeg/grace_hopper_517x606.jpg") batch = preprocess(img).unsqueeze(0) # Step 4: 前向推理并输出类别 prediction = model(batch).squeeze(0).softmax(0) class_id = prediction.argmax().item() score = prediction[class_id].item() category_name = weights.meta["categories"][class_id] print(f"{category_name}: {100 * score:.1f}%")

关键点说明:

  • 类别名列表存放在weights.meta["categories"](即 ImageNet-1K 的 1000 类),由 _meta.py 中的_IMAGENET_CATEGORIES提供(见 regnet.py 的_COMMON_META);
  • 传入预训练权重时,_regnet会自动用len(weights.meta["categories"])覆盖num_classes(见 regnet.py),因此无需手动指定;
  • 若加载权重失败或哈希校验不通过,会抛出错误,因为_regnet使用weights.get_state_dict(progress=progress, check_hash=True)校验下载文件完整性(见 regnet.py);
  • 权重默认下载到TORCH_HOME指定的缓存目录,可参考 models.rst 的说明;
  • 显式传入weights=None或不传weights时,得到随机初始化模型;旧版pretrained=True写法已被弃用(见 models.rst)。

指定不同权重版本

from torchvision.models import regnet_y_16gf, RegNet_Y_16GF_Weights # 显式指定版本(枚举或字符串均可) model_v2 = regnet_y_16gf(weights=RegNet_Y_16GF_Weights.IMAGENET1K_V2) model_swag = regnet_y_16gf(weights="IMAGENET1K_SWAG_E2E_V1") # 字符串形式等价 assert regnet_y_16gf(weights="IMAGENET1K_V1") is not None

选型建议:追求最高精度且算力充足时优先IMAGENET1K_SWAG_E2E_V1;在 224 输入尺寸下获得高精度则用IMAGENET1K_SWAG_LINEAR_V1;常规场景直接用DEFAULT即可。

加载不带预训练权重的模型

import torch from torchvision.models import regnet_x_400mf model = regnet_x_400mf(weights=None) # 随机初始化,1000 类 model_finetune = regnet_x_400mf(num_classes=10) # 自定义类别数 x = torch.rand(1, 3, 224, 224) print(model(x).shape) # torch.Size([1, 1000])

从零训练:官方训练配方

仓库在 references/classification 提供了可复现 ImageNet-1K 精度的训练脚本(入口为train.py),README.md 中按模型规模给出三组 RegNet 专用命令:

Small 模型regnet_x_400mfregnet_x_800mfregnet_x_1_6gfregnet_y_400mfregnet_y_800mfregnet_y_1_6gf):

torchrun --nproc_per_node=8 train.py\ --model $MODEL --epochs 100 --batch-size 128 --wd 0.00005 --lr=0.8\ --lr-scheduler=cosineannealinglr --lr-warmup-method=linear\ --lr-warmup-epochs=5 --lr-warmup-decay=0.1

注意:regnet_y_400mf需要把学习率改为 0.4 才能复现论文的 Acc@1。

Medium 模型regnet_x_3_2gfregnet_x_8gfregnet_x_16gfregnet_y_3_2gfregnet_y_8gf):

torchrun --nproc_per_node=8 train.py\ --model $MODEL --epochs 100 --batch-size 64 --wd 0.00005 --lr=0.4\ --lr-scheduler=cosineannealinglr --lr-warmup-method=linear\ --lr-warmup-epochs=5 --lr-warmup-decay=0.1

Large 模型regnet_x_32gfregnet_y_16gfregnet_y_32gf):

torchrun --nproc_per_node=8 train.py\ --model $MODEL --epochs 100 --batch-size 32 --wd 0.00005 --lr=0.2\ --lr-scheduler=cosineannealinglr --lr-warmup-method=linear\ --lr-warmup-epochs=5 --lr-warmup-decay=0.1

三组配方遵循同一规律:模型越大,batch-size 与学习率越小(128/0.8 → 64/0.4 → 32/0.2),权重衰减统一为0.00005,均使用 100 epochs、余弦退火调度与 5 epochs 线性 warmup。V2 权重之所以精度显著高于 V1,正是因为后者使用了改进的新版训练配方(含 FixRes 等策略)。SWAG 系权重的复现方式见_COMMON_SWAG_META中记录的迁移学习方案(见 regnet.py)。

测试验证

当前仓库通过以下方式保证 RegNet 实现的正确性:

  • test/test_models.py 将 15 个 RegNet 构建器纳入模型清单,配合test/expect/目录下的ModelTester.test_regnet_*_expect.pkl期望文件做前向输出对比验证;
  • test/test_extended_models.py 在扩展模型批量测试中显式排除regnet_y_128gf(因其规模过大),其余变体均参与实例化与推理验证;
  • BlockParams.from_init_params内置参数合法性校验,非法组合直接抛ValueError,从源头杜绝了无法整除/宽度失配的配置。

小结

RegNet 是"参数即架构"设计哲学在 TorchVision 中的完整落地:开发者只需给出depth / w_0 / w_a / w_m / group_width / se_ratio六个超参数,即可由 BlockParams 程序化推导出整个网络。配合多版本预训练权重(V1 / V2 / SWAG)、自动化的weights.transforms()预处理与 references/classification 的复现配方,RegNetX / RegNetY 既是精度导向任务(SWAG_E2E 可达 88.2% Top-1)的有力候选,也是算力受限场景(400MF 级约 0.4 GFLOPs)下高效基线模型的优选。

更深入的实现细节可继续阅读:

  • 模型源码:torchvision/models/regnet.py
  • 官方文档:docs/source/models/regnet.rst
  • 模型总览:docs/source/models.rst
  • 训练配方:references/classification/README.md
  • 权重期望值:test/expect

【免费下载链接】visionDatasets, Transforms and Models specific to Computer Vision项目地址: https://gitcode.com/gh_mirrors/vi/vision

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询