ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

从NLP到CV:Transformer跨界计算机视觉的核心原理与实战指南

从NLP到CV:Transformer跨界计算机视觉的核心原理与实战指南 1. 从NLP到CVTransformer的跨界之旅如果你在2020年之前问我Transformer是什么我会毫不犹豫地告诉你它是一种在自然语言处理领域大放异彩的模型架构其核心的自注意力机制让机器理解长距离文本依赖关系的能力得到了质的飞跃。但今天当“Transformer”这个词再次被提及时语境已经发生了翻天覆地的变化。它不再仅仅是BERT、GPT这些NLP巨头的专属引擎而是成为了计算机视觉领域一股无法忽视的、甚至可以说是颠覆性的力量。从图像分类到目标检测再到图像生成Transformer架构正在重新定义我们处理视觉信息的方式。这篇指南就是为你拆解这场跨界革命的核心逻辑、关键技术细节以及在实际视觉任务中落地时那些文档里不会写的实战心得。为什么视觉领域需要Transformer传统的卷积神经网络CNN统治了计算机视觉近十年它通过局部感受野和权值共享高效地捕捉图像的局部特征如图像的边缘、纹理。这套范式非常成功ResNet、EfficientNet等经典网络至今仍是许多任务的基石。然而CNN也存在其固有的局限性卷积核的局部性决定了它难以直接建模图像中远距离像素间的全局依赖关系。虽然可以通过堆叠更深的层或使用更大的卷积核来扩大感受野但这在计算效率和模型表达能力上并非最优解。而视觉任务中这种全局关系恰恰至关重要——识别一只猫需要同时看到它的耳朵、胡须和尾巴理解一张街景图片需要将分散的行人、车辆、交通标志关联起来。Transformer的自注意力机制天生就是为了建模这种全局依赖而生的。它允许序列中的任何一个元素在视觉任务中就是图像的一个个“块”或“像素”直接与序列中的所有其他元素进行交互计算它们之间的相关性权重。这种“全局视野”是CNN通过层层卷积间接获得的而Transformer可以更直接、更灵活地实现。正是这一根本优势催生了Vision Transformer等一系列模型的诞生开启了视觉Transformer的时代。接下来我们将深入这个新时代的核心。2. Vision Transformer如何将图像“喂”给Transformer将原本为序列设计的Transformer应用于图像第一个要解决的、也是最关键的问题就是如何把二维的图像数据转换成Transformer能理解的序列Vision Transformer的解决方案既巧妙又直接可以概括为“分块、展平、嵌入”三步。2.1 图像分块与线性投影假设我们有一张分辨率是 H x W 像素通道数为 C 的输入图像。ViT的做法是将这张图像均匀地分割成 N 个固定大小的图像块。每个图像块的大小为 P x P 像素。那么图像块的总数 N 就等于 (H / P) * (W / P)。例如一张224x224的图片如果使用16x16的分块大小那么就会得到 (224/16) * (224/16) 14 * 14 196 个图像块。每个图像块本身是一个三维张量形状为 (P, P, C)。ViT接下来将这个三维块沿着空间维度展平变成一个长度为 (P * P * C) 的一维向量。对于16x16的块和3通道的RGB图像这个向量的长度就是 16163 768。现在我们有了196个长度为768的向量。但这只是原始的像素值还需要将它们映射到Transformer模型隐藏层的大小 D 上。这一步通过一个可训练的线性投影层一个全连接层来完成。这个投影层通常也被称为“Patch Embedding”层。经过投影后我们得到了一个形状为 (N, D) 的序列其中 N 是图像块的数量D 是模型的隐藏维度例如768。至此二维图像被成功地转换成了一个长度为 N 的序列序列中的每个元素都是一个 D 维的向量代表了一个图像块的抽象特征。注意分块大小 P 是一个超参数需要在模型容量和计算效率之间权衡。更小的 P如8或14会产生更多的图像块N更大序列更长模型能捕捉更细粒度的信息但计算自注意力的成本会以 O(N²) 的复杂度急剧上升。更大的 P如32则相反。ViT-Base/16Patch Size16是一个常用的平衡点。2.2 可学习的分类令牌与位置编码在NLP的BERT中有一个特殊的[CLS]令牌用于汇聚整个句子的信息以进行分类。ViT借鉴了这一思想在输入序列的开头额外添加了一个可学习的嵌入向量称为“分类令牌”。这个令牌本身不来自任何图像块它是一个模型需要学习的参数形状为 (1, D)。我们将它拼接到图像块序列之前于是输入序列的形状变成了 (N1, D)。为什么需要这个额外的令牌因为Transformer的输出是对应于每个输入位置的向量。对于分类任务我们需要一个单一的、能够代表整张图片的向量。让模型自己学习一个专门的令牌来聚合全局信息比从所有图像块输出中做平均池化或选择某一个在理论上更灵活实践中也通常更有效。另一个至关重要的组件是位置编码。自注意力机制本身是排列不变的它处理序列[A, B, C]和[C, B, A]在理论上没有区别。但对于图像而言像素或图像块的空间位置信息是至关重要的。左上角的一块天空和右下角的一块天空含义可能完全不同。因此我们必须向模型注入位置信息。ViT采用的方式是标准的、可学习的一维位置编码。我们创建一个形状为 (N1, D) 的可学习参数矩阵其中每一行对应一个位置包括分类令牌的位置。在输入Transformer编码器之前我们将这个位置编码矩阵直接加到图像块嵌入含分类令牌矩阵上输入 嵌入 位置编码。这样模型就能在学习过程中区分不同位置的图像块了。实操心得关于位置编码后来的一些研究如Swin Transformer表明对于视觉任务相对位置编码或二维感知的位置编码可能比绝对一维位置编码更合适因为图像的本质是二维的。但在标准的ViT中可学习的一维绝对位置编码已经能取得非常好的效果且实现简单。在实际复现时务必确保位置编码只加一次并且在推理时如果输入图像大小与训练时不同导致N变化需要如何处理位置编码是一个需要小心处理的问题通常需要对预训练的位置编码进行插值。3. Transformer编码器在视觉中的核心自注意力与MLP经过嵌入和位置编码后得到的 (N1, D) 序列就被送入由 L 个完全相同的层堆叠而成的Transformer编码器。每一层都包含两个核心子层多头自注意力层和前馈网络层每个子层前后都应用了残差连接和层归一化。3.1 多头自注意力机制详解自注意力是Transformer的灵魂。对于视觉任务它的工作方式如下生成Q, K, V对于输入序列 X形状 (N1, D)我们通过三个不同的线性变换矩阵 W_q, W_k, W_v形状均为 (D, D_k)其中 D_k 是每个头的维度将其分别投影为查询、键和值向量Q XW_q, K XW_k, V XW_v。这里D_k 通常设置为 D / hh 是注意力头的数量。计算注意力分数注意力分数的核心是衡量序列中每个元素查询与所有元素键的相关性。计算公式为注意力分数 softmax( (Q * K^T) / sqrt(D_k) )。这里Q * K^T 得到一个 (N1, N1) 的矩阵其中第 i 行第 j 列的值就代表了第 i 个位置对第 j 个位置的“关注程度”。除以 sqrt(D_k) 是为了防止点积结果过大导致softmax梯度消失。加权求和将上一步得到的注意力权重矩阵与值矩阵 V 相乘输出 注意力分数 * V。这就意味着每个位置的输出都是所有位置值的加权和权重由该位置与其它位置的相关性决定。“多头”的意义在于模型可以并行地学习多种不同的关注模式。例如一个头可能专注于捕捉颜色相似性另一个头专注于纹理连续性第三个头可能关注空间相邻关系。最后将所有头的输出拼接起来再经过一个线性投影得到最终的自注意力层输出。在视觉中这意味着一个图像块可以同时关注到颜色相近的块、纹理连续的块以及空间上可能很远但语义相关的块如猫的头部和尾巴。这种能力是CNN通过多层卷积才能间接、隐式地学习到的。3.2 前馈网络与层设计自注意力层的输出会经过一个前馈网络。这个FFN通常是一个简单的两层MLP中间有一个非线性激活函数如GELUFFN(x) GELU(xW1 b1)W2 b2。它的作用是对每个位置的特征进行独立的、非线性的变换和增强。残差连接和层归一化是稳定深层模型训练的关键。每个子层MSA和FFN的输出都是LayerNorm(子层输入 子层函数(子层输入))。这种设计极大地缓解了梯度消失问题使得堆叠数十甚至上百层Transformer成为可能。经过 L 层这样的处理序列中的每个令牌都融合了全局信息。最终我们取分类令牌对应的输出向量即序列的第一个位置通过一个小的分类头通常是单个线性层映射到目标类别数用于图像分类任务。踩坑实录训练视觉Transformer尤其是大型ViT对优化器和超参数非常敏感。AdamW优化器几乎是标配并且需要一个精心设计的学习率warmup和cosine衰减策略。直接使用训练CNN的套路如SGD with momentum往往难以收敛或效果很差。这是因为Transformer的初始化方式和训练动态与CNN不同。一个常见的技巧是使用梯度裁剪来防止训练初期的不稳定。4. 超越ViT视觉Transformer的演进与变体标准的ViT证明了Transformer在视觉上的可行性但它也有明显的缺点计算复杂度高O(N²)且缺乏像CNN那样的层次化归纳偏置即局部性、平移不变性。后续的研究主要围绕这两个方向展开。4.1 层次化架构Swin TransformerSwin Transformer的提出是视觉Transformer发展中的一个里程碑。它引入了两个关键思想层级特征图和滑动窗口注意力。层级特征图Swin Transformer像CNN一样构建了特征金字塔。它通过“Patch Merging”操作在多个阶段逐渐合并相邻的图像块从而在深层减少序列长度、增加每个令牌的感受野和特征维度。这产生了类似于CNN中“高分辨率-低语义”到“低分辨率-高语义”的特征图非常适合于需要多尺度特征的任务如目标检测和语义分割。滑动窗口注意力为了降低全局自注意力的计算复杂度Swin Transformer将注意力计算限制在不重叠的局部窗口内。例如将特征图划分为多个7x7的窗口只在每个窗口内部计算自注意力。这样计算复杂度就从与图像块数量的平方相关变为与窗口大小固定的平方相关是线性的复杂度。但仅仅这样会失去窗口间的信息交互。因此Swin Transformer采用了移位窗口机制。在下一层窗口的划分网格会进行偏移例如向右下角偏移半个窗口使得新的窗口能够覆盖上一层中不同窗口的部分从而实现了跨窗口的信息传递。这种设计在效率和建模能力之间取得了极佳的平衡。4.2 高效注意力机制探索除了滑动窗口还有许多其他工作致力于降低自注意力的计算负担轴向注意力将二维的全局注意力分解为两个一维操作先在行方向做注意力再在列方向做注意力。复杂度从O(N²)降为O(N√N)。稀疏注意力只让每个位置关注特定的、预先定义好的一组位置如局部邻域、随机位置、或按步长采样的位置。线性注意力通过核函数近似将softmax注意力中的QK^T计算顺序改写实现理论上的线性复杂度。蒸馏令牌在DeiT模型中除了分类令牌还引入了一个“蒸馏令牌”它通过与一个CNN教师模型的输出进行交互从教师那里学习知识从而让ViT能在相对较小的数据集如ImageNet-1K上有效训练而无需依赖超大规模数据集。这些变体各有优劣选择哪一种取决于具体的任务、对精度的要求以及对计算资源的限制。Swin Transformer因其在通用视觉任务上的优异表现和良好的效率成为了目前应用最广泛的视觉Transformer架构之一。5. 实战在自定义数据集上微调Vision Transformer理解了原理我们来看看如何动手实践。这里以使用Hugging Facetransformers库在自定义图像分类数据集上微调一个预训练的ViT模型为例。5.1 环境准备与数据预处理首先确保安装必要的库pip install transformers datasets torch torchvision pillow假设你的自定义数据集是一个文件夹结构如下所示my_dataset/ ├── train/ │ ├── class_0/ │ │ ├── img1.jpg │ │ └── ... │ ├── class_1/ │ └── ... └── val/ ├── class_0/ ├── class_1/ └── ...我们需要使用torchvision和transformers的处理器来准备数据。ViT模型有特定的图像预处理要求如分辨率调整、归一化等。from transformers import ViTImageProcessor from torchvision import transforms from datasets import load_dataset import torch # 加载预训练模型对应的处理器 # 以 google/vit-base-patch16-224-in21k 为例 model_name google/vit-base-patch16-224-in21k processor ViTImageProcessor.from_pretrained(model_name) # 定义转换函数 def transform(examples): # 假设数据集的图像列名为 image images examples[image] # 使用处理器进行标准化预处理 inputs processor(imagesimages, return_tensorspt) # 添加标签 inputs[labels] examples[label] return inputs # 使用 datasets 库加载自定义数据 # 这里需要你先将文件夹数据集转换为 datasets.Dataset 格式 # 可以使用 ImageFolder 方式或自定义脚本 dataset load_dataset(imagefolder, data_dir./my_dataset) # 应用预处理 processed_dataset dataset.with_transform(transform)5.2 模型加载与微调配置接下来加载预训练模型并修改其分类头以适应你的类别数。from transformers import ViTForImageClassification # 获取数据集的类别数 num_labels len(processed_dataset[train].features[label].names) # 加载模型并指定新的类别数 model ViTForImageClassification.from_pretrained( model_name, num_labelsnum_labels, # 关键覆盖预训练模型的分类头 ignore_mismatched_sizesTrue # 忽略分类头大小不匹配的警告 ) # 配置训练参数 from transformers import TrainingArguments, Trainer training_args TrainingArguments( output_dir./vit-finetuned, per_device_train_batch_size16, per_device_eval_batch_size16, evaluation_strategyepoch, save_strategyepoch, num_train_epochs10, fp16True, # 如果GPU支持混合精度训练可以加速 logging_dir./logs, logging_steps10, learning_rate2e-5, # 微调学习率通常较小 weight_decay0.01, load_best_model_at_endTrue, metric_for_best_modelaccuracy, )5.3 训练循环与评估定义评估指标并创建Trainer开始训练。import numpy as np from datasets import load_metric metric load_metric(accuracy) def compute_metrics(eval_pred): logits, labels eval_pred predictions np.argmax(logits, axis-1) return metric.compute(predictionspredictions, referenceslabels) trainer Trainer( modelmodel, argstraining_args, train_datasetprocessed_dataset[train], eval_datasetprocessed_dataset[validation], compute_metricscompute_metrics, ) trainer.train()训练完成后你可以保存模型并进行推理。# 保存模型 trainer.save_model(./my_finetuned_vit) processor.save_pretrained(./my_finetuned_vit) # 推理示例 from PIL import Image image Image.open(path_to_test_image.jpg).convert(RGB) inputs processor(imagesimage, return_tensorspt) with torch.no_grad(): logits model(**inputs).logits predicted_label logits.argmax(-1).item() label_name processed_dataset[train].features[label].names[predicted_label] print(fPredicted class: {label_name})重要提示视觉Transformer尤其是像ViT这样的模型对数据增强非常敏感。在微调时强烈建议使用比CNN更激进的数据增强策略如RandAugment、MixUp、CutMix等。这能有效防止模型在小数据集上过拟合并提升泛化能力。transformers的ViTImageProcessor通常只包含基础的归一化和缩放你可能需要在数据加载管道中额外添加这些增强。6. 视觉Transformer的适用场景与当前局限视觉Transformer并非万能理解其优势和局限有助于你在项目中做出正确的技术选型。优势场景数据充足的任务当拥有海量数据如JFT-300M时ViT能展现出超越CNN的潜力因为它能从数据中学习到更强大的、不受局部性先验限制的特征表示。需要长距离依赖建模的任务例如图像生成如Diffusion模型大量使用Transformer、全景分割、视频理解时空注意力等其中全局上下文至关重要。多模态任务Transformer是统一多种模态图像、文本、音频的天然架构。像CLIP、DALL-E等模型其核心就是Transformer它能无缝处理来自不同模态的嵌入序列。当前局限与挑战计算与内存开销尽管有Swin等优化大型视觉Transformer的推理速度和在边缘设备上的部署难度仍然高于经过高度优化的轻量级CNN如MobileNet、EfficientNet-Lite。小样本学习在数据量有限的情况下缺乏CNN固有的归纳偏置局部性、平移等变性可能是一个劣势导致模型更容易过拟合需要更强的数据增强和正则化。对空间细节的敏感性将图像分割成块可能会破坏最细粒度的空间信息。对于需要像素级精度的任务如超分辨率、图像修复纯Transformer架构有时需要与CNN或其他结构结合。解释性虽然注意力图可以可视化模型关注了图像的哪些区域但其解释性仍然比CNN的滤波器可视化更抽象和难以理解。在实际项目中我的经验是“混合使用各取所长”。对于需要快速部署、对计算资源敏感的应用轻量级CNN仍是首选。对于追求极致精度、且有充足算力和数据的研发项目或者涉及多模态、长序列理解的任务视觉Transformer是必须深入探索的方向。而像ConvNeXt这样的模型则展示了将Transformer的设计理念如更大的感受野、更少的激活函数重新注入CNN后也能取得惊人效果这提示我们未来的架构很可能是融合了双方优点的混合体。
返回列表