YAOTU INSIGHTS

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

ViT 为什么只取第一个位置作为输出:CLS Token 特征聚合完整解析
ViT 为什么只取第一个位置作为输出CLS Token 特征聚合完整解析【免费下载链接】visionDatasets, Transforms and Models specific to Computer Vision项目地址: https://gitcode.com/gh_mirrors/vi/vision在 PyTorch Vision 库里跑 ViTVision 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一个刻意插入的汇总槽位CLSClassificationToken 的思路来自 NLP 领域的 BERT在序列开头放一个特殊 token经过多层自注意力self-attention即序列中每个元素都能看到其他所有元素并据此更新自己后它的最终表示会汇聚全局信息供分类使用。PyTorch Vision 的实现同样是预置槽位 靠注意力填充batch_class_token self.class_token.expand(n, -1, -1) x torch.cat([batch_class_token, x], dim1)CLS Token 是一个可学习参数被拼接到所有 patch 特征之前。关键在于它刚进场时对图像一无所知只能通过自注意力向196 个 patch 提问。每一层它都在关注全部 patch层层堆叠后这个向量的内容就是经过注意力加权蒸馏出的全局摘要。从图像到序列CLS Token 走过的完整路径以 ViT-B/16 为例图像到序列的变化分四步切 patch 并投影224×224 的图像被 16×16 的卷积切成 14×14196 个 patch每个 patch 经线性投影变成 768 维向量即 patch embedding加位置编码编码器为每个 token 加上表示空间位置的向量让模型能区分 patch 的先后位置多层编码器自注意力 MLP 反复交互所有 token 互相交流只取第一个位置输出仍是 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(dim1)即 GAP对比两者在自己数据集上的表现这是很常见的对照实验。一句话总结ViT 只取第一个位置是因为 CLS Token 从输入阶段就被放在那里充当汇总槽位多层自注意力把所有 patch 的全局信息蒸馏进了这个向量。至于聚合策略它只是分类头前一个可替换的组件按任务特点选择即可。【免费下载链接】visionDatasets, Transforms and Models specific to Computer Vision项目地址: https://gitcode.com/gh_mirrors/vi/vision创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考