Vision Transformer (ViT):图像分块、图像块嵌入、类别标记、QKV矩阵与自注意力机制的解析

作者:CSDN @ _养乐多_

本文将介绍Vision Transformers (ViT)中的关键点。包括图像分块(Image Patching)、图像块嵌入(Patch Embedding)、类别标记、(class_token)、QKV矩阵计算过程、余弦相似度(cosine similarity)、Softmax、自注意力机制等概念。主要介绍QKV矩阵计算过程。


文章目录


一、Image Patching

图像被分成小的块的过程是 “Image Patching”(图像分块)或者简称 “Patching”。在这个过程中,图像被划分成一系列大小相同或不同的小块,这些小块通常被称为 “Image Patches”(图像块)或简称 “Patches”。

图像分块(Image Patching)过程如图所示,

在这里插入图片描述

“Patch” 是指图像中的一个小块区域或片段。这个概念通常用于将大尺寸的图像分解成更小的部分,以便对每个小块进行单独处理、分析或特征提取。

将图像分成小块(即 Patch)可以带来的优势:

  • 特征提取:在一些任务中,特定区域的信息比整个图像更有用。通过对每个 Patch 进行特征提取,可以获得更细粒度的信息,有助于更好地理解图像内容。

  • 处理大尺寸图像:对于非常大的图像,可能会遇到计算和存储方面的限制。将图像分成小的 Patch 可以帮助降低计算复杂度,并且可以更轻松地处理这些小尺寸的块。

  • 自适应性:在一些自适应处理的算法中,对于不同的图像区域采取不同的策略是很常见的。将图像划分成 Patch 可以使算法在局部区域上更加灵活和自适应。

二、Patch Embedding

“Patch Embedding” 是一个计算机视觉领域的概念,它与图像处理和深度学习中的卷积神经网络(Convolutional Neural Networks,CNN)相关。

传统的卷积神经网络在图像处理时使用的是像素级的操作,通过卷积核在图像上滑动进行特征提取。而在"Patch Embedding"中,这个概念引入了更高级的特征表示方式。它将输入的图像分成小的块(也称为“patch”),然后将每个小块转换为低维的向量表示。这种向量表示可以被用作后续任务的输入。

Patch Embedding的目的在于降低计算复杂度并提高特征提取的效率。由于在传统的卷积操作中,相邻的像素通常会有大量重叠,而Patch Embedding将图像分成块后,可以减少冗余计算,同时保留了重要的特征信息。

在这里插入图片描述

三、Class token

“Class token” 是一个特殊的令牌,用于表示整个图像的类别信息。通常,它会被添加到 Patch Embedding 后得到的向量序列中的某个位置,使得模型能够利用这个类别信息进行分类或生成任务。

3.1 Add Class token

在Transformer模型中,“Class token” 通常被添加在输入序列的开头,并且在训练过程中会经过特定的注意力机制,以使得模型能够对类别信息进行编码和利用。

在 Patch Embedding 操作之后,“Class token” 被添加到 Patch Embedding 向量序列的开头,用于表示整个图像的类别信息,以辅助后续的图像分类或生成任务。

在这里插入图片描述

下面举例说明Class token,假设此次应用是为了分类图像是不是石原里美。我们使用 one-hot 编码的方式表示类别信息。那么类别信息就有两种,是和不是,现在用向量 [1, 0] 表示是,[0, 1] 表示不是。那么class_token就是 [1, 0] 或者 [0, 1]

现在,我们将这个 “Class token” 与每个小块的 Patch Embedding 向量连接在一起,得到最终的输入序列。假设得到的 196 个 Patch Embedding 向量分别为:

[v1, v2, v3, ..., v196]

那么,添加 “Class token” 后的最终输入序列为:

[Class_token, v1, v2, v3, ..., v196]

这样,整个输入序列中的第一个向量就是 “Class token”,它包含了整个图像的类别信息,即图像属于是不是石原里美。模型在训练过程中可以利用这个类别信息,帮助进行图像分类任务。

往细一点讲,假设 v1 是一个 2 维向量,表示为:

v1 = [0.2, 0.7]

这个向量表示第一个小块的特征。现在,我们将 “Class token” 和 v1 连接在一起,得到最终的输入序列:

[Class_token, v1]

假设 “Class token” 表示图像属于石原里美的类别,它的 one-hot 编码为:

[1, 0]

那么最终的输入序列是:

[[1, 0], [0.2, 0.7]]

这个输入序列包含了整个图像的类别信息(属于石原里美的概率为 1,不是石原里美的概率为 0)以及第一个小块的特征向量 [0.2, 0.7]

