LaViT:这也行,微软提出直接用上一层的注意力权重生成当前层的注意力权重 | CVPR 2024

Less-Attention Vision Transformer利用了在多头自注意力(MHSA)块中计算的依赖关系,通过重复使用先前MSA块的注意力来绕过注意力计算,还额外增加了一个简单的保持对角性的损失函数,旨在促进注意力矩阵在表示标记之间关系方面的预期行为。该架构你能有效地捕捉了跨标记的关联,超越了基线的性能,同时在参数数量和每秒浮点运算操作(FLOPs)方面保持了计算效率。

来源:晓飞的算法工程笔记 公众号

论文: You Only Need Less Attention at Each Stage in Vision Transformers

  • 论文地址:https://arxiv.org/abs/2406.00427

Introduction


  近年来,计算机视觉经历了快速的增长和发展,主要得益于深度学习的进步以及大规模数据集的可获得性。在杰出的深度学习技术中,卷积神经网络(Convolutional Neural Networks, CNNs)被证明特别有效,在包括图像分类、目标检测和语义分割等广泛应用中展现了卓越的性能。

  受到Transformer在自然语言处理领域巨大成功的启发,ViTVision Transformers)将每幅图像划分为一组标记。这些标记随后被编码以生成一个注意力矩阵,作为自注意力机制的基础组成部分。自注意力机制的计算复杂度随着标记数量的增加而呈平方增长,且随着图像分辨率的提高,计算负担变得更加沉重。一些研究人员尝试通过动态选择或标记修剪来减少标记冗余,以减轻注意力计算的计算负担。这些方法在性能上已证明与标准ViT相当。然而,涉及标记减少和修剪的方法需要对标记选择模块进行细致设计,可能导致关键标记的意外丢失。在本研究中,作者探索了不同的方向,并重新思考自注意力的机制。发现在注意力饱和问题中,随着ViTs层数的逐渐加深,注意力矩阵往往保持大部分不变,重复前面层中观察到的权重分配。考虑到这些因素,作者提出以下问题:

在网络的每个阶段,从开始到结束,是否真的有必要始终一致地应用自注意力机制?

  在本文中,作者提出通过引入少注意力ViTLess-Attention Vision Transformer)来修改标准ViT的基本架构。框架由原始注意力(Vanilla Attention, VA)层和少注意力(Less Attention, LA)层组成,以捕捉长范围的关系。在每个阶段,专门计算传统的自注意力,并将注意力分数存储在几个初始的原始注意力(VA)层中。在后续的层中,通过利用先前计算的注意力矩阵高效地生成注意力分数,从而减轻与自注意力机制相关的平方计算开销。此外,在跨阶段的降采样过程中,在注意力层内集成了残差连接,允许保留在早期阶段学习到的重要语义信息,同时通过替代路径传输全局上下文信息。最后,作者仔细设计了一种新颖的损失函数,从而在变换过程中保持注意力矩阵的对角性。这些关键组件使作者提出的ViT模型能够减少计算复杂性和注意力饱和,从而实现显著的性能提升,同时降低每秒浮点运算次数(FLOPs)和显著的吞吐量。

  为验证作者提出的方法的有效性,在各种基准数据集上进行了全面的实验,将模型的性能与现有最先进的ViT变种(以及最近的高效ViT)进行了比较。实验结果表明,作者的方法在解决注意力饱和并在视觉识别任务中取得优越性能方面非常有效。

  论文的主要贡献总结如下:

  1. 提出了一种新颖的ViT架构,通过重新参数化前面层计算的注意力矩阵生成注意力分数,这种方法同时解决了注意力饱和和相关的计算负担。

  2. 此外,提出了一种新颖的损失函数,旨在在注意力重新参数化的过程中保持注意力矩阵的对角性。作者认为这一点对维护注意力的语义完整性至关重要,确保注意力矩阵准确反映输入标记之间的相对重要性。

  3. 论文的架构在包括分类、检测和分割在内的多个视觉任务中,始终表现优异,同时在计算复杂度和内存消耗方面具有类似甚至更低的特点,胜过几种最先进的ViTs

