[特殊字符] Transformers 中的 Dilated Neighborhood Attention Transformer(DiNAT):架构原理、配置详解与实战使用指南

发布时间:2026/9/11 7:24:58
[特殊字符] Transformers 中的 Dilated Neighborhood Attention Transformer(DiNAT):架构原理、配置详解与实战使用指南 Transformers 中的 Dilated Neighborhood Attention TransformerDiNAT架构原理、配置详解与实战使用指南【免费下载链接】transformers Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and multimodal models, for both inference and training.项目地址: https://gitcode.com/GitHub_Trending/tra/transformers导读DiNATDilated Neighborhood Attention Transformer扩张近邻注意力 Transformer是 Transformers 中收录的一种分层视觉 Transformer它通过引入扩张近邻注意力DiNA模式在保持局部注意力低计算成本的同时捕获全局上下文、指数级扩展感受野。本文以仓库内 DiNAT 文档及对应的 英文文档为核心结合 configuration_dinat.py 与 modeling_dinat.py 的源码实现系统讲解 DiNAT 的模型原理、NATTEN 依赖环境、DinatConfig全部配置参数、DinatModel/DinatForImageClassification/DinatBackbone三类模型的用法以及将其作为图像分类与下游视觉任务骨干网络backbone的完整实战方案。读完本文你将能够独立安装依赖、加载与微调 DiNAT 模型并理解其局部 稀疏全局混合注意力的设计逻辑。一、模型概述从 NAT 到 DiNATDiNAT 由 Ali Hassani 与 Humphrey Shi 在论文《Dilated Neighborhood Attention Transformer》中提出论文于 2022-09-29 发布模型于 2022-11-18 贡献进本仓库见 英文文档 开头说明。它是 NATNeighborhood Attention Transformer 的直接扩展在 NAT 的基础上加入扩张近邻注意力Dilated Neighborhood Attention, DiNA模式用于捕获全局上下文并在 NAT 基础上取得了显著的性能提升。论文摘要中阐述了这一设计动机视觉领域的 Transformer 通常采用局部注意力机制如滑窗近邻注意力 NA、Swin Transformer 的移位窗口自注意力来削减自注意力的二次复杂度但局部注意力同时弱化了自注意力最可贵的两个特性——长距离相互依赖建模与全局感受野。DiNA 作为 NA 的一种自然、灵活且高效的扩展可以捕获更多全局上下文并在零额外成本的前提下从零开始指数级扩展感受野NA 的局部注意力与 DiNA 的稀疏全局注意力相互补充二者共同构成 DiNAT 这一新型分层视觉 Transformer。论文中报告DiNAT 各变体相比 NAT、Swin、ConvNeXt 等强基线有显著改进。其大模型在 COCO 目标检测上比对应的 Swin 模型更快且 box AP 领先 1.5%COCO 实例分割 mask AP 领先 1.3%ADE20K 语义分割 mIoU 领先 1.1%。配合新框架后其大模型在 COCO58.2 PQ与 ADE20K48.5 PQ上成为全景分割新 SOTA在 Cityscapes44.5 AP与 ADE20K35.4 AP上无额外数据刷新实例分割记录并追平 ADE20K 上专用语义分割模型的 SOTA58.2 mIoU。以上均为论文报告的实验结果。文档中展示的不同扩张值下的近邻注意力示意图不同扩张值对应的注意力采样区域直观说明了这一思想当 dilation 为 1 时注意力覆盖紧邻的kernel_size × kernel_size窗口随着 dilation 增大参与计算的 token 彼此间距拉大形成稀疏但覆盖范围更广的全局采样模式。二、架构原理源码级拆解 DiNAT 的分层结构从 modeling_dinat.py 的实现看DiNAT 是典型的分层hierarchical视觉 Transformer整体由DinatEmbeddingsPatch 嵌入、DinatEncoder四阶段编码器与可选的下游头组成。下面按数据流向逐层拆解。2.1 Patch Embedding仅支持 patch size 4 的卷积下采样DinatPatchEmbeddingsmodeling_dinat.py L144-L177负责把形状为(batch_size, num_channels, height, width)的pixel_values转成(batch_size, height, width, hidden_size)的 patch 嵌入。它没有使用传统的切 patch 线性投影而是用两个连续的 3×3、stride 2 卷积逐级把分辨率降到原来的 1/4self.projection nn.Sequential( nn.Conv2d(self.num_channels, hidden_size // 2, kernel_size(3, 3), stride(2, 2), padding(1, 1)), nn.Conv2d(hidden_size // 2, hidden_size, kernel_size(3, 3), stride(2, 2), padding(1, 1)), )注意源码中显式限制if patch_size 4: pass else: # TODO: Support arbitrary patch sizes. raise ValueError(Dinat only supports patch size of 4 at the moment.)这与文档现时仅支持 patch size 4的说明一致——这是当前实现层面的硬性约束而非配置建议。嵌入后还会接LayerNorm与DropoutDinatEmbeddingsL122-L141。2.2 四阶段编码器与卷积下采样器DinatEncoderL462-L529包含len(config.depths)个 stage默认 4 个。每个 stage 的维度为embed_dim * 2**i64 → 128 → 256 → 512其内部的每个 layer 使用不同的扩张值来自config.dilations[i]。阶段之间用DinatDownsamplerL180-L200衔接一个 3×3、stride 2 的卷积将特征图分辨率减半、通道数翻倍再跟一层 LayerNorm。最后一个 stage 之后不再下采样。2.3 核心算子NeighborhoodAttention含 DiNANeighborhoodAttentionL203-L259是 DiNAT 的核心模块其计算流程为对hidden_states分别经过 query / key / value 三个线性层并拆分为多头attention_head_size dim / num_heads在缩放因子1/sqrt(attention_head_size)之后调用 NATTEN 提供的natten2dqkrpb计算扩张近邻注意力原始分数并同时加上可学习的相对位置偏置rpb——源码注释明确说明 rpb is learnable relative positional biases; same concept is used in SwinL217对注意力分数做 softmax 与 dropout调用natten2dav聚合 value得到上下文向量。其中rpb的形状为(num_heads, 2*kernel_size-1, 2*kernel_size-1)L218kernel_size与dilation由配置与所在层共同决定。值得注意的是扩张正是通过把 dilation 参数传入natten2dqkrpb/natten2dav实现的注意力窗口的实际覆盖范围是window_size kernel_size * dilation因而既保持参与计算的 token 数量不变零额外成本又把感受野按层逐级扩大。2.4 DiNAT Layer 的残差结构DinatLayerL344-L412采用 Pre-LayerNorm 的 Transformer 块结构并包含若干工程细节layernorm_before → attention → drop_path → 残差再layernorm_after → intermediateMLP 升维倍率为 mlp_ratio→ outputMLP 降维→ drop_path → 残差当layer_scale_init_value 0时为注意力和 MLP 输出各乘以一组可学习的层缩放参数L359-L363、L398-L407maybe_padL365-L374在特征图小于kernel_size * dilation时做右侧/底部 padding计算后再裁剪回原尺寸L394-L396保证小分辨率输入也能正常前向。2.5 DropPath随机深度DinatDropPathL319-L341是从 Swin 的SwinDropPath复制而来源码标注 Copied from transformers.models.swin...按样本对残差块做随机深度正则drop_prob为 0 或非训练模式下恒等映射否则按1 - drop_prob的概率保留并除以 keep_prob 保持期望一致。drop_path_rate由DinatEncoder在[0, config.drop_path_rate]区间按总层数线性插值分配L467。2.6 输出形态hidden_states 与 reshaped_hidden_states文档Usage tips中特别强调当output_hidden_states True时模型同时输出hidden_states与reshaped_hidden_states且后者的形状是(batch, num_channels, height, width)而不是(batch_size, height, width, num_channels)。这与内部张量布局直接相关整个编码器内部的特征图以(batch, height, width, channels)的 NHWC 布局流动Patch Embedding 输出时已permute成该布局见 L175DinatEncoder在收集隐藏状态时执行hidden_states.permute(0, 3, 1, 2)L497 等把每个 stage 的特征图重排回(batch, channels, height, width)的 NCHW 布局形成reshaped_hidden_states方便直接接入卷积类下游模块如分割/检测头因此做视觉 backbone 时优先使用reshaped_hidden_states而沿用 Transformer 习惯例如拼接序列时可使用hidden_states。DinatModel还包含一个可选的池化层AdaptiveAvgPool1d(1)L559对最后一层特征做平均池化得到pooler_output供分类头使用。三、环境准备NATTEN 依赖安装与限制DiNAT 的注意力计算不包含在本仓库内而是依赖 SHI-Labs 的 NATTEN 对 Neighborhood Attention / Dilated Neighborhood Attention 的高效 CUDA 实现。这一点在源码中有双重印证modeling_dinat.py L37-L45 仅在is_natten_available()为真时从natten.functional导入natten2dav、natten2dqkrpb否则替换为抛出OptionalDependencyNotAvailable的占位函数DinatModel、DinatForImageClassification、DinatBackbone的__init__均调用requires_backends(self, [natten])如 L549未安装时直接报错依赖探测函数is_natten_available()定义于 import_utils.py L1516-L1517缺失时的提示文案见同一文件的NATTEN_IMPORT_ERRORL2144-L2148。安装方式按文档说明# 方式一Linux 使用预编译 wheel推荐参考 shi-labs.com/natten 提供的构建产物 # 方式二在本机源码编译可能耗时较长 pip install natten使用限制NATTEN 目前不支持 Windows 设备编译安装耗时较长安装后可能需要重启运行环境DiNAT 当前仅支持 patch size 4见 2.1 节。提示由于 DiNAT 前向必须依赖 NATTEN 的 CUDA kernel纯 CPU 环境或无 GPU 的容器内使用会受限请以 NATTEN 官方发布说明为准。四、DinatConfig 配置参数详解DinatConfig定义于 configuration_dinat.py L25-L82继承BackboneConfigMixin与PreTrainedConfigmodel_type dinat。其默认值对应shi-labs/dinat-mini-in1k-224风格的配置该 checkpoint 名出现在配置类的自动文档字符串中。全部核心参数如下参数默认值说明patch_size4Patch 大小当前仅支持 4支持int/list/tuple类型声明num_channels3输入图像通道数灰度图可设为 1测试用例中有验证embed_dim64第一个 stage 的嵌入维度之后每级翻倍depths(3, 4, 6, 5)每个 stage 中 DiNAT 层的数量num_heads(2, 4, 8, 16)每个 stage 的注意力头数kernel_size7近邻注意力窗口大小dilations[[1, 8, 1], [1, 4, 1, 4], [1, 2, 1, 2, 1, 2], [1, 1, 1, 1, 1]]编码器中每个 NA 层的扩张值不传时自动使用该默认值mlp_ratio3.0MLP 隐藏层相对维度的放大倍数qkv_biasTrueQ/K/V 线性层是否带偏置hidden_dropout_prob0.0隐藏层 Dropout 概率attention_probs_dropout_prob0.0注意力分数 Dropout 概率drop_path_rate0.1随机深度DropPath最大概率按层线性插值hidden_actgelu中间层激活函数initializer_range0.02权重初始化标准差layer_norm_eps1e-5LayerNorm 的 epsilonlayer_scale_init_value0.0层缩放初始值大于 0 时启用可学习层缩放几个派生属性值得注意L71-L82 的__post_init__num_layers len(depths)attribute_map中把num_hidden_layers映射到num_layers把num_attention_heads映射到num_heads便于与通用配置接口兼容hidden_size embed_dim * 2 ** (len(depths) - 1)即最后一个 stage 的通道数mini 配置下为 512。源码注释说明设置该属性是为了让 DiNAT 能与VisionEncoderDecoderModel配合使用stage_names [stem] [fstage{idx} for idx in range(1, len(depths) 1)]与out_features/out_indices配合供 Backbone 使用。dilations参数是 DiNAT 区别于 NAT 的关键默认配置中第一个 stage 使用[1, 8, 1]——中间层的 dilation 高达 8意味着该层注意力以 8 为间隔采样远处的 token从而以稀疏方式捕获全局上下文越到后期 stage扩张越趋于 1[1, 1, 1, 1, 1]回归更精细的局部建模。五、模型类与实战用法5.1 从配置实例化模型参照 configuration_dinat.py L30-L43 中的示例可以先用配置初始化随机权重模型from transformers import DinatConfig, DinatModel # 初始化一个 shi-labs/dinat-mini-in1k-224 风格的配置 configuration DinatConfig() # 用随机权重初始化模型 model DinatModel(configuration) # 访问模型配置 configuration model.config5.2 DinatModel纯编码器输出DinatModelmodeling_dinat.py L541-L613是基础编码器前向参数包括pixel_values、output_attentions、output_hidden_states、return_dict。返回的DinatModelOutputL76-L92包含last_hidden_state最后一层输出形状(batch, height, width, channels)pooler_output平均池化结果形状(batch, hidden_size)hidden_states与reshaped_hidden_states各 stage 隐藏状态详见 2.6 节attentions各层注意力权重需要output_attentionsTrue。测试用例 test_modeling_dinat.py L132-L143 验证了前向输出形状对image_size64、depths[1,2,1]的配置last_hidden_state的形状应为(batch, 64//4//2**2, 64//4//2**2, 16*2**2)即每经过一个 stage 分辨率减半、通道翻倍——这与架构设计完全一致。5.3 DinatForImageClassification图像分类DinatForImageClassificationL622-L682在DinatModel之上加一个线性分类头nn.Linear(self.dinat.num_features, config.num_labels)当num_labels 0否则为nn.Identity。labels传入时自动计算损失num_labels 1时用 MSE 回归损失num_labels 1时用交叉熵分类损失。推理示例from transformers import AutoImageProcessor, AutoModelForImageClassification from PIL import Image processor AutoImageProcessor.from_pretrained(shi-labs/dinat-mini-in1k-224) model AutoModelForImageClassification.from_pretrained(shi-labs/dinat-mini-in1k-224) image Image.open(path/to/your/image.jpg) inputs processor(image, return_tensorspt) with torch.no_grad(): logits model(**inputs).logits predicted_class_id logits.argmax(-1).item() print(model.config.id2label[predicted_class_id])仓库还提供了完整的图像分类训练脚本 run_image_classification.py 及其无 Trainer 版本run_image_classification_no_trainer.py依赖见同目录 requirements.txt可配合--model_name_or_path shi-labs/dinat-mini-in1k-224等参数直接进行微调或评估。文档将 [DinatForImageClassification] 的官方支持资源指向该示例脚本与官方图像分类 notebook本仓库内可直接运行的是前者。5.4 DinatBackbone作为下游视觉任务的骨干网络文档明确指出 DiNAT can be used as abackbone可作为骨干网络使用。虽然文档的 autodoc 列表只列出DinatConfig、DinatModel、DinatForImageClassification但当前仓库源码中还提供了DinatBackboneL690-L789继承BackboneMixin专为 DETR、MaskFormer 等检测/分割框架设计源码注释 NAT backbone, to be used with frameworks like DETR and MaskFormer。DinatBackbone前向返回BackboneOutput其中feature_maps为各指定 stage 的多尺度特征图它对每个输出 stage 额外套了一层 LayerNormL700-L704并对不在out_features中的 stage 做过滤。其 docstring 中给出了用AutoImageProcessorAutoBackbone提取特征图的示例流程指定out_features[stage1, stage2, stage3, stage4]后最后一个 stage 的 feature map 形状为[1, 512, 7, 7]输入 224×224 时。注意该示例使用的是shi-labs/nat-mini-in1k-224checkpoint实际使用 DiNAT 时可换成对应的shi-labs/dinat-*系列 checkpoint。测试方面test_modeling_dinat.py L162-L187 验证了 backbone 的输出指定out_features时feature_maps数量与通道数与之对应out_featuresNone时退化为仅输出最后一层形状[batch, channels[-1], 4, 4]并在 L196 起通过require_natten装饰器把整套测试限定在已安装 NATTEN 的环境中运行。5.5 任务指南衔接图像分类是 DiNAT 最直接的落地任务完整的任务级说明参见 图像分类任务指南。六、使用注意事项与限制汇总硬性依赖 NATTEN任何 DiNAT 模型类实例化都会触发requires_backends(self, [natten])必须先安装 NATTEN见第三节平台限制NATTEN 暂不支持 WindowsLinux 用户优先使用预编译 wheel 避免长时间编译patch size 固定为 4源码在DinatPatchEmbeddings中直接对非 4 的 patch size 抛ValueError目前无绕过途径输入通道校验pixel_values的通道数必须与config.num_channels一致L169-L173灰度图需显式把num_channels设为 1隐藏状态布局hidden_states为(batch, height, width, channels)reshaped_hidden_states为(batch, channels, height, width)接入下游模块前务必确认所需布局输出形状推导每个 stage 分辨率减半、通道翻倍最后一层特征分辨率约为input_size / patch_size / 2**(len(depths)-1)测试用例 L138-L139 的推导式即此逻辑配置超大kernel_size * dilation与过小输入时需注意maybe_pad的边界处理。七、小结DiNAT 通过局部 NA 稀疏 DiNA的组合在层级架构中同时兼顾了局部精细建模与全局上下文捕获是 NAT 的重要演进。在本仓库中它由 DinatConfig 提供配置、modeling_dinat.py 提供DinatModel、DinatForImageClassification与DinatBackbone三种模型形态分别覆盖纯特征提取、图像分类与多尺度骨干网络三类场景test_modeling_dinat.py 则对输出形状、backbone 行为与灰度图输入等关键路径做了系统验证。上手时请务必先解决 NATTEN 依赖再结合 图像分类示例脚本 快速跑通训练与推理链路。【免费下载链接】transformers Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and multimodal models, for both inference and training.项目地址: https://gitcode.com/GitHub_Trending/tra/transformers创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考