3.2 Positional Encoding

在了解了class token 以后,我们来看看 vit 中的 class token 。

在 Vision Transformer (ViT) 模型中,“PE” 表示位置编码(Positional Encoding),用于将图像中的每个 Patch Embedding 向量与其位置信息相关联,用于将整个图像的全局位置信息引入到 Transformer 模型中。

位置编码是为了给 Transformer 模型提供输入序列中的位置信息,因为 Transformer 模型没有像卷积神经网络那样显式地保留位置信息。在自然语言处理任务中,输入是一个词语序列,为了保留词语的位置信息,通常会添加位置编码。类似地,在 ViT 中,输入是图像的 Patch Embedding 序列,为了保留 Patch 的位置信息,也需要添加位置编码。

在 ViT 中,PE(pos, 2i) 和 PE(pos, 2i + 1) 是用来计算 “Class token” 的位置编码公式。位置编码使用的是 sin 和 cos 函数来计算。对于 “Class token” 的位置编码,计算方式为:

P E ( p o s , 2 i ) = s i n ( p o s / 1000 0 2 i / d m o d e l ) PE(pos, 2i) = sin(pos / 10000^{2i / dmodel}) PE(pos,2i)=sin(pos/100002i/dmodel)
P E ( p o s , 2 i + 1 ) = c o s ( p o s / 1000 0 2 i / d m o d e l ) PE(pos, 2i + 1) = cos(pos / 10000^{2i / dmodel}) PE(pos,2i+1)=cos(pos/100002i/dmodel)

位置编码采用了正弦和余弦函数的形式,其中 PE(pos, 2i) 是对应维度为偶数的位置编码,PE(pos, 2i + 1) 是对应维度为奇数的位置编码。在计算时,pos 表示 Patch 在序列中的位置,i 是位置编码的维度索引,从 0 开始,dmodel 是 Transformer 模型中的隐藏层维度(也称为特征维度)。

这种位置编码的计算方式在 Transformer 中是常见的,它使得不同位置的 Patch Embedding 向量在特征空间上具有不同的位置偏移,以便于模型在处理序列数据时考虑到它们的相对位置关系。


为了更好地说明位置编码的计算过程,我们来举一个简化的例子。假设我们有一个图像,将其分成 4x4 个小块(Patch),共计 16 个小块,每个小块用一个 2 维向量表示。我们假设隐藏层大小(d_model)为 4。

现在,我们来计算 “Class token” 和每个小块的位置编码。

首先,“Class token” 的位置为整个图像,我们可以选择一个虚拟的位置编号 pos = 0 来表示 “Class token” 的位置。然后,我们计算 “Class token” 的位置编码:

d_model = 4
i = 0PE(pos=0, 2i) = sin(0 / 10000^(2*0 / 4)) = sin(0) = 0
PE(pos=0, 2i + 1) = cos(0 / 10000^(2*0 / 4)) = cos(0) = 1

所以 “Class token” 的位置编码为 [0, 1]。

接下来,我们计算每个小块的位置编码。假设小块的位置编号从 1 到 16。我们可以使用以下公式来计算每个小块的位置编码:

d_model = 4
i = 0, 1, 2, 3pos = 1
PE(pos=1, 2*0) = sin(1 / 10000^(2*0 / 4)) = sin(1)0.8415
PE(pos=1, 2*0 + 1) = cos(1 / 10000^(2*0 / 4)) = cos(1)0.5403pos = 2
PE(pos=2, 2*0) = sin(2 / 10000^(2*0 / 4)) = sin(2)0.9093
PE(pos=2, 2*0 + 1) = cos(2 / 10000^(2*0 / 4)) = cos(2)-0.4161


依此类推,计算每个小块的位置编码。最终得到每个小块的位置编码的结果。

请注意,这只是一个简化的例子,并且隐藏层大小(d_model)和小块的位置编号可能会根据实际情况有所不同。实际中,ViT 模型使用更高维度的隐藏层,并且位置编号会更加复杂。这里的目的是为了演示位置编码的计算过程。

四、QKV

在这里插入图片描述

如上图所示,QKV 矩阵是在自注意力机制(Self-Attention Mechanism)中用于计算注意力权重的三个矩阵。这三个矩阵通常是通过对输入序列进行线性变换得到的。它们分别是:

  • Q矩阵(Query Matrix):Q矩阵用于生成查询向量,每个查询向量代表一个小块(Patch)在注意力机制中的查询,即用于寻找与当前小块相关的信息。

  • K矩阵(Key Matrix):K矩阵用于生成键向量,每个键向量代表一个小块(Patch)在注意力机制中的键,即用于表示当前小块与其他小块之间的关系。

  • V矩阵(Value Matrix):V矩阵用于生成值向量,每个值向量代表一个小块(Patch)在注意力机制中的值,即用于表示当前小块的特征信息。