Methodology


Vision Transformer

  令 x ∈ R H × W × C \mathbf{x} \in \mathbb{R}^{H \times W \times C} xRH×W×C 表示一个输入图像,其中 H × W H \times W H×W 表示空间分辨率, C C C 表示通道数。首先通过将图像划分为 $N = \frac{HW}{p^{2}} $ 个块来对图像进行分块,其中每个块 P i ∈ R p × p × C ( i ∈ { 1 , … , N } ) P_i \in \mathbb{R}^{p \times p \times C}\left(i \in \{1, \ldots, N\} \right) PiRp×p×C(i{1,,N}) 的大小为 p × p p \times p p×p 像素和 C C C 通道。块大小 p p p 是一个超参数,用于确定标记的粒度。块嵌入可以通过使用步幅和卷积核大小均等于块大小的卷积操作提取。然后,每个块通过不重叠的卷积投影到嵌入空间 Z ∈ R N × D \boldsymbol{Z} \in \mathbb{R}^{N\times{D}} ZRN×D ,其中 D D D 表示每个块的维度。

  • Multi-Head Self-Attention

  首先提供一个关于处理块嵌入的经典自注意力机制的简要概述,该机制在多头自注意力块(MHSAs)的框架内工作。在第 l l lMHSA块中,输入 Z l − 1 , l ∈ { 1 , ⋯ , L } \boldsymbol{Z}_{l-1}, l \in \{1,\cdots, L\} Zl1,l{1,,L} 被投影为三个可学习的嵌入 { Q , K , V } ∈ R N × D \{\mathbf{Q,K,V}\} \in \mathbb{R}^{N \times D} {Q,K,V}RN×D 。多头注意力旨在从不同的视角捕捉注意力;为简单起见,选择 H H H 个头,每个头都是一个维度为 N × D H N \times \frac{D}{H} N×HD 的矩阵。第 h h h 个头的注意力矩阵 A h \mathbf{A}_h Ah 可以通过以下方式计算:

KaTeX parse error: Undefined control sequence: \label at position 145: …^{N \times N}. \̲l̲a̲b̲e̲l̲{eq:attn} \end{…

A h , Q h \mathbf{A}_h, \mathbf{Q}_h Ah,Qh K h \mathbf{K}_h Kh 分别是第 h h h 个头的注意力矩阵、查询和键。还将值 V \mathbf{V} V 分割成 H H H 个头。为了避免由于概率分布的锐性导致的梯度消失,将 Q h \mathbf{Q}_h Qh K h \mathbf{K}_h Kh 的内积除以 d \sqrt{d} d ( d = D / H d = D/H d=D/H )。注意力矩阵被拼接为:

KaTeX parse error: Undefined control sequence: \label at position 224: …). \end{split} \̲l̲a̲b̲e̲l̲{eq:concat} \en…

  在空间分割的标记之间计算的注意力,可能会引导模型关注视觉数据中最有价值的标记。随后,将加权线性聚合应用于相应的值 V \mathbf{V} V

KaTeX parse error: Undefined control sequence: \label at position 90: …^{N \times D}. \̲l̲a̲b̲e̲l̲{eq:val-feats} …

  • Downsampling Operation

  受到CNN中层次架构成功的启发,一些研究将层次结构引入到ViTs中。这些工作将Transformer块划分为 M M M 个阶段,并在每个Transformer阶段之前应用下采样操作,从而减少序列长度。在论文的研究中,作者采用了一个卷积层进行下采样操作,卷积核的大小和步幅都设置为 2 2 2 。该方法允许在每个阶段灵活调整特征图的尺度,从而建立一个与人类视觉系统的组织相一致的Transformer层次结构。

