首页
/ Transformers 中的 ConvNeXt V2:从 FCMAE 自监督预训练到 GRN 架构的纯卷积模型详解

Transformers 中的 ConvNeXt V2:从 FCMAE 自监督预训练到 GRN 架构的纯卷积模型详解

2026-09-06 19:20:51作者:温玫谨Lighthearted

ConvNeXt V2 是 Facebook AI(Meta)在 2023 年提出的纯卷积视觉模型,它把卷积网络的强表达力与掩码自编码器(Masked Autoencoder)式自监督表征学习做了协同设计。本文以 docs/source/en/model_doc/convnextv2.md 为主线,结合当前仓库中 configuration_convnextv2.pymodeling_convnextv2.py 及对应测试与转换脚本,系统讲解其模型族背景、架构组件(GRN、FCMAE)、配置参数含义,以及基于 AutoModel 系列进行推理、图像分类、Backbone 抽取和微调的完整实操方案。

ConvNeXt V2 是什么:纯卷积模型与自监督学习的协同设计

ConvNeXt V2 由 Sanghyun Woo、Shoubhik Debnath、Ronghang Hu、Xinlei Chen、Zhuang Liu、In So Kweon、Saining Xie 在论文 ConvNeXt V2: Co-designing and Scaling ConvNets with Masked Autoencoders 中提出(HF Papers 收录于 2023-01-02,在 Transformers 中由贡献者 adirik 于 2023-03-14 合入)。它是一个纯卷积模型(ConvNet),设计上受 Vision Transformer 启发,是仓库中另一模型 ConvNeXt 的直接后继者。

论文摘要的核心观点是:

尽管以 ConvNeXt 为代表的现代卷积网络已在多种视觉场景中表现出色,但它们最初是为 ImageNet 有监督学习设计的,理论上也能从掩码自编码器(MAE)这类自监督技术中获益。然而作者发现,简单地把两者组合效果并不理想。为此论文提出了一个全卷积掩码自编码器框架(fully convolutional masked autoencoder, FCMAE),以及一个可插入 ConvNeXt 主干的新模块 GRN(Global Response Normalization,全局响应归一化)层,用来增强通道间的特征竞争。这种"自监督训练方法 + 架构改进"的协同设计形成了新的模型族 ConvNeXt V2,在 ImageNet 图像分类、COCO 检测、ADE20K 分割等多项识别基准上显著提升了纯卷积网络的表现。

从论文摘要还可以看到该模型族覆盖的规模区间(注意:以下数字为论文中的报告数据,引用自关联文档,非本仓库实测):小到参数量约 3.7M 的 Atto(ImageNet top-1 约 76.7%),大到 650M 的 Huge(仅用公开训练数据即可达到约 88.9% 的 top-1 精度)。官方预训练权重与原始代码来自 facebookresearch/ConvNeXt-V2,仓库中保留了对应的权重转换脚本 convert_convnextv2_to_pytorch.py,用于把官方 checkpoint 转换为可在 Transformers 中直接加载的格式。

仓库中的代码结构:从配置到四类可加载组件

ConvNeXt V2 的实现集中在 src/transformers/models/convnextv2/ 目录,由 4 个文件组成:

文件 职责
configuration_convnextv2.py 定义 ConvNextV2Config,声明模型超参与输出特征(out_features/out_indices)
modeling_convnextv2.py PyTorch 实现全部网络模块与三类对外模型
convert_convnextv2_to_pytorch.py 将官方 ConvNeXt V2 权重重命名为 HF 命名并转存
__init__.py 基于 _LazyModule 的惰性导入入口

其中 modeling_convnextv2.py__all__ 导出了四个类(建模文件末尾):

  • ConvNextV2PreTrainedModel:权重初始化、保存加载的公共基类;
  • ConvNextV2Model:纯主干,输出特征图与池化向量;
  • ConvNextV2ForImageClassification:主干 + 分类头(用于 ImageNet 等任务);
  • ConvNextV2Backbone:面向 DETR、MaskFormer 等下游框架的多尺度 Backbone 封装。