首先需要知道的是X矩阵和Y矩阵的维度大小是一样的,输入维度和输入维度一样。

具体来说,在自注意力机制中,输入序列首先通过三个不同的线性变换,分别得到查询矩阵 Q、键矩阵 K 和值矩阵 V。 这三个矩阵将用于计算注意力权重,从而对输入序列进行加权求和,得到最终的表示。

其中,Q和K的点乘得到的矩阵就是注意力权重矩阵A。假设如果只有V矩阵,不经过Q和K的过程,那么这就算是普通的网络,没有加入注意力机制。

假设不管你用什么线性变换方法,也不过你线性变换用了多少隐藏层(这部分自行百度),现在我们得到了QKV矩阵,并且添加了 class token。如下图所示,

在这里插入图片描述

当然我们计算的时候,QKV都是被拉伸成了一行,为了方便表示,这里画的还是矩形形式。

4.1 cosine similarity

在了解Q和K点乘之前,需要理解余弦相似度的概念。因为Q和K的点乘就是在比较其余弦相似度大小,如果Q中第一个patch和K中所有patch相比较,进行点乘,那么他们的余弦相似度会被计算。

余弦相似度越大,自注意力权重越大。

下面是余弦相似度的概念和计算方式,

余弦相似度是一种用于衡量两个向量之间相似性的度量方法,常用于计算两个向量的方向是否相似。在余弦相似度中,向量的长度并不影响相似度的计算,因此它更关注向量的方向。

假设有两个向量 A 和 B,它们可以表示为:

A = [ a 1 , a 2 , a 3 , . . . , a n ] A = [a₁, a₂, a₃, ..., aₙ] A=[a1,a2,a3,...,an]
B = [ b 1 , b 2 , b 3 , . . . , b n ] B = [b₁, b₂, b₃, ..., bₙ] B=[b1,b2,b3,...,bn]

其中 a₁、a₂、…、aₙ 和 b₁、b₂、…、bₙ 分别是两个向量的元素。

余弦相似度的计算公式如下:

c o s i n e _ s i m i l a r i t y = ( A ⋅ B ) / ( ∣ ∣ A ∣ ∣ ∗ ∣ ∣ B ∣ ∣ ) cosine\_similarity = (A·B) / (||A|| * ||B||) cosine_similarity=(AB)/(∣∣A∣∣∣∣B∣∣)

其中,

  • A·B 表示向量 A 和向量 B 的点积(内积),即 a₁ * b₁ + a₂ * b₂ + … + aₙ * bₙ。
  • ||A|| 表示向量 A 的范数(或长度),即 √(a₁² + a₂² + … + aₙ²)。
  • ||B|| 表示向量 B 的范数,即 √(b₁² + b₂² + … + bₙ²)。

计算余弦相似度时,首先计算向量 A 和向量 B 的点积,然后分别计算它们的范数。最后将点积除以两个向量的范数的乘积,得到余弦相似度值。余弦相似度的取值范围在 -1 到 1 之间,

  • 当余弦相似度为 1 时,表示两个向量的方向完全相同,即它们在空间中指向相同的方向。
  • 当余弦相似度为 -1 时,表示两个向量的方向完全相反,即它们在空间中指向相反的方向。
  • 当余弦相似度为 0 时,表示两个向量的方向垂直,即它们在空间中互相垂直。

4.2 Q @ K T K^{T} KT

下面我们来看一看 Q 和 K 计算权重矩阵A的过程,如图红框中的过程,

在这里插入图片描述

在这里插入图片描述

如上图所示,假设黄色矩形表示Q矩阵中的元素,蓝色矩形表示 K T K^{T} KT矩阵中的元素,绿色矩形表示Q点乘K之后的结果矩阵中的元素。其中,q0表示一行,k0表示一列,q0k0表示黄色的一行和蓝色的一列点乘得到的一个数。

这里的 q0 就是 class_token 拉成一维的向量,q1 就是 Q 矩阵(石原里美图片)第一个 patch 向量;k0就是 K 矩阵转置后的矩阵的一列,表示的是 class_token 拉成一维的向量,k1是 K 矩阵(石原里美图片)第一个 patch 向量。

