草庐IT

论文笔记:InternImage—基于可变形卷积的视觉大模型,超越ViT视觉大模型,COCO 新纪录 64.5 mAP!

苏三平 2025-06-04 原文

目录

文章信息

  • Title:InternImage: Exploring Large-Scale Vision Foundation Models with Deformable Convolutions
  • Paper Link:https://arxiv.org/abs/2211.05778
  • Code Link:https://github.com/OpenGVLab/InternImage

写在前面

拿到文章之后先看了一眼在ImageNet1k上的结果,确实很高,超越了同等大小下的VAN、RepLKNet、ConvNext等先进的大核注意力CNN模型,同时也超过了Swin、DeiT3、CoAtNet等ViT模型。回顾自从Vision Transformer被提出之后,通过大量数据训练出的ViT大模型刷新了许多视觉任务的记录,这得益于ViT的MHSA机制能够建模长距离依赖,具有相当低的归纳偏置,从而能够在海量数据中学习到强大鲁棒的特征表达。相反的,我们以前经常使用的卷积神经网络具有较高的归纳偏置,在大模型和大数据的条件下的表现却不如ViT大模型。该论文就指出,通过合适的算子、先进的架构设计、大量模型参数和海量数据的训练之下,CNN大模型也可以具有媲美ViT大模型的性能。InternImage设计了全新的可变性卷积模块,并且借鉴了ViT的先进架构和相关组件,从而设计出一个新的CNN大模型。并且,InternImage在相关的下游任务上的性能也很高,InternImage-H在目标检测COCO数据集上达到了 65.4 65.4% 65.4的性能,超越了SwinV2-G大模型的性能。

Background & Motivation

随着基于Transformer的语言大模型在NLP相关下游任务中取得优异性能,Vision Transformer也席卷了CV领域,成为基础视觉大模型研究和实践的首选。Swin V2、BeiT、CoAtNet等工作已经将ViT扩展到超过十亿参数规模,显著提升了CV分类、检测和分割等下游任务的性能,超越了CNN模型。但是,该论文提出如果CNN具备类似于ViT的算子和架构,并且在大量参数和海量数据情况下,其性能是可以与ViT相同甚至更好的。
作者认为CNN和ViT大模型性能存在差距的主要有两个原因:

  • ViTs的MHSA具有长程依赖和自适应空间聚合能力,从而可以在海量数据中学习到比CNN更强大鲁棒的特征表达。
  • 除MHSA外,ViT还包含不同于CNN的高级组件,如层归一化、前馈网络、GELU等。

基于此,该论文设计了一个新颖的基于可变性卷积CNN网络——InternImage,可以在大量参数和海量数据的情况下表现很好。如下图所示,动态稀疏可变性卷积既不像MHSA那样具有较高复杂度,也不像Local attention那样缺乏长程依赖,同时具有自适应的空间聚合能力。

该论文的主要贡献如下:

  • 提出一种新的CNN大模型——InternImage,首个参数达1B、训练数据达400M、取得与ViT相当甚至更优性能的CNN模型。证明对于大尺度模型研究,CNN同样是一个值得探索的方向。
  • 将长程依赖、自适应空域聚合引入到DCNv3,将CNN模型的大小和尺度进行扩展;并对模块定制化、堆叠规则以及缩放策略进行了探索。
  • 在图像分类、目标检测、语义分割以及实例分割等下游任务上验证了所提方案的有效性。其中,InternImage-B仅在ImageNet-1K训练即可取得84.9%的精度(比其他CNN至少高出1.1%);当在大量参数(1B)、海量数据(427M)条件下,InternImage-H取得了89.2%的性能;在COCO数据集上,InternImage-H以2.18B的参数量取得了65.4%mAP,比SwinV2-G高出2.3%,参数量少27% 。

Method

该论文首先从DCNv2算子开始实验,然后借鉴了MHSA的相关思想对DCN V2做出了三个关键改进,设计出了全新的DCNv3算子;基于此算子,作者又提出了与ViT相似的Basic Block组成了InternImage网络,并且给出了InternImage的堆叠规则和大小缩放规则。

DCN V2