The Less-Attention Framework

  整体框架如图1所示。在每个阶段,分两步提取特征表示。在最初的几个Vanilla Attention(VA) 层中,进行标准的多头自注意力(MHSA)操作,以捕捉整体的长距离依赖关系。随后,通过对存储的注意力分数应用线性变换,模拟注意力矩阵,以减少平方计算并解决接下来的低注意力(LA)层中的注意力饱和问题。在这里,将第 m m m 个阶段的初始 l l l -th VA 层的 Softmax \textrm{Softmax} Softmax 函数之前的注意力分数表示为 A m VA , l \mathbf{A}^{\text{VA},l}_m AmVA,l ,它是通过以下标准程序计算的:

KaTeX parse error: Undefined control sequence: \label at position 135: …{\text{VA}}_m. \̲l̲a̲b̲e̲l̲{eq:init} \end{…

  这里, Q m l \mathbf{Q}_m^l Qml K m l \mathbf{K}_m^l Kml 分别表示来自第 m m m 个阶段第 l l l 层的查询和键,遵循来自前一阶段的下采样。而 L m VA L^{\text{VA}}_m LmVA 用于表示VA层的数量。在最初的原始注意力阶段之后,丢弃传统的平方MHSA,并对 A m VA \mathbf{A}^\textrm{VA}_m AmVA 应用变换,以减少注意力计算的数量。这个过程包括进行两次线性变换,中间夹一个矩阵转置操作。为了说明,对于该阶段的第 l l l 层( l > L m VA l > L^{\text{VA}}_m l>LmVA ,即LA层)的注意力矩阵:

A m l = Ψ ( Θ ( A m l − 1 ) T ) T , L m VA < l ≤ L m , Z LA , l = Softmax ( A m l ) V l . \begin{equation} \begin{aligned} &\mathbf{A}^{l}_m = \Psi(\Theta(\mathbf{A}^{l-1}_m)^\mathsf{T})^\mathsf{T}, ~~ L^{\text{VA}}_m<l \leq L_m,\\ &\mathbf{Z}^{\text{LA},l} = \textrm{Softmax}(\mathbf{A}^l_m)\mathbf{V}^l. \end{aligned} \end{equation} Aml=Ψ(Θ(Aml1)T)T,  LmVA<lLm,ZLA,l=Softmax(Aml)Vl.

  在这个上下文中, Ψ \Psi Ψ Θ \Theta Θ 表示维度为 R N × N \mathbb{R}^{N\times{N}} RN×N 的线性变换层。这里, L m L_m Lm L m VA L_m^{\text{VA}} LmVA 分别表示第 m m m 个阶段的层数和VA层的数量。在这两个线性层之间插入转置操作的目的是保持矩阵的相似性行为。这个步骤是必需的,因为单层中的线性变换是逐行进行的,这可能导致对角特性丧失。

Residual-based Attention Downsampling

  当计算在分层ViTViTs)中跨阶段进行时,通常会对特征图进行下采样操作。虽然该技术减少了标记数量,但可能会导致重要上下文信息的丧失。因此,论文认为来自前一阶段学习的注意力亲和度对于当前阶段在捕捉更复杂的全局关系方面可能是有利的。受到ResNet的启发,后者引入了快捷连接以减轻特征饱和问题,作者在架构的下采样注意力计算中采用了类似的概念。通过引入一个短路连接,可以将固有的偏差引入当前的多头自注意力(MHSA)块。这使得前一阶段的注意力矩阵能够有效引导当前阶段的注意力计算,从而保留重要的上下文信息。

  然而,直接将短路连接应用于注意力矩阵可能在这种情况下面临挑战,主要是由于当前阶段和前一阶段之间注意力维度的不同。为此,作者设计了一个注意力残差(AR)模块,该模块由深度卷积(DWConv)和一个 Conv 1 × 1 \textrm{Conv}_{1\times1} Conv1×1 层构成,用以在保持语义信息的同时对前一阶段的注意力图进行下采样。将前一阶段(第 m − 1 m-1 m1 阶段)的最后一个注意力矩阵(在 L m − 1 L_{m-1} Lm1 层)表示为 A m − 1 last \textbf{A}_{m-1}^{\text{last}} Am1last ,将当前阶段(第 m m m 阶段)的下采样初始注意力矩阵表示为 A m init \textbf{A}_m^\text{init} Aminit A m − 1 last \textbf{A}_{m-1}^{\text{last}} Am1last 的维度为 R B × H × N m − 1 × N m − 1 \mathbb{R}^{B\times{H}\times{N_{m-1}}\times{N_{m-1}}} RB×H×Nm1×Nm1 N m − 1 N_{m-1} Nm1 表示第 m − 1 m-1 m1 阶段的标记数量)。将多头维度 H H H 视为常规图像空间中的通道维度,因此通过 DWConv \textrm{DWConv} DWConv 操作符( stride = 2 , kernel size = 2 \textrm{stride}=2,\ \textrm{kernel size}=2 stride=2, kernel size=2 ),可以在注意力下采样过程中捕获标记之间的空间依赖关系。经过 DWConv \textrm{DWConv} DWConv 变换后的输出矩阵适合当前阶段的注意力矩阵的尺寸,即 R B × H × N m × N m ( N m = N m − 1 2 ) \mathbb{R}^{B\times{H}\times{N_m}\times{N_m}} (N_m = \frac{N_{m-1}}{2}) RB×H×Nm×Nm(Nm=2Nm1) 。在对注意力矩阵进行深度卷积后,再执行 Conv 1 × 1 \text{Conv}_{1\times1} Conv1×1 ,以便在不同头之间交换信息。

  论文的注意力下采样过程如图2所示,从 A m − 1 last \textbf{A}_{m-1}^\text{last} Am1last A m init \textbf{A}_{m}^\text{init} Aminit 的变换可以表示为:

KaTeX parse error: Undefined control sequence: \label at position 147: …m-1}))\right), \̲l̲a̲b̲e̲l̲{eq:residual} \…

  其中 LS \textrm{LS} LS 是在CaiT中引入的层缩放操作符,用以缓解注意力饱和现象。 A m VA \mathbf{A}^{\text{VA}}_m AmVA 是第 m m m 阶段第一层的注意力得分,它是通过将标准多头自注意力(MHSA)与公式4和由公式6计算的残差相加得出的。

  论文的注意力下采样模块受两个基本设计原则的指导。首先,利用 DWConv \text{DWConv} DWConv 在下采样过程中捕获空间局部关系,从而实现对注意力关系的高效压缩。其次,采用 Conv 1 × 1 \textrm{Conv}_{1\times1} Conv1×1 操作在不同头之间交换注意力信息。这一设计至关重要,因为它促进了注意力从前一阶段有效传播到后续阶段。引入残差注意力机制只需进行少量调整,通常只需在现有的ViT主干中添加几行代码。值得强调的是,这项技术可以无缝应用于各种版本的Transformer架构。唯一的前提是存储来自上一层的注意力得分,并相应地建立到该层的跳跃连接。通过综合的消融研究,该模块的重要性将得到进一步阐明。

Diagonality Preserving Loss

  作者通过融入注意力变换算子,精心设计了Transformer模块,旨在减轻计算成本和注意力饱和的问题。然而,仍然存在一个紧迫的挑战——确保变换后的注意力保留跨Token之间的关系。众所周知,对注意力矩阵应用变换可能会妨碍其捕捉相似性的能力,这在很大程度上是因为线性变换以行的方式处理注意力矩阵。因此,作者设计了一种替代方法,以确保变换后的注意力矩阵保留传达Token之间关联所需的基本属性。一个常规的注意力矩阵应该具备以下两个属性,即对角性和对称性:

KaTeX parse error: Undefined control sequence: \label at position 146: … \end{aligned} \̲l̲a̲b̲e̲l̲{eq:property} \…

  因此,设计了第 l l l 层的对角性保持损失,以保持这两个基本属性如下所示:

L DP , l = ∑ i = 1 N ∑ j = 1 N ∣ A i j − A j i ∣ + ∑ i = 1 N ( ( N − 1 ) A i i − ∑ j ≠ i A j ) . \begin{equation} \begin{split} {\mathcal{L}_{\textrm{DP},l}} &= \sum_{i=1}^N\sum_{j=1}^N\left|\mathbf{A}_{ij} -\mathbf{A}_{ji}\right| \\ &+ \sum_{i=1}^N((N-1)\mathbf{A}_{ii}-\sum_{j\neq i}\mathbf{A}_{j}). \end{split} \end{equation} LDP,l=i=1Nj=1NAijAji+i=1N((N1)Aiij=iAj).

  在这里, L DP \mathcal{L}_\textrm{DP} LDP 是对角性保持损失,旨在维护公式8中注意力矩阵的属性。在所有变换层上将对角性保持损失与普通的交叉熵 (CE) 损失相结合,因此训练中的总损失可以表示为:

[ b ] L total = L CE + ∑ m = 1 M ∑ l = 1 L m L DP , l , L CE = cross-entropy ( Z Cls , y ) , \begin{equation} \begin{aligned}[b] \mathcal{L}_\textrm{total} &= \mathcal{L}_\textrm{CE} + \sum_{m=1}^M\sum_{l=1}^{L_m}\mathcal{L}_{\textrm{DP},l}, \\ \mathcal{L}_\textrm{CE} &= \textrm{cross-entropy}(Z_\texttt{Cls}, y), \end{aligned} \end{equation} [b]LtotalLCE=LCE+m=1Ml=1LmLDP,l,=cross-entropy(ZCls,y),

  其中, Z Cls Z_\texttt{Cls} ZCls 是最后一层表示中的分类标记。

Complexity Analysis

  论文的架构由四个阶段组成,每个阶段包含 L m L_m Lm 层。下采样层应用于每个连续阶段之间。因此,传统自注意力的计算复杂度为 O ( N m 2 D ) \mathcal{O}(N_m^2{D}) O(Nm2D) ,而相关的K-Q-V转换则带来了 O ( 3 N m D 2 ) \mathcal{O}(3N_mD^2) O(3NmD2) 的复杂度。相比之下,论文的方法在变换层内利用了 N m × N m N_m\times N_m Nm×Nm 的线性变换,从而避免了计算内积的需要。因此,变换层中注意力机制的计算复杂度降至 O ( N m 2 ) \mathcal{O}(N_m^2) O(Nm2) ,实现了 D D D 的减少因子。此外,由于论文的方法在 Less-Attention中只计算查询嵌入,因此K-Q-V转换复杂度也减少了3倍。

  在连续阶段之间的下采样层中,以下采样率2为例,注意力下采样层中DWConv的计算复杂度可以计算为 Complexity = 2 × 2 × N m 2 × N m 2 × D = O ( N m 2 D ) \textrm{Complexity} = 2 \times 2 \times \frac{N_m}{2} \times \frac{N_m}{2} \times D = \mathcal{O}(N_m^2D) Complexity=2×2×2Nm×2Nm×D=O(Nm2D) 。同样,注意力残差模块中 Conv 1 × 1 \textrm{Conv}_{1\times1} Conv1×1 操作的复杂度也是 O ( N m 2 D ) \mathcal{O}(N_m^2D) O(Nm2D) 。然而,重要的是,注意力下采样在每个阶段仅发生一次。因此,对比Less-Attention方法所实现的复杂度减少,这些操作引入的额外复杂度可以忽略不计。

Experiments




如果本文对你有帮助,麻烦点个赞或在看呗~
更多内容请关注 微信公众号【晓飞的算法工程笔记】

work-life balance.

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

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

相关文章

从0到1搭建用户管理系统

手把手教你搭建前后端框架 新手对于很多成熟框架&#xff0c;不知道如何搭建的&#xff0c;不知道如何实现等等&#xff0c;忙碌之余&#xff0c;写了一篇博客 手把手教你搭建前后端框架源码&#xff0c; springbootmysqlelementuivue 从0到1&#xff0c;搭建springboot框架&am…