4.3 softmax( (Q @ K T K^{T} KT) / d k \sqrt{dk} dk )

首先,让给我们了解一下 Softmax 函数。Softmax 是一种用于将向量元素转换为概率分布的函数。给定一个输入向量 z = [z₁, z₂, …, zₙ],Softmax 函数将每个元素 zᵢ 转换为一个概率值 pᵢ,使得所有概率值的和等于 1。

在这里插入图片描述

举个例子,这里将q0k0、q0k1…q0kn的值转变为概率值,并将他们的和变为1。

在自注意力机制中,除以 d k \sqrt{d_k} dk 是为了缩放注意力权重,从而避免在深度较大的 Transformer 模型中由于注意力权重过大造成的梯度爆炸问题。

这里的 dk 是模型中注意力头(attention head)的维度(dimension),那么点积结果的大小为 dk ,而不同位置之间的点积结果的值范围可能差异较大。如果不进行缩放,一些较大的点积值在经过 Softmax 后可能会变得非常大,而较小的点积值在经过 Softmax 后可能接近于0。这会导致注意力权重的巨大差异,使得一些位置对其他位置的影响过大或过小,从而影响模型的学习和泛化能力。

通过除以 d k \sqrt{d_k} dk ,可以将点积结果进行缩放,使得所有点积结果的范围相对稳定,不会出现过大或过小的情况。这样,Softmax 后得到的注意力权重就会相对均衡,并且更有利于模型学习有效的全局关系和表示。

4.4 A @ V

在这里插入图片描述

如图所示,经过之前的计算,我们已经得到了权重 A 矩阵,将 A 和 Value 矩阵点乘,就是将注意力权重矩阵应用到 V 矩阵上了。图中黄色的矩形就是经过注意力机制计算得到的 Y 矩阵。Y 矩阵的维度和X 输入矩阵的维度是一模一样的。所以说 Transform 是一个即插即用的模块。

这里的qk0是 A 权重矩阵的一行,v0是 Value 矩阵的一列,qk0v0是它们点乘以后得到的一个数(即q0k0v00+q0k1v10+q0k2v20+…)。

声明:
本人作为一名作者,非常重视自己的作品和知识产权。在此声明,本人的所有原创文章均受版权法保护,未经本人授权,任何人不得擅自公开发布。
本人的文章已经在一些知名平台进行了付费发布,希望各位读者能够尊重知识产权,不要进行侵权行为。任何未经本人授权而将付费文章免费或者付费(包含商用)发布在互联网上的行为,都将视为侵犯本人的版权,本人保留追究法律责任的权利。
谢谢各位读者对本人文章的关注和支持!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/73569.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微服务 云原生:搭建 K8S 集群

为节约时间和成本,仅供学习使用,直接在两台虚拟机上模拟 K8S 集群搭建 踩坑之旅 系统环境:CentOS-7-x86_64-Minimal-2009 镜像,为方便起见,直接在 root 账户下操作,现实情况最好不要这样做。 基础准备 关…

pycharm——涟漪散点图