src/transformers/models/auto/modeling_auto.py 中,convnextv2 这一 model_type 被同时注册到通用模型映射、图像分类映射与 Backbone 映射,因此可以用 AutoModelAutoModelForImageClassificationAutoBackbone 直接按名称加载。模型内部按 ConvNextV2Embeddings → ConvNextV2Encoder(N 个 ConvNextV2Stage)→ 可选分类头/池化 组织,基础结构代码大量复用自 ConvNeXt(源码注释中多处标注 # Copied from transformers.models.convnext.modeling_convnext.ConvNext...),保证两代模型行为一致、便于维护。

ConvNextV2Config:核心配置参数一览

ConvNextV2Config配置文件)继承自 PreTrainedConfig 并混入 BackboneConfigMixin,声明了 model_type = "convnextv2"。其类属性的默认值即对应 facebook/convnextv2-tiny-1k-224 这一骨干结构的配置风格(@auto_docstring(checkpoint="facebook/convnextv2-tiny-1k-224") 装饰器会把该 checkpoint 的真实字段注入文档字符串)。

关键参数及其默认值如下:

参数 默认值 说明
num_channels 3 输入图像的通道数,默认 RGB 三通道
patch_size 4 Patch Embedding 卷积的 kernel_size/stride,把图像切成 4×4 patch
num_stages 4 主干中的 stage 数量
hidden_sizes (96, 192, 384, 768) 各 stage 的输出通道数,第 0 项也是 stem 卷积后的宽度
depths (3, 3, 9, 3) 各 stage 内残差 Block 的数量
hidden_act "gelu" Block 中激活函数,经 ACT2FN[config.hidden_act] 解析
initializer_range 0.02 参数初始化范围
layer_norm_eps 1e-12 顶部 nn.LayerNorm 的 epsilon
drop_path_rate 0.0 随机深度(Stochastic Depth)总衰减率,按层数线性插值分配
image_size 224 模型设计输入尺寸
out_features / out_indices None Backbone 需要输出的 stage 名称/索引(可选)

__post_init__ 中,配置会自动生成 stage_names = ["stem"] + [f"stage{idx}" ...],并调用 set_output_features_output_indices 同步 out_featuresout_indices,因此同一份配置既能驱动分类模型,也能直接驱动多尺度 Backbone。

从随机权重初始化一个模型的最简代码如下(取自配置文件中的官方示例):

>>> from transformers import ConvNextV2Config, ConvNextV2Model

>>> # 以 convnextv2-tiny-1k-224 风格配置初始化
>>> configuration = ConvNextV2Config()

>>> # 用随机权重构建模型
>>> model = ConvNextV2Model(configuration)

>>> # 访问模型配置
>>> configuration = model.config

需要说明的是:示例中的默认配置(depths 为 (3, 3, 9, 3)、hidden_sizes 为 (96, 192, 384, 768))与 tiny 架构的结构一致,但训练好的权重仍应从官方 checkpoint 加载,而不是直接用随机权重做推理。

模型前向接口与返回结构

与多数视觉模型不同,ConvNeXt V2 不使用 input_ids/attention_mask,主输入名为 pixel_values。它的特征提取与分类任务的输出类型都能从返回对象名字里看出"无注意力"的特征。

ConvNextV2Model(特征提取)

前向返回 BaseModelOutputWithPoolingAndNoAttention实现位置),包含两个核心字段:

  • last_hidden_state:最后一个 stage 输出的特征图;
  • pooler_output:先对特征图做全局平均池化(hidden_states.mean([-2, -1])),再经 nn.LayerNorm(hidden_sizes[-1]) 得到的 (N, C) 向量。
>>> from transformers import AutoImageProcessor, AutoModel
>>> from PIL import Image
>>> import httpx
>>> from io import BytesIO

>>> url = "http://images.cocodataset.org/val2017/000000039769.jpg"
>>> image = Image.open(BytesIO(httpx.get(url).content))

>>> processor = AutoImageProcessor.from_pretrained("facebook/convnextv2-tiny-1k-224")
>>> model = AutoModel.from_pretrained("facebook/convnextv2-tiny-1k-224")

>>> inputs = processor(image, return_tensors="pt")
>>> outputs = model(**inputs)
>>> outputs.last_hidden_state.shape, outputs.pooler_output.shape