出租车4G5G无线车载监控系统解决方案(下)

目录 一、项目概述 1.1 项目背景 1.2 设计原则 1.3 设计目标 1.4 实施意义 二、系统总体设计 2.1建设目标 2.2系统模式 2.3设计思路 2.4设计架构 2.5系统组成 2.6优势分析 2.7设备达到的功能要求 2.8系统组成 三、系统详细设计 3.1 出租车车载监控 3.1.1 系统功能设计 3.2系统前…

如何在退出Qt时保存用户配置

如何在退出Qt时保存用户配置 文章目录 如何在退出Qt时保存用户配置一、简介二、 保存配置数据&#xff08;方法一&#xff09;2.1 项目实现2.2 运行结果 三、保存配置数据&#xff08;方法二&#xff09;3.1 项目实现3.2 运行结果 四、写在最后 ​ 一、简介 在我们使用 Qt 进行…

吹爆上海交大的大模型实战教程!!非常详细收藏我这一篇就够了

各位好&#xff0c;这里是DASOU 今天分享一个上海交大的免费的大模型课程&#xff0c;有相关教程文档和Slides&#xff0c;目前是1.6K星标&#xff0c;还是挺火的 项目动机 《动手学大模型》系列编程实践教程&#xff0c;由上海交通大学2024年春季《人工智能安全技术》课程&…

MySQL集群

一、Mysql 在服务器中的部署方法 1.1源码安装 下载依赖性 dnf install cmake gcc-c openssl-devel ncurses-devel.x86_64 libtirpc-devel-1.3.3-8.el9_4.x86_64.rpm rpcgen.x86_64 解压压缩包并安装 tar zxf mysql-boost-5.7.44.tar.gz cd /root/mysql-5.7.44 cmake \ -DCM…

java写入word表格(poi-tl)

1.导入依赖 <!--poi-tl--> <dependency><groupId>com.deepoove</groupId><artifactId>poi-tl</artifactId><version>1.12.0</version> </dependency>2.代码 自己创建模板。放在&#xff08;resource/file&#xff09;…

非标机械设计项目“规范”笔记

2.自动化设备开发特点与技术文件输出 2.1自动化设备 自动化设备 工业自动化设备类型&#xff1a;标准自动化、非标自动化 载具和治具 焊接治具---汽车行业用的多 压装、压合治具---3C行业 治具种类&#xff1a; 电木&#xff1a;测试治具箱体&#xf…

工作5年,没听过MySQL半同步复制,是我的问题吗?

目录 一、存储高可用二、读写分离三、解决主从复制延迟问题的几种方案1、写操作后的读操作指定发给数据库主服务器2、读从机失败后再读一次主机3、关键业务读写操作全部指向主机&#xff0c;非关键业务采用读写分离4、压缩与批量传输5、优化从库的查询性能6、优化网络延迟7、调…

构建大师:深入理解Linux下的Make和Makefile

引言 在软件开发的世界里&#xff0c;构建过程是一项繁琐而重要的任务。无论是简单的脚本还是复杂的软件项目&#xff0c;都需要一种方式来自动化编译、链接以及测试等过程。在Linux环境下&#xff0c;Make工具和它的配置文件——Makefile&#xff0c;成为了许多开发者构建项目…

RuoYi-Vue 最新 SpringBoot3 前后端分离版本源码分析

RuoYi-Vue 最新 SpringBoot3 前后端分离版本源码分析 RuoYi-Vue 本地环境部署若依菜单类型权限管理SpringSecurity 配置登录接口(认证管理)Authentication 认证token的生成 权限控制 异步任务管理操作日志数据权限 RuoYi-Vue 本地环境部署 直接去 gitee 上拉取最新版本即可&am…

<Rust>egui学习之小部件(三):如何为窗口UI元件设置布局(间隔、水平、垂直排列)?