from pyecharts import options as opts from pyecharts.charts import EffectScatterc (EffectScatter().add_xaxis( ["高等数学1,2","C语言程序设计","python程序设计","大数据导论","数据结构","大数据…

CentOS 8 上安装 Nginx

Nginx是一款高性能的开源Web服务器和反向代理服务器,以其轻量级和高效能而广受欢迎。在本教程中,我们将学习在 CentOS 8 操作系统上安装和配置 Nginx。 步骤 1:更新系统 在安装任何软件之前,让我们先更新系统的软件包列表和已安…

opencv 31-图像平滑处理-方框滤波cv2.boxFilter()

方框滤波(Box Filtering)是一种简单的图像平滑处理方法,它主要用于去除图像中的噪声和减少细节,同时保持图像的整体亮度分布。 方框滤波的原理很简单:对于图像中的每个像素,将其周围的一个固定大小的邻域内…

HTTP、HTTPS协议详解

文章目录 HTTP是什么报文结构请求头部响应头部 工作原理用户点击一个URL链接后,浏览器和web服务器会执行什么http的版本持久连接和非持久连接无状态与有状态Cookie和Sessionhttp方法:get和post的区别 状态码 HTTPS是什么ssl如何搞到证书nginx中的部署 加…

Sqli-labs1~65关 通关详解 解题思路+解题步骤+解析

Sqli-labs 01关 (web517) 输入?id1 正常 输入?id1 报错 .0 输入?id1-- 正常判断是字符型注入,闭合方式是这里插一句。limit 100,1是从第100条数据开始,读取1条数据。limit 6是读取前6条数据。 ?id1 order by 3-- 正常判断回显位有三个。?id…

ChatGPT在法律行业的市场潜力

​ChatGPT现在已经成为我们的文字生成辅助工具、搜索引擎助手,许多体验过它的朋友会发现对它越来越依赖,并将其逐渐融入到自己的日常工作、生活。但有一点值得注意:这种人工智能除了技术可行、经济价值可行还要与相关规范即人类普遍的价值观念…

轻松批量文件改名!一键翻译重命名文件夹/文件,省时高效!」

繁忙的数字时代,我们经常需要处理大量的文件和文件夹。而手动逐个更改文件名不仅费时费力,还容易出错。因此,我们为您带来了一款强大的工具——批量文件改名软件!现在,您可以一键翻译重命名文件夹和文件,轻…

csdn新星计划vue3+ts+antd赛道——利用inscode搭建vue3(ts)+antd前端模板

文章目录 ⭐前言⭐利用inscode免费开放资源💖 在inscode搭建vue3tsant项目💖 调整配置💖 antd 国际化配置💖 用户store💖 路由权限💖 预览 ⭐结束 ⭐前言 大家好,我是yma16,本文分享…

Day10-作业(SpringBootWeb案例)

作业1:完成课上预留给大家自己完成的功能 【部门管理的修改功能】 注意: 部门管理的修改功能,需要开发两个接口: 先开发根据ID查询部门信息的接口,该接口用户查询数据并展示 。(一定一定先做这个功能) 再开发根据ID…

YOLOv5改进系列(18)——更换Neck之AFPN(全新渐进特征金字塔|超越PAFPN|实测涨点)

【YOLOv5改进系列】前期回顾: YOLOv5改进系列(0)——重要性能指标与训练结果评价及分析 YOLOv5改进系列(1)——添加SE注意力机制

[JAVA基础]自动拆装箱NPE问题

1.自动拆装箱场景 自动装箱 当把字面量转换成包装类的时候会自动装箱 比如: Integer a 1; Integer b 1; 自动拆箱 当你对包装类的对象进行运算(如加法、减法等)时,Java会自动进行拆箱操作。拆箱是将包装类型的对象转换为相应的基…

华为云hcip核心知识笔记(数据库服务规划)

华为云hcip核心知识笔记(数据库服务规划) 1.云数据接库优势 1.1云数据库优点有: 易用性强:能欧快速部署和运行 高扩展:开放式架构和云计算存储分离 低成本:按需使用,成本更加低廉 2.云数据库r…

react中的高阶组件理解与使用

一、什么是高阶组件? 其实就是一个函数,参数是一个组件,经过这个函数的处理返回一个功能增加的组件。 二、代码中如何使用 1,高级组件headerHoc 2,在普通组件header中引入高阶组件并导出高阶组件,参数是普…

基于jeecg-boot的flowable流程提供一种动态设置发起人部门负责人的方式

更多功能看演示系统 gitee源代码地址 后端代码: https://gitee.com/nbacheng/nbcio-boot 前端代码:https://gitee.com/nbacheng/nbcio-vue.git 在线演示(包括H5) : http://122.227.135.243:9888 这里给大家提供一种…

安全加固服务器

根据以下的内容来加固一台Linux服务器的安全。 首先是限制连续密码错误的登录次数,由于RHEL8之后都不再使用pam_tally.so和pam_tally2.so,而是pam_faillock.so 首先进入/usr/lib64/security/中查看有什么模块,确认有pam_faillock.so 因为只…

【雕爷学编程】MicroPython动手做(28)——物联网之Yeelight 5

知识点:什么是掌控板? 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片,支持WiFi和蓝牙双模通信,可作为物联网节点,实现物联网应用。同时掌控板上集成了OLED…

HTML中元素和标签有什么区别?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 标签(Tag)⭐元素(Element)⭐ 写在最后 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&a…

Rust操作MySQL

查询 本部分是对 「Rust入门系列」Rust 中使用 MySQL[1]的学习与记录 经常使用的时间处理库: chrono 流式查询使用: query_iter 输出到Vec使用: query 映射到结构体使用: query_map 获取单条数据使用: query_first 命名…

中兴服务器支持百度“文心一言”,助力AI产业发展

前段时间,中兴和百度正式对外宣布中兴服务器将会支持百度“文心一言”,为其提供更加强劲的算力支撑,从而加速“文心一言”的完事升级与更新迭代,助力AI产业化应用和生态的繁荣发展。   “文心一言”是百度基于文心大模型技术推出…