本文涉及到的详细测试代码和测试步骤放置于:
https://github.com/xinyuwei-david/david-share.git下的:Multimodal-Models/
Train ViT and Run Qianwen-VL
,本文中不再赘述代码实现。
欢迎给repo点亮Star,您的点赞是作者持续创作的动力。
一、侦探与艺术家
想象一下你在试图理解一幅复杂的画作。你可以逐一检查每一笔刷痕迹,费力地拼凑细节。或者,你可以退后一步,看到整体构图,领会艺术家的意图。这就是传统计算机视觉模型与革命性Vision Transformer (ViT)之间的区别。
多年来,Convolutional Neural Networks (CNNs)一直是分析图像的首选方法。CNNs将图像分解成小的局部片段,并在这些片段中学习模式,就像侦探分析单个线索一样。它们擅长识别简单的形状和模式,但在理解整个图像的复杂关系时却显得力不从心。
而ViTs则像艺术评论家一样,看到大局。它们不仅仅关注单个笔触,而是看到整个构图、颜色、形状以及元素之间的相互作用。这种“大局”理解来自一种强大的机制,称为self-attention。通过self-attention,图像的每个部分都可以与其他部分“对话”,瞬间理解其与整体的关系。
ViTs将图像视为“词”的集合——不是单个像素,而是有意义的块,就像画作中的不同元素。这些块被称为patches。self-attention的魔力让模型理解这些patches之间的关系,就像艺术评论家理解画作中不同元素之间的关系一样。这使得ViTs在识别复杂图像时能够取得显著的准确性,甚至在某些情况下超过CNNs。
二、Vision Transformer的结构:分解图像
想象一个艺术评论家在欣赏一幅杰作。他们不仅仅盯着画布,而是首先将其分解为不同的元素——人物、风景、中心焦点。Vision Transformers (ViTs)对图像做同样的事情,但不是依赖人类判断,而是依靠系统的patching过程。
把图像想象成一个大型拼图。ViTs首先将图像划分为一个个小的矩形块,就像单个拼图块。这些块就是patches。patch的大小由一个称为“patch size”的参数决定,决定了每个块捕捉的细节量。较大的patch size意味着更多的细节,但整体块数更少,就像一个较少但更大的拼图。
一旦图像被分割成patches,真正的魔法就开始了——这些patches被嵌入到向量中。这个过程将每个patch,即视觉信息块,转换为数学表示,即一系列数字。我们可以将其视为将图像翻译成模型可以理解的语言。
但这些嵌入的patches只是没有上下文的“词”。就像句子需要顺序才能有意义,我们需要保留图像中的空间信息。这就是positional encoding的作用。想象每个patch在图像网格上有一个唯一的地址。positional encoding为每个patch添加一个数字“地址”,使模型能够理解其相对于其他patch的位置。
现在,我们有了一系列带有空间地址的“词”。这个序列被输入到ViT模型的核心——Transformer encoder。Transformer encoder是一个受语言模型启发的强大神经网络,由multi-head attention和Multi-Layer Perceptrons (MLPs)交替层组成,每层都有layer normalization和residual connections。
但还有一个关键成分。一个特殊的“classification token”被添加到patch序列的开头。可以将其视为最终答案的占位符。这个标记从整个patch序列中收集信息,成为整个图像的表示,概括重要特征和关系。然后,classification token通过最后一层,模型最终做出预测,无论是类别标签、对象检测还是其他任务。
这就是Vision Transformer的本质——一个将图像分解为有意义的patches,利用self-attention理解其关系,并最终理解整个图像的模型。现在,让我们更深入地探讨这一非凡架构的数学基础。
我们看一下ViT的架构图
在上面这张图中,ViT处理步骤如下:
图像分割:图像被分成多个小块(patches)。
线性投影:每个小块被转换成一个向量(数字表示)。
位置嵌入:给每个向量加上位置信息,形成最终的嵌入向量。这帮助模型知道每个小块在图像中的位置。
[class]嵌入:添加一个特殊的[class]嵌入,用于表示整个图像的类别信息。
输入Transformer:这些嵌入向量(包括[class]嵌入)被送入Transformer编码器。编码器通过self-attention机制理解小块之间的关系。
MLP Head:编码器的输出被传递到一个多层感知器(MLP)头部,用于进一步处理。
分类输出:最终,模型在[class]嵌入上输出一个类别标签,比如识别出图像中的物体是鸟、球还是车。
这样,ViT通过分析小块和[class]嵌入来理解和分类整个图像。
三、ViTs与CNNs:性能对比
让我们回顾一下ViTs的独特之处。CNNs像侦探,专注于局部细节,仔细检查每个像素及其周围环境,擅长识别简单的模式和形状。
而ViTs则像艺术评论家,关注整体图像,理解元素之间的关系,并解读艺术家的意图。它们擅长捕捉图像中复杂的关系和依赖性。
这种基本的处理方式差异对性能有显著影响。
准确性:在许多情况下,ViTs比CNNs达到更高的准确性,尤其是在需要理解复杂关系或识别细微特征的任务中。
可扩展性:ViTs表现出更快的神经扩展规律。这意味着随着模型规模的增加,它们变得更准确,而CNNs的性能往往趋于平稳。
研究表明,ViTs在图像识别基准测试中通常达到最先进的准确性,尤其是在大数据集上训练时。这是因为它们能够捕捉到更大、更多样化数据集中存在的复杂模式和微妙关系,而CNNs难以处理这些。
然而,ViTs也有一些限制。
数据需求:ViTs通常需要比CNNs更大的数据集才能发挥其全部潜力,因为其数据驱动的方法需要更多的例子来学习复杂模式。
计算成本:对于较小的模型,ViTs可能比CNNs在计算上更昂贵,尤其是在推理时,因为其全局注意力机制需要更多的计算。
那么,什么时候应该使用ViTs,什么时候应该坚持使用CNNs呢?
大数据集:如果你有大量的训练数据并需要达到高准确性,ViTs是一个强大的选择。
复杂关系:对于需要理解整个图像中复杂关系的任务,ViTs是更好的选择。
可扩展性:如果你需要一个扩展性好的模型,即随着其规模的增加性能显著提高,ViTs是最佳选择。
然而,如果你有一个有限的数据集,需要一个用于实时应用的快速模型,或者处理较简单的任务,CNNs可能仍然是更合适的选择。
图像识别的未来:
图像识别的未来可能是CNNs和ViTs的结合。研究人员不断探索融合两者优势的方法,开发出利用两者优点的混合模型。
这段旅程为我们打开了视觉Transformer的世界。我们探索了它们的数学基础,使用Python构建了一个简化模型,并了解了它们独特的优势和局限性。ViTs在图像识别中是一个革命性的进步,推动了人工智能可以实现的边界。
四、代码展现
我写了一段代码,模拟ViT拆图和向量化,并且做推理的步骤。完整代码放在了github上。
我们看看效果:
以下是对每个形状的详细解释:
Positional Encoding Shape:
[1, 196, 64]
解释:输入图像被分成了196个patch(每个patch是16x16像素),每个patch被嵌入到一个64维的向量中。
符合设计:因为图像大小是224x224,patch大小是16x16,所以有
(224/16) * (224/16) = 196
个patch。每个patch被映射到64维的嵌入空间。
Attention Output Shape: [1, 196, 64]
解释:经过多头注意力机制后,每个patch的嵌入向量仍然是64维。
符合设计:注意力机制在不改变嵌入维度的情况下,重新计算每个patch的表示。
MLP Output Shape: [1, 196, 64]
解释:经过多层感知机(MLP)后,每个patch的嵌入向量仍然是64维。
符合设计:MLP通常用于对每个patch的表示进行非线性变换,但不改变其维度。
Final Embedding Shape: [1, 64]
解释:所有patch的嵌入向量被平均化,得到一个64维的图像表示。
符合设计:通过对所有patch的表示取平均值,得到整个图像的全局表示。
总结
这些形状表明数据在模型的每一层中都按照预期的方式进行处理,确保了模型的正常运行。每一步都保持了设计的嵌入维度和patch数量。
新书已经上市,欢迎关注:
参考:
https://medium.com/@cristianleo120/the-math-behind-vision-transformers-95a64a6f0c1a