在提出DCN V3算子前,作者先回顾了一下传统卷积和多头自注意力机制这两种算子的区别,主要包括如下两点:

  • 长距离建模能力。普通的卷积聚合邻域内的信息,显然不具备全局建模的能力,尽管传统的CNN能够通过堆叠多个 3 × 3 3 \times 3 3×3的卷积增加模型的感受野,但是仍然不能像ViT那样进行全局的交互。
  • 自适应空间聚合能力。多头自注意力机制在聚合不同的tokens的时候,权重都是根据输入query的不同而动态变化的;而传统的CNN不管输入是什么,卷积核的参数都是静态不变的。

然后回过头看一下DCN V2算子,其恰好是具有上述两个特性的;对于给定输入 x ∈ R C × H × W \mathbf{x}\in \mathbb{R} ^{C\times H\times W} xRC×H×W 和某像素 p 0 p_0 p0,DCN V2算子的输出如下
y ( p 0 ) = ∑ k = 1 K w k m k x ( p 0 + p k + △ p k ) \mathbf{y}\left( p_0 \right) =\sum_{k=1}^K{\mathbf{w}_k\mathbf{m}_k\mathbf{x}\left( p_0+p_k+\bigtriangleup p_k \right)} y(p0)=k=1Kwkmkx(p0+pk+pk)其中, K K K表示采样点的个数、 w k \mathbf{w}_k wk为相应采样点的投影权重、 m k \mathbf{m}_k mk代表了相应采样点的调制标量、 △ p k \bigtriangleup p_k pk表示相应采样点的偏移量。
由这个表达式可以看出:

  • DCN V2算子可以通过偏移量来与局部或全局的交互,具有长距离建模的能力;
  • 由于调制标量 m k \mathbf{m}_k mk和偏移量 △ p k \bigtriangleup p_k pk都是可学习并且根据输入不同而变化的,所以DCN V2算子也具有类似于MHSA的自适应空间聚合能力。

因此,DCN V2算子具备MHSA算子的相关特性,有可能构成大规模的CNN基础模型。

DCN V3

尽管DCN V2算子已经缩小了普通卷积算子和MHSA之间的差距,对于大规模的视觉基础模型来说,DCN V2算子仍然不是最优的选择,于是作者从三个方面对DCN V2进行改进,得到了IntenImage的主要算子——DCN V3。

  1. 共享卷积权重。在DCN V2中,对于每一个采样点处的特征向量,都使用一个独立的投影权重。当采样点增多的时候,模型的参数和复杂度将会线性增加,不利于构建大规模的模型。在这里,作者借鉴了深度可分离卷积的思想来降低DCN算子的复杂度;具体地。对于point-wise,也就是不同的采样点向量,使用一个共享的权重 w w w来进行投影;而对于depth-wise,则直接使用算子中的调制标量 m k \mathbf{m}_k mk来代替。总体来说就是用同一个同权重对采样点进行投影,然后用一个位置感知的可学习系数对投影后的特征向量进行加权。
  2. 引入多组机制。回顾多头自注意力机制中的“多头”思想,不同的head实际上能够提供在不同子空间的丰富的信息。因此,作者将DCN V3也进行分组,在每组中进行不同的偏移采样、采样向量投影、因子调制。相当于把原来的操作重复多次,增强了DCN V3算子的表达能力(确实应该这样设计,不然只有一个共享的投影权重的话,特征表达的确单一)。
  3. 归一化调制标量。这个是因为在原始的DCN V2中,调制标量是用sigmoid进行处理的,对于 K K K个调制因子来说,其和并不是 1 1 1。作者指出,这样会导致训练不稳定的问题,因此作者改为了对 K K K个调制因子进行 s o f t m a x softmax softmax归一化,使得整个训练过程更为稳定。

以上三个点都是根据论文理解而来,因为现在作者还没有公布InternImage模型代码,无法查看具体的实现细节。综上所述,完整的DCN V3算子可以表示如下 y ( p 0 ) = ∑ g = 1 G ∑ k = 1 K w g m g k x g ( p 0 + p k + △ p g k ) \mathbf{y}\left( p_0 \right) =\sum_{g=1}^G{\sum_{k=1}^K{\mathbf{w}_g\mathbf{m}_{gk}\mathbf{x}_g\left( p_0+p_k+\bigtriangleup p_{gk} \right)}} y(p0)=g=1Gk=1Kwgmgkxg(p0+pk+pgk)
其中, G G G表示group的数量。 w g \mathbf{w}_g wg每组内共享投影权重, m g k \mathbf{m}_{gk} mgk表示第 g g g组第 k k k个采样点的归一化后的调制因子。如此一来 ,新设计的DCN V3算子弥补了传统卷积在长程依赖和自适应空间聚合方面的不足,同时使得可变性卷积算子更加适用于视觉大模型;在实现了稀疏全局建模的同时,又适当的保留了CNN的归纳偏置,可以说是在计算量和准确度之间进行了更好的权衡。