空间分辨率变化规律可以从结构和测试共同确认:stem 以 stride 4 降采样一次,后续第 2~4 个 stage 各以 stride 2 降采样一次,共缩小 2⁵=32 倍。因此 224×224 输入对应输出约 7×7,测试文件 test_modeling_convnextv2.py 中对 create_and_check_model 的断言即为 (batch_size, hidden_sizes[-1], image_size // 32, image_size // 32)

ConvNextV2ForImageClassification(图像分类)

在池化特征之上接一个 nn.Linear(config.hidden_sizes[-1], config.num_labels) 分类头;num_labels 为 0 时用 nn.Identity() 占位。前向返回 ImageClassifierOutputWithNoAttention,其中:

  • logits:形状 (batch_size, num_labels)
  • labels:可选。当 config.num_labels == 1 时计算 MSE 回归损失,num_labels > 1 时计算交叉熵分类损失(见 建模文件前向文档)。
>>> from transformers import AutoImageProcessor, AutoModelForImageClassification
>>> import torch

>>> processor = AutoImageProcessor.from_pretrained("facebook/convnextv2-tiny-1k-224")
>>> model = AutoModelForImageClassification.from_pretrained("facebook/convnextv2-tiny-1k-224")

>>> inputs = processor(image, return_tensors="pt")
>>> with torch.no_grad():
...     logits = model(**inputs).logits
>>> predicted_label = logits.argmax(-1).item()

在 Pipeline 层面,测试中注册了 image-classification(对应 ConvNextV2ForImageClassification)与 image-feature-extraction(对应 ConvNextV2Model)两个任务管线(见 测试文件 pipeline_model_mapping),所以也可以直接使用:

>>> from transformers import pipeline
>>> classifier = pipeline("image-classification", model="facebook/convnextv2-tiny-1k-224")
>>> classifier(image)

图像预处理不需要单独实现:convnextv2image_processing_auto.py 中注册为复用 ConvNeXt 系列的 ConvNextImageProcessor,因此 AutoImageProcessor.from_pretrained("facebook/convnextv2-tiny-1k-224") 即可获得正确的 resize、归一化与通道处理流程。

ConvNextV2Backbone(多尺度特征抽取)

官方文档将 Backbone 定位为"供 DETR、MaskFormer 这类框架使用"的组件。其构造逻辑(实现位置)为:

  • num_features = [hidden_sizes[0]] + hidden_sizes,与 stem 及各 stage 一一对应;
  • 为每个输出 stage 额外挂一个 ConvNextV2LayerNormchannels_first 格式);
  • 前向按配置的 out_features/out_indices 过滤并归一化各层特征图,返回 BackboneOutput(feature_maps=..., hidden_states=...)

官方 docstring 示例展示了它与 AutoBackbone 的组合用法(建模文件 Backbone 示例):

>>> from transformers import AutoImageProcessor, AutoBackbone
>>> import torch
>>> from PIL import Image
>>> import httpx
>>> from io import BytesIO

>>> url = "http://images.cocodataset.org/val2017/000000039769.jpg"
>>> with httpx.stream("GET", url) as response:
...     image = Image.open(BytesIO(response.read()))

>>> processor = AutoImageProcessor.from_pretrained("facebook/convnextv2-tiny-1k-224")
>>> model = AutoBackbone.from_pretrained("facebook/convnextv2-tiny-1k-224")

>>> inputs = processor(image, return_tensors="pt")
>>> outputs = model(**inputs)
>>> outputs.feature_maps  # 多尺度特征元组

从源码理解 ConvNeXt V2 的关键设计

GRN:通道间特征竞争的增强层

GRN 是相对 ConvNeXt V1 最核心的新增模块,实现在 modeling_convnextv2.py。源码表明其计算过程分三步:

  1. 聚合空间信息:对每个通道计算特征图在空间维 (H, W) 上的 L2 范数 torch.linalg.vector_norm(..., ord=2, dim=(1, 2)),得到全局响应向量;
  2. 归一化:每个通道的范数除以所有通道范数的均值(+1e-6 防止除零),使通道间的响应可比较;
  3. 门控与残差:用可学习的 weight(形状 (1, 1, 1, dim))对归一化后的特征做缩放,叠加 bias,再与原输入做残差相加。

GRN 由此突出"响应强的通道、抑制响应弱的通道",即论文所称的增强通道间特征竞争。值得一提的实现细节是:它的 weightbias 初始化为全零(见 _init_weights 中对 ConvNextV2GRN 特判的 初始化逻辑),从而在训练初期保证残差路径不改变主分支信号,这与论文"新增结构应从恒等变换起步"的思路一致。

Block 与 Stage:7×7 深度卷积 + 倒瓶颈 + DropPath

ConvNextV2Layer(源码中对应原始实现的 Block)的结构为(实现位置):

  • DwConv:7×7、padding=3、groups=dim 的深度卷积(逐通道卷积),负责空间混合;
  • LayerNorm(channels_last):在 (N, H, W, C) 布局上做归一化(注释说明作者实测这种排列在 PyTorch 中更快);
  • pwconv1Linear(dim, 4*dim) 放大通道(倒瓶颈,expansion=4);
  • 激活函数 GELU
  • GRN:作用于放大后的 4×dim 特征,抑制无用通道;
  • pwconv2Linear(4*dim, dim) 投影回原宽度;
  • DropPath 残差:随机深度(每个样本以 drop_prob 丢弃整条残差分支),训练时除以 keep_prob 保持期望值不变。