前言 本专栏是关于Rust的GUI库egui的部件讲解及应用实例分析&#xff0c;主要讲解egui的源代码、部件属性、如何应用。 环境配置 系统&#xff1a;windows 平台&#xff1a;visual studio code 语言&#xff1a;rust 库&#xff1a;egui、eframe 概述 本文是本专栏的第三篇博…

C++和OpenGL实现3D游戏编程【连载7】——文字和汉字的显示

1、本节实现的内容 上一节我们讨论了纹理在二维平面内不规则图形贴图的相关基础操作,本节我们开始了解游戏里文字以及汉字的显示方法。本节课我们将从基本的ASCII字符显示,拓展到中文字符的显示,最后再讲到纹理字符的显示,并对各种文字显示方法的优缺点和使用场景进行分析…

使用Masscan扫描器进行信息搜集

Masscan 是一款极为高效的端口扫描工具&#xff0c;以其卓越的扫描速度和大规模扫描能力而著称。该工具不仅支持 TCP 和 UDP 协议的扫描&#xff0c;还允许用户根据需求灵活指定多个目标和端口。Masscan 通过采用先进的网络性能优化技术&#xff0c;充分利用操作系统的资源和多…

基于北斗+自组网技术的光伏电场人员位置监控系统优化方案

一、方案背景 1.1 用户需求 随着我国经济的快速发展&#xff0c;光伏电场等新能源项目的建设日益增多。然而&#xff0c;这些项目往往位于偏远地区&#xff0c;通信基础设施不完善&#xff0c;导致施工人员在作业过程中难以与外界保持实时联系。特别是在无人区或信号弱的地区…

【Qt 事件】—— 详解Qt事件处理

目录 &#xff08;一&#xff09;事件介绍 &#xff08;二&#xff09;事件的处理 &#xff08;三&#xff09;按键事件 3.1 单个按键 3.2 组合按键 &#xff08;四&#xff09;鼠标事件 4.1 鼠标单击事件 4.2 鼠标释放事件 4.3 鼠标双击事件 4.4 鼠标移动事件 4.5…

101.SAP MII功能详解(15)Workbench-Transaction Logic(Iterator)

目录 1.Logic->Iterator 2.演示 配置连接 Iterator使用示例 1.Logic->Iterator 您可以使用此操作迭代循环浏览List&#xff0c;迭代是指遍历某个List数据结构&#xff0c;逐个访问其元素的过程。迭代使用的场景不多。 2.演示 配置连接 Iterator使用示例 数据源是Lis…

Qt:玩转QPainter序列九(文本,文本框,填充)

前言 继续承接序列八 正文 1. drawImage系列函数 绘制图像 inline void drawImage(const QPoint &p, const QImage &image); 作用: 在指定的点 p 上绘制 QImage 图像。图像的左上角将对齐到 p 点。 inline void drawImage(int x, int y, const QImage &image,…

[001-07-001].Redis7缓存双写一致性之更新策略探讨

1、面试题&#xff1a; 1.只要使用缓存&#xff0c;就可能会涉及到redis缓存与数据库双存储双写&#xff0c;只要是双写&#xff0c;就存在数据一致性问题&#xff0c;那么是如何解决数据一致性问题的2.双写一致性&#xff0c;你先动缓存redis还是数据库MySQL&#xff0c;哪一个…

新能源汽车超级电容和电池能量管理系统的simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1 电池模型 4.2 电池荷电状态&#xff08;SOC&#xff09;估算 4.3 超级电容器模型 4.4 能量管理 5.完整工程文件 1.课题概述 新能源汽车的能量管理系统&#xff08;Energy Management System, EMS…

中国艺术孙溟㠭凿篆《无用之用》

孙溟㠭凿篆作品《无用之用》 这方作品是孙溟㠭先生用凿木的方式凿刻出来的&#xff0c;呈现出了凿痕的效果&#xff0c;与众不同。 孙溟㠭凿篆《无用之用》 孙溟㠭凿篆《无用之用》 万般皆有所用&#xff0c;取其长补余短&#xff0c;无用之用是为大用&#xff0…