模型架构


在设计完DCN v3算子后,作者抛弃了传统CNN的Block设计方式,而是采用了与ViT类似的整体架构设计。如上图所示,基本模块与ViT相同,什么LN、FFN、GELU激活函数都使用上了;downsample模块也是采用了正常的3*3、stride2、pooling1模块。然后按照论文中的堆叠和缩放策略就可以构建出完整的InternImage模型了。

Experiment

分类


部分模型在ImageNet 1K上的效果如上图所示,可以说是非常SOTA了,超越了同等大小下的VAN、RepLKNet、ConvNext等先进的大核注意力CNN模型,同时也超过了Swin、DeiT3、CoAtNet等ViT模型。

检测


在COCO val2017 和 test-dev 上的性能在当时也达到了SOTA的水平,确实可以。

有关论文笔记:InternImage—基于可变形卷积的视觉大模型,超越ViT视觉大模型,COCO 新纪录 64.5 mAP!的更多相关文章

  1. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  2. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  3. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  4. ruby-on-rails - 如何验证非模型(甚至非对象)字段 - 2

    我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss

  5. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

  6. ruby-on-rails - 如何将验证与模型分开 - 2

    我有一些非常大的模型,我必须将它们迁移到最新版本的Rails。这些模型有相当多的验证(User有大约50个验证)。是否可以将所有这些验证移动到另一个文件中?说app/models/validations/user_validations.rb。如果可以,有人可以提供示例吗? 最佳答案 您可以为此使用关注点:#app/models/validations/user_validations.rbrequire'active_support/concern'moduleUserValidationsextendActiveSupport:

  7. ruby-on-rails - Rails 模型——非持久类成员或属性? - 2

    对于Rails模型,是否可以/建议让一个类的成员不持久保存到数据库中?我想将用户最后选择的类型存储在session变量中。由于我无法从我的模型中设置session变量,我想将值存储在一个“虚拟”类成员中,该成员只是将值传递回Controller。你能有这样的类(class)成员吗? 最佳答案 将非持久属性添加到Rails模型就像任何其他Ruby类一样:classUser扩展解释:在Ruby中,所有实例变量都是私有(private)的,不需要在赋值前定义。attr_accessor创建一个setter和getter方法:classUs

  8. ruby-on-rails - Rails - 从另一个模型中创建一个模型的实例 - 2

    我有一个正在构建的应用程序,我需要一个模型来创建另一个模型的实例。我希望每辆车都有4个轮胎。汽车模型classCar轮胎模型classTire但是,在make_tires内部有一个错误,如果我为Tire尝试它,则没有用于创建或新建的activerecord方法。当我检查轮胎时,它没有这些方法。我该如何补救?错误是这样的:未定义的方法'create'forActiveRecord::AttributeMethods::Serialization::Tire::Module我测试了两个环境:测试和开发,它们都因相同的错误而失败。 最佳答案

  9. ruby-on-rails - Ruby 中的内存模型 - 2

    ruby如何管理内存。例如:如果我们在执行过程中采用C程序,则以下是内存模型。类似于这个ruby如何处理内存。C:__________________|||stack|||------------------||||------------------|||||Heap|||||__________________|||data|__________________|text|__________________Ruby:? 最佳答案 Ruby中没有“内存”这样的东西。Class#allocate分配一个对象并返回该对象。这就是程序

  10. ruby-on-rails - Rails 3.1 中具有相同形式的多个模型? - 2

    我正在使用Rails3.1并在一个论坛上工作。我有一个名为Topic的模型,每个模型都有许多Post。当用户创建新主题时,他们也应该创建第一个Post。但是,我不确定如何以相同的形式执行此操作。这是我的代码:classTopic:destroyaccepts_nested_attributes_for:postsvalidates_presence_of:titleendclassPost...但这似乎不起作用。有什么想法吗?谢谢! 最佳答案 @Pablo的回答似乎有你需要的一切。但更具体地说...首先改变你View中的这一行对此#

随机推荐