1. 从“看”到“理解”:视觉任务范式的分野
最近和几个做计算机视觉的朋友聊天,发现一个挺有意思的现象:大家讨论模型选型时,Transformer和CNN(卷积神经网络)几乎成了两个绕不开的“阵营”。新手入门,往往会被各种缩写和概念搞晕:ViT、Swin Transformer、ResNet、EfficientNet…… 这些模型到底有什么区别?为什么Transformer一出来,就好像要颠覆CNN的“统治地位”?我自己在图像分类、目标检测这些项目里都深度用过这两类模型,今天就想从一个实践者的角度,掰开揉碎了聊聊ViT(Vision Transformer)的模型架构,以及它和传统CNN最核心的区别到底在哪。这不仅仅是学术上的概念辨析,更直接关系到我们做项目时,该如何根据数据、算力和任务目标,做出最合适的技术选型。
简单来说,你可以把CNN想象成一个经验老道的“局部侦察兵”。它有一双精心设计的“卷积核”眼睛,这双眼睛被训练得特别擅长捕捉图像中局部、连续的图案,比如边缘、角点、纹理。它看图片的方式是“由近及远,从局部到整体”:先看清一个个小方块(像素)组成的边缘,然后把这些边缘组合成更复杂的图案(比如车轮、窗户),最后再识别出这是一个“汽车”或者“房子”。CNN的这种“归纳偏置”(Inductive Bias)——即对平移不变性和局部相关性的强假设——让它特别高效,用相对少的参数和计算量就能在图像数据上取得很好的效果,这也是过去十年它统治计算机视觉领域的根本原因。
而ViT,则更像是一个试图“通读全文”的“语言学家”。它借鉴了NLP(自然语言处理)领域大获成功的Transformer架构,其核心思想是“注意力机制”。ViT处理图像的第一步,是把一张完整的图片,切割成一个个固定大小的图像块(Patch),比如16x16像素。然后把这些图像块线性映射成一系列向量,称为“Patch Embeddings”。接下来,ViT会为这些图像块序列加上位置编码(因为Transformer本身没有空间顺序的概念),然后送入一个标准的Transformer Encoder。在这个Encoder里,模型通过“自注意力”(Self-Attention)机制,让序列中的每一个图像块(Patch)都能和序列中所有其他的图像块进行交互和“沟通”,从而计算出一张全局的“关系图”。它没有预先假设局部信息更重要,而是让数据自己告诉模型,哪些区域之间的关系对于完成分类任务是关键的。
所以,最根本的区别在于处理视觉信息的基本哲学:CNN是基于局部卷积的、层次化的特征提取器,而ViT是基于全局注意力机制的、关系建模器。CNN从设计上就相信“邻近像素关联性强”,并以此构建网络;ViT则试图抛弃这种先验,完全依赖数据驱动,让模型自己去发现图像中任意两个部分之间的关联,无论它们相隔多远。这种根本性的差异,导致了它们在架构、数据需求、计算特性和应用表现上的一系列不同。接下来,我们就深入模型内部,看看这些差异具体是如何体现的。
2. ViT架构拆解:当Transformer“看见”世界
要理解ViT和CNN的区别,必须先把ViT的“五脏六腑”看清楚。很多人觉得Transformer架构复杂,其实拆解开来,它的设计逻辑非常清晰。ViT的整个流程,可以概括为“分块、嵌入、编码、分类”四个核心步骤。
2.1 图像分块与嵌入:从像素到“单词”
这是ViT处理图像的第一步,也是最关键的一步,因为它完成了从2D图像到1D序列的转换。
- 分块(Patch Partition):假设我们有一张分辨率是224x224的RGB图像。ViT会将它均匀地切割成多个固定大小的正方形块。在原始论文中,这个大小通常是16x16。那么,一张224x224的图,就会被切成 (224/16) * (224/16) = 14 * 14 = 196个图像块。每个图像块是16x16x3=768维的像素值(16宽16高3颜色通道)。
- 线性投影(Linear Projection):这196个图像块,每个都是768维的向量。我们需要通过一个可训练的线性层(一个全连接层),将它们映射到一个固定的维度D上,这个D就是Transformer模型隐藏层的大小(例如768)。这个操作被称为“Patch Embedding”。经过这一步,我们得到了一个形状为
[196, 768]的矩阵,可以理解为196个“视觉单词”,每个单词是768维的特征向量。 - 添加[CLS]标记与位置编码:
- [CLS] Token]:借鉴BERT,ViT会在序列的最前面添加一个额外的、可学习的嵌入向量,称为
[CLS]token。这个token本身不包含任何图像信息,它的作用是在经过Transformer Encoder的多层交互后,聚合整个序列的全局信息,最终用于图像分类。所以,序列长度从196变成了197。 - 位置编码(Positional Encoding):Transformer本身是置换不变的(Permutation-Invariant),它不知道输入的序列是有顺序的。但对于图像来说,空间位置信息至关重要(天空通常在顶部,草地通常在底部)。因此,ViT需要为每一个图像块(以及
[CLS]token)添加一个位置编码向量,来告知模型它的原始空间位置。这个编码可以是固定的(如正弦余弦函数),也可以是可学习的。最终,嵌入向量加上位置编码,就构成了Transformer Encoder的输入。
- [CLS] Token]:借鉴BERT,ViT会在序列的最前面添加一个额外的、可学习的嵌入向量,称为
注意:这里有一个非常重要的实操细节。图像分块的大小直接决定了序列的长度。16x16的分块得到196的长度,如果使用更小的分块(如8x8),序列长度会变成784,这将导致计算量(尤其是注意力计算)呈平方级增长。因此,分块大小是平衡模型性能与计算成本的一个关键超参数。
2.2 Transformer Encoder:全局关系的“议会”
经过嵌入的序列([CLS]+ 197个图像块)被送入一个由L个相同层堆叠而成的Transformer Encoder。每一层都包含两个核心子层:
- 多头自注意力层(Multi-Head Self-Attention, MSA):这是Transformer的灵魂。对于序列中的每一个元素(比如第i个图像块),MSA会计算它与序列中所有其他元素(包括它自己)的“注意力分数”。这个分数决定了在更新第i个元素的表示时,应该“关注”其他元素的程度。具体来说:
- Query, Key, Value:每个输入向量通过三个不同的线性变换,生成Query、Key、Value三组向量。
- 注意力计算:第i个位置的Query向量会与所有位置的Key向量进行点积,然后经过Softmax归一化,得到一组权重。这组权重再与所有位置的Value向量加权求和,就得到了第i个位置更新后的表示。公式简化表达为:
Attention(Q, K, V) = softmax(QK^T / sqrt(d_k)) V。 - “多头”的意义:MSA不是只做一次上述计算,而是并行地做h次(例如12次),每次使用不同的投影矩阵,相当于从h个不同的“子空间”或“视角”去计算注意力。最后将h个结果拼接起来,再经过一次线性变换。这能让模型同时关注来自不同位置的不同类型的信息。 通过MSA,图像中任意两个块,无论它们相距多远(比如图片左上角的天空和右下角的汽车),都能直接建立联系。这是CNN通过堆叠多层卷积才能间接实现的“远程依赖”建模。
- 多层感知机层(MLP):在MSA之后,每个位置的特征会经过一个简单的两层全连接网络(通常中间包含一个GELU激活函数)。这个MLP的作用是对MSA提取的、经过交互的特征进行非线性变换和增强。
- 残差连接与层归一化:每个子层(MSA和MLP)周围都包裹着残差连接和层归一化。即:
LayerOutput = MLP(LayerNorm(x + MSA(LayerNorm(x))))。这种设计是训练深层网络稳定性的关键,能有效缓解梯度消失问题。
经过L层(例如12层)这样的处理,序列中每个位置的表示都融合了全局的上下文信息。此时,序列最前面的那个[CLS]token的最终表示,就被认为包含了整张图像的全局语义信息。
2.3 分类头与输出
最后,我们将[CLS]token对应的输出向量,通过一个轻量级的MLP分类头(通常就是一个全连接层),映射到目标类别数上,再经过Softmax得到分类概率。
一个完整的ViT-Base模型参数示例:输入224x224图像,分块大小16x16,隐藏维度D=768,Transformer层数L=12,注意力头数h=12,MLP隐藏层维度为3072。总参数量大约在8600万左右,与ResNet-50规模相当。
从架构流程可以看出,ViT完全摒弃了卷积操作。它对图像空间结构的理解,完全依赖于从数据中学到的位置编码和自注意力机制。这种“无卷积”的设计,是它与CNN最直观的架构区别。
3. CNN的运作机理:层次化的局部特征工厂
在ViT的对比下,我们有必要重新审视一下CNN这个“老朋友”的核心工作原理。CNN的架构思想深受生物视觉皮层的启发,其设计充满了对图像数据统计特性的深刻洞察和精巧利用。
3.1 卷积层:局部特征检测器
卷积层是CNN的基石。它的核心是一个可学习的卷积核(或滤波器)。这个卷积核通常是一个小尺寸(如3x3、5x5)的二维矩阵。它在输入图像或特征图上进行滑动窗口式的操作:
- 局部连接:每次只关注输入的一小块局部区域(感受野),计算该区域像素与卷积核的点积。
- 权重共享:同一个卷积核会滑过整张图的所有位置。这意味着无论边缘出现在图像的左上角还是右下角,都由同一个“边缘检测器”来识别。这极大地减少了参数量,并赋予了模型平移不变性——物体在图像中移动位置,不影响对其的识别。
- 特征图:一个卷积核的输出是一张特征图,它激活了输入中符合该卷积核模式的区域。例如,一个检测“右斜边缘”的卷积核,会在包含右斜边缘的区域输出高值。通过使用多个不同的卷积核,我们就能得到多张特征图,每张图捕捉一种特定的局部模式。
3.2 池化层与非线性激活:抽象与不变性
- 池化层(Pooling):通常在卷积层之后插入。最大池化(Max Pooling)是最常用的,它在一个小窗口(如2x2)内取最大值。它的核心作用有两个:一是降维,减少计算量和参数;二是引入一定程度的平移、旋转、缩放不变性。因为只要窗口内最强的特征被保留,其精确位置信息就被模糊化了。这有助于模型关注“有什么特征”,而不是“特征精确在哪”。
- 非线性激活函数:如ReLU,为网络引入非线性变换,使得网络能够拟合复杂的函数。没有非线性,多层网络就等价于单层网络。
3.3 层次化架构:从简单到复杂的特征组装
CNN的强大之处在于其层次化、端到端的学习方式:
- 浅层网络:学习到的是低级、通用的特征,如边缘、角点、颜色、纹理。这些特征对于大多数视觉任务都是有用的。
- 中层网络:通过组合低级特征,形成更复杂的图案,如车轮、窗户、动物的四肢。
- 深层网络:进一步组合中层特征,形成与高级语义相关的部件或整体,如“车头”、“人脸”、“整个建筑物”。
这个过程就像一个特征工厂的流水线:原材料(像素)经过一道道工序(卷积、激活、池化),被逐步加工成越来越抽象、语义性越来越强的“零件”和“产品”。这种设计使得CNN非常数据高效,因为它的结构本身(局部性、平移不变性)就编码了关于图像世界的大量先验知识,模型不需要从零开始学习这些规律。
以ResNet-50为例,它通过残差块堆叠了50层,早期层用大卷积核(7x7)快速下采样,后续大量使用3x3小卷积核进行深度特征提取。其参数量约2500万,但得益于卷积的局部性和权重共享,其计算效率(FLOPs)和内存访问模式对硬件(尤其是GPU)非常友好。
4. 核心差异对比:哲学、效率与数据依赖
理解了各自的架构,我们可以从多个维度对ViT和CNN进行系统性的对比。这些差异决定了它们各自的应用场景和优劣。
4.1 归纳偏置:内置假设 vs. 数据驱动
这是最根本的差异,决定了模型的学习方式。
- CNN的归纳偏置:局部性(相邻像素关联性强)和平移等变性(物体移动,其特征表示也相应移动)。CNN的结构强制模型从局部开始感知,并通过池化逐步获得全局视图。这是一种“自底向上”的、强假设引导的路径。
- ViT的归纳偏置:最少。ViT的结构本身几乎没有对图像空间结构做任何硬性假设。它对局部性的感知,完全依赖于在足够大数据上学习到的位置编码和注意力权重。它通过自注意力机制,理论上在第一层就能建立任意两个图像块之间的联系,是一种“全局关联优先”的、数据驱动的路径。
影响:CNN的强归纳偏置使其在中小型数据集上表现优异,因为它不需要海量数据来“发现”局部性这个显而易见的规律。而ViT在数据不足时,可能因为缺乏这种引导而难以学到有效的特征,导致性能不如CNN。但当数据量极大时(如JFT-300M),ViT摆脱了“局部性”的束缚,能够挖掘出数据中更复杂、更长程的依赖关系,其性能上限可能更高。
4.2 计算特性与效率
- 计算复杂度:
- CNN:计算量主要来自卷积操作。对于一个
H x W x C的输入和K x K的卷积核,输出通道为C‘,其计算复杂度约为O(H * W * C * C‘ * K * K)。由于K通常很小(3或5),且随着网络加深,H和W通过池化或步幅卷积减小,所以计算效率很高。 - ViT:计算瓶颈在自注意力层。对于长度为N的序列,其复杂度为
O(N^2 * D),其中D是特征维度。N是图像块的数量,对于224x224图像和16x16分块,N=196,这个平方项已经不小。如果图像分辨率增大或分块变小,N会急剧增加(如384x384图像,16x16分块,N=576),导致计算量爆炸式增长。
- CNN:计算量主要来自卷积操作。对于一个
- 硬件友好度:
- CNN:卷积操作是高度规则、可并行化的计算,与GPU的SIMD架构完美匹配,计算密度高,能效比好。
- ViT:自注意力机制涉及大量的矩阵乘法和Softmax操作,虽然也可并行,但其内存访问模式不如卷积规则,对硬件缓存不友好。尤其是在处理长序列时,
N^2的内存占用会成为瓶颈。
实操心得:在资源受限的边缘设备或实时应用中,轻量级CNN(如MobileNet, ShuffleNet)目前仍是首选。ViT及其变种(如Swin Transformer引入了局部窗口注意力)正在努力优化计算效率,但在同等性能下,其推理速度通常仍慢于优化良好的CNN。
4.3 特征表示与感受野
- 感受野:
- CNN:一个神经元的感受野(能看到的输入图像区域)随着网络层数的加深而逐步扩大。底层神经元看到局部边缘,高层神经元才能看到全局物体。要建立远程依赖,需要堆叠很多层。
- ViT:从第一层Transformer Encoder开始,每个图像块(通过自注意力)就能看到所有其他图像块。也就是说,ViT从一开始就拥有全局感受野。这使得它天生擅长建模图像中远距离元素之间的关系。
- 特征交互方式:
- CNN:特征交互是层次化、顺序式的。信息从局部流向全局,传递路径长,可能存在信息稀释。
- ViT:特征交互是全局、并行式的。所有块在同一层内直接交换信息,信息流通路径短,更直接。
影响:对于需要理解全局场景结构或长程依赖的任务,如图像中多个分散物体的关系判断、某些类型的图像分割,ViT的全局注意力机制显示出优势。而CNN在捕捉精细的局部纹理和模式方面,由于其专注的局部计算,有时表现得更加鲁棒。
4.4 数据依赖性与训练策略
- 数据需求:如前所述,ViT是典型的“大数据模型”。原始ViT论文指出,在ImageNet-1K(130万张图)这样的数据集上训练,ViT的性能不如同等规模的CNN(如ResNet)。但当在超大数据集(如JFT-300M,3亿张图)上预训练后,再迁移到ImageNet上做微调,ViT的性能实现了反超。CNN则对数据量的要求相对温和。
- 训练技巧:ViT的训练通常需要更强的正则化(如Dropout, Stochastic Depth),更精细的学习率调度(如Cosine Decay),以及可能的数据增强(如RandAugment, MixUp)。CNN的训练流程则相对更加成熟和稳定。
5. 实战选型:什么场景用谁?兼谈混合架构
理论对比之后,落到实际项目上,我们该如何选择?这里没有银弹,只有权衡。
5.1 优先考虑CNN的场景
- 数据量有限:如果你的标注数据只有几千到几十万张,CNN(特别是经过ImageNet预训练的模型)通常是更安全、更容易取得好效果的选择。它的强归纳偏置起到了正则化作用,防止过拟合。
- 计算资源紧张:需要部署在手机、嵌入式设备或要求高帧率的实时系统(如自动驾驶感知、视频监控)。轻量级CNN架构经过多年优化,在精度-速度权衡上目前仍有优势。
- 任务强依赖局部纹理:例如细粒度图像分类(区分不同品种的狗、鸟)、医学图像分析(细胞形态、组织纹理)、工业缺陷检测(微小划痕、斑点)。CNN捕捉局部细节的能力非常出色。
- 项目周期短,追求稳定:CNN的生态极其成熟,有大量现成的预训练模型、训练技巧和部署工具包(如TorchVision, TensorFlow Hub)。可以快速搭建baseline并迭代。
5.2 优先考虑ViT的场景
- 拥有海量数据:如果你能获取或生成数百万甚至上亿的标注/无标注图像数据,ViT的潜力更大。在大数据预训练后,其迁移到下游任务的能力非常强。
- 任务需要全局上下文理解:
- 图像分类:需要理解整体场景才能分类的图片(例如,判断一张图是“婚礼”还是“会议”,需要综合看人物、装饰、环境等多个分散元素)。
- 目标检测与分割:特别是需要理解物体间关系的场景(如“人骑摩托车”)。一些基于ViT的检测器(如DETR)省去了Anchor和NMS等复杂后处理。
- 多模态任务:如图像描述生成、视觉问答(VQA)。Transformer架构天然适合处理序列数据,便于与文本模态对齐。
- 追求SOTA性能:在许多主流视觉榜单上,基于ViT或类似架构的模型(如Swin Transformer, DeiT)已经占据了榜首。如果你的目标是刷榜,ViT及其变体是必须深入研究的。
- 研究与探索性项目:如果你想探索模型架构的前沿,或者你的数据本身具有长程依赖特性(如某些遥感图像、天文图像),ViT是一个值得尝试的方向。
5.3 混合架构:取二者之长的未来趋势
纯粹的ViT和CNN并非水火不容,近年来大量的工作致力于融合二者的优点,形成了强大的混合架构(Hybrid Architecture)。这可能是目前最实用的方向。
- CNN作为特征提取器 + Transformer作为关系建模器:这是一种非常有效的模式。例如,用一个轻量的CNN主干网络(如ResNet的前几层)来处理图像,得到下采样后的特征图。然后将这个特征图展平或进一步切块,作为序列输入Transformer Encoder。这样既利用了CNN在早期高效提取低级局部特征的能力,又利用了Transformer强大的全局关系建模能力。许多视频理解、图像分割的SOTA模型都采用了这种设计。
- 在Transformer中引入卷积先验:代表工作是Swin Transformer。它提出了“窗口注意力”和“移位窗口”机制。将自注意力计算限制在一个个局部窗口内,大幅降低了计算复杂度(从
O(N^2)降到O(N))。再通过层与层之间窗口的移动,实现跨窗口的信息传递。这种设计巧妙地引入了CNN的“局部性”和“层次性”思想,同时保留了Transformer的全局建模潜力,在速度和精度上取得了极佳的平衡。 - 在CNN中引入注意力机制:这其实在ViT之前就存在,如SENet、CBAM等模块。它们在CNN的特征图上施加通道注意力或空间注意力,让模型可以自适应地强调重要特征。可以看作是“卷积主菜”加了一点“注意力调料”。
我的个人体会是,对于大多数工业界的计算机视觉项目,不要陷入“非此即彼”的阵营之争。更务实的做法是:
- 从CNN基线开始:用ResNet、EfficientNet等成熟模型快速验证任务可行性和数据质量。
- 尝试ViT/混合模型以提升性能:如果数据充足,且基线模型表现遇到瓶颈,尤其是感觉模型对全局上下文利用不足时,可以尝试引入Transformer。可以从在CNN基础上加一个轻量的Transformer模块开始,或者直接使用Swin Transformer这类混合架构。
- 始终以部署环境为准绳:最终模型的选择必须经过严格的性能(精度、速度、内存)测试。在服务器端,可以更多考虑精度;在终端设备,则必须把计算效率和功耗放在首位。
ViT的出现不是对CNN的简单替代,而是为我们提供了另一种强大的建模视觉世界的工具。它拓宽了视觉模型的设计思路,让我们看到了超越局部卷积的另一种可能。理解它们内核的差异,能帮助我们在面对具体问题时,做出更明智、更高效的技术决策。未来,我们看到的很可能不是谁取代谁,而是二者思想更深层次的融合,催生出更强大、更高效的视觉基础模型。