ConvNextV2Stage 在通道数变化或需要降采样时(in_channels != out_channels or stride > 1)先执行一个 LayerNorm(channels_first) + Conv2d(kernel=2, stride=2) 的下采样块,再堆叠 depth 个 Block。各 Block 的 DropPath 概率由 ConvNextV2Encodertorch.linspace(0, config.drop_path_rate, sum(depths)) 在全部层上线性插值后按各 stage 切分,保证深层的正则化更强。

Patch Embedding 与通道数校验

ConvNextV2Embeddingsnn.Conv2d(num_channels, hidden_sizes[0], kernel_size=patch_size, stride=patch_size) 完成 patch 化,再接 channels_first 的 LayerNorm;前向时会校验输入通道数与 num_channels 配置是否一致,否则抛出提示 ValueError(实现位置)。这也意味着加载模型时配置中的 num_channels 必须与实际图像匹配。

微调与上手资源

ConvNeXt V2 属于图像分类任务管线,仓库文档给出如下资源:ConvNextV2ForImageClassificationexamples/pytorch/image-classification/ 下的官方示例脚本支持(包含训练与评估入口)。具体运行方式(数据集路径、--model_name_or_path facebook/convnextv2-tiny-1k-224、学习率等超参)可参考该目录下的 README.md,脚本内部使用 AutoImageProcessor + AutoModelForImageClassification,因此直接把 model name 换成任意 facebook/convnextv2-* checkpoint 即可开始微调。

如果你拿到的是官方(非 HF)格式的 ConvNeXt V2 权重,仓库提供了转换脚本 convert_convnextv2_to_pytorch.py,它会读取 checkpoint URL 构造 ConvNextV2Config、执行 key 重命名并保存为 Transformers 格式,还附带图像预处理转换逻辑。这保证了"官方预训练 → HF 加载"路径的完整性。

测试与可复现验证

ConvNeXt V2 的测试集中在 tests/models/convnextv2/test_modeling_convnextv2.py,覆盖三个层面:

  • 模型行为测试ConvNextV2ModelTest 同时验证 ConvNextV2ModelConvNextV2ForImageClassificationConvNextV2Backbone,包括前向形状、梯度 checkpoint、hidden_states 输出、标签损失等;
  • 快速推理测试@slow):加载 facebook/convnextv2-tiny-1k-224 并对 tests/fixtures/tests_samples/COCO/000000039769.png(两只猫的经典 COCO 样例图)推理,断言 logits 形状为 (1, 1000),且前三个 logits 的期望切片约为 [0.9989, 0.1953, -0.4382](见 测试文件 L292)。这份期望值可以直接用来验证你本地环境加载权重与预处理是否一致;
  • Backbone 专项测试ConvNextV2BackboneTest 通过 BackboneTesterMixin 覆盖多尺度输出的配置组合。

此外,测试还显式声明了 has_attentions = Falsetest_resize_embeddings = False,反映纯卷积模型"无注意力、无 token embedding"的本质属性。

小结:与 ConvNeXt V1 的关系与选用建议

从仓库实现看,ConvNeXt V2 的工程骨架大量复用了 ConvNeXt V1(Patch Embedding、DropPath、Stage 结构均以 # Copied from 方式同步),真正的架构增量集中在每个 Block 中嵌入 GRN 层以及配套的 FCMAE 自监督预训练。如果你正在对比两代模型,可以同时查阅 ConvNeXt 官方文档,两者在配置字段、加载方式与图像处理器上高度一致,便于做公平的消融或性能对比实验。

选用建议(基于仓库可确认的事实归纳,而非外部评测):需要多尺度特征图给检测/分割模型做 Backbone 时,使用 ConvNextV2Backbone 配合 out_features/out_indices;只做图像分类或微调时,直接使用 ConvNextV2ForImageClassification 与官方预训练 checkpoint 即可;而 GRN 的源码实现(L2 范数聚合 + 均值归一化门控 + 全零初始化残差)是理解该模型为何能在纯卷积范式下追平 Transformer 式自监督表征学习的核心阅读材料。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.8 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
594
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
916
1.83 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.58 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.01 K
516
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
388