ViT 为什么只取第一个位置作为输出:CLS Token 特征聚合完整解析

ViT 为什么只取第一个位置作为输出:CLS Token 特征聚合完整解析

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

在 PyTorch Vision 库里跑 ViT(Vision Transformer)时你会发现一个细节:编码器输出的特征序列很长,但模型只截取第一个位置送入分类头,最终 logits 形状是 [B, 768]。为什么偏偏是"第一个位置"?📌 这篇文章从输出形状出发,把 CLS Token 特征聚合这套设计讲清楚。

从 [B, 768] 说起:输出形状是怎么来的

先看代码。在 torchvision/models/vision_transformer.py 的forward里,有两行非常直白:

x = x[:, 0] # 取序列第一个位置 x = self.heads(x)

此时x的形状是 [B, 197, 768]:197 是序列长度,768 是特征维度。而分类头是一个把 768 维映射到 1000 类的线性层,它只接受"一张图一个向量",无法直接处理 197 个向量。问题于是变成:197 个位置里,哪一个最适合代表整张图?模型设计给出的答案就是第一个位置。

CLS Token:一个刻意插入的"汇总槽位"

CLS(Classification)Token 的思路来自 NLP 领域的 BERT:在序列开头放一个特殊 token,经过多层自注意力(self-attention,即序列中每个元素都能看到其他所有元素并据此更新自己)后,它的最终表示会汇聚全局信息,供分类使用。

PyTorch Vision 的实现同样是"预置槽位 + 靠注意力填充":

batch_class_token = self.class_token.expand(n, -1, -1) x = torch.cat([batch_class_token, x], dim=1)

CLS Token 是一个可学习参数,被拼接到所有 patch 特征之前。关键在于:它刚进场时对图像一无所知,只能通过自注意力"向"196 个 patch 提问。每一层它都在关注全部 patch,层层堆叠后,这个向量的内容就是经过注意力加权蒸馏出的全局摘要。

从图像到序列:CLS Token 走过的完整路径

以 ViT-B/16 为例,图像到序列的变化分四步:

  1. 切 patch 并投影:224×224 的图像被 16×16 的卷积切成 14×14=196 个 patch,每个 patch 经线性投影变成 768 维向量(即 patch embedding);
  2. 加位置编码:编码器为每个 token 加上表示空间位置的向量,让模型能区分 patch 的先后位置;
  3. 多层编码器:自注意力 + MLP 反复交互,所有 token 互相"交流";
  4. 只取第一个位置:输出仍是 197 个 token,但分类只读取 CLS 位置,得到 [B, 768] 的分类特征。

也就是说,197 个 token 并行地"读懂"了图像,而输出时只读出预留的汇总槽位。

CLS Token 与全局平均池化:两种特征聚合的差异

CLS Token 的本质是特征聚合——把 196 个 patch 特征压成一个向量。全局平均池化(GAP)是常见的替代做法,差异如下:

对比维度CLS Token全局平均池化
聚合方式注意力加权,权重由学习决定所有 patch 等权平均
重点区域可动态聚焦关键 patch局部信息被等比例稀释
推理成本读取单向量,几乎无额外开销需对整条序列做一次平均
适用场景分类任务的标准做法也常配合 patch 特征用于密集任务

此外还有多 Token 融合的思路:把 CLS 输出与 GAP 拼接或相加,可能提升鲁棒性,但计算与调参成本更高。

开发者如何选择与修改聚合方式

  • 标准分类任务:直接用 PyTorch Vision 的默认实现,CLS Token 聚合已经被大量预训练权重验证,不需要动;
  • 微调或换分类头:只替换heads即可,"取第一个位置"的逻辑保持不变;
  • 检测、分割等需要局部信息的任务:CLS 位置没有空间含义,应改用 patch 特征序列(即丢弃第 0 位)接入下游模块;
  • 做消融实验:可把x[:, 0]换成x[:, 1:].mean(dim=1)即 GAP,对比两者在自己数据集上的表现,这是很常见的对照实验。

一句话总结:ViT 只取第一个位置,是因为 CLS Token 从输入阶段就被放在那里充当汇总槽位,多层自注意力把所有 patch 的全局信息蒸馏进了这个向量。至于聚合策略,它只是分类头前一个可替换的组件,按任务特点选择即可。

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

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