注意力机制介绍
注意力机制介绍
- 1.注意力机制由来,以及解决什么问题
- 2.什么是注意力机制
- 3.注意力机制分类及如何实现
- 3.1 Soft Attention(常见):软注意
- 3.1.1普通Encoder-Decoder框架
- 3.1.2加入Attention的Encoder-Decoder框架
- 3.1.3如何理解注意力概率分布
- 3.1.4 Attention机制本质思想
- 3.2 Hard Attention(硬注意)
- 3.3 Self Attention:自注意
- 注意力机制介绍2
- 1.注意力机制规则
- 2.常见的注意计算规则
- 3.注意力机制作用
- 4.注意力机制实现步骤;
- 4.1步骤
- 4.2代码实现
1.注意力机制由来,以及解决什么问题
- 机器翻译任务
例子:seq2seq架构翻译任务

- seq2seq 模型架构包括三个部分:编码器(encoder),解码器(decoder),中间语义张量C
- 图中表示中文翻译:欢迎来北京—> welcome to beijing,首先编码器 通过embedding把每个token转换为词向量,在通过GRU模型获取每个时间步的输出张量最后拼接为中间语义张量c;输入_GO通过解码器将使用中间语义张量c以及每一个时间步的隐层张量,组个生成对应的翻译语言,直到输出_EOS翻译结束.
- 早期在解决机器翻译这一类seq2seq时,通常利用一个编码器(encoder)以及一个解码器(decoder)构建端到端的神经网络模型,但基于编码解码存在两个问题:
- 问题1:如果翻译的句子很长很复杂,模型计算量很大,并且模型准确率下降严重.
- 问题2:在翻译时,可能在不同的语境下,同一个词具有不同含义,网络对这些词向量没有区分度,没有考虑词与词之间的相关性,导致翻译效果比较差.
2.什么是注意力机制
- 伴随着transformer模型架构的提出,注意力机制在NLP,CV相关问题的模型被广泛使用,注意力机制就是将人的感知方式,注意力行为应用在机器上,让机器去学习数据中重要和不重要的部分.
- 在机器翻译时,让机器注意到每个词向量之间的相关性,有侧重的进行翻译,模拟人类理解过程.
3.注意力机制分类及如何实现
介绍:
就是对于模型的的每一个输入项,可能是图片中不同部分,又或者是语句中某个单词分配的权重,这个分配的权重大小就希望模型地该部分一个关注程度.通过调整权重大小 来模拟在处理信息的注意力侧重,有效提高模型的性能,并且一定程度上降低计算量.
- 深度学习中注意力机制通常可分为三类:软注意(全局注意),硬注意(局部注意),自注意(内注意)
- 软注意机制 (Soft-Attention):对每个输入项的分配权重为0-1之间,对部分关注对一点,对部分关注少一点,对大部分信息考虑,但考虑层度不一样,计算量比较大.
- 硬注意机制(Hard-Attention):对每个输入项分配的权重非0即1,硬注意只考虑部分需要关注,不需要关注的部分直接舍弃,有可能丢失一些本应该注意的信息,优势在于可以减少时间与计算成本.
- 自注意机制(Self-Attention):对每个输入项分配的权重取决于输入项之间相互作用,通过输入项内部"表决"来决定应该关注那些输入项,与前两者相比,在处理很长的输入时,具有并行计算的优势.
3.1 Soft Attention(常见):软注意
注意力机制:是一种通用的思想与技术,不依赖于任何模型;注意力机制可用于任何模型
以文本领域的Encoder-Decoder框架,以普通Encoder-Decoder框架以及加Attention的Encoder-Decoder框架分别做对比.
3.1.1普通Encoder-Decoder框架
- 如图所示

- 上图图例可以看作由一个句子(或篇章)生成另外一个句子(或篇章)的通用处理模型,我们给定输入句子Source,通过Encoder-Decoder框架来生成目标句子Target,Source和Target可以使用同种语言,也可以使用不同语言,Source和Target分别由各自单词序列构成:
S o u r c e = < X 1 , X 2 . . . X m > T a r g e t = < y 1 , y 2 . . . , Y n > Source = <X_1,X_2...X_m>\\Target = <y_1,y_2...,Y_n> Source=<X1,X2...Xm>Target=<y1,y2...,Yn>
- encoder就是对输入句子Source进行编码,将句子通过非线性变换转换(拼接)成中间语义表示C:
C = F ( X 1 , X 2 . . . X m ) C = F(X_1,X_2...X_m) C=F(X1,X2...Xm)
- decoder根据句子Source的中间语义表示C和之前生成的历史信息y1,y2…yi-1来生成i时刻要生层的单词yi:
y i = G ( C , y 1 , y 2 . . . y i − 1 ) y_i = G(C,y_1,y_2...y_{i-1}) yi=G(C,y1,y2...yi−1)
- 上述模型没有出现注意力模型,看作注意力不集中分心模型,Target中每个单词生成过程如下:
y 1 = f ( C ) y 2 = f ( C , y 1 ) y 3 = f ( C , y 1 , y 2 ) y_1 = f(C)\\ y_2 = f(C,y_1)\\ y_3 = f(C,y_1,y_2) y1=f(C)y2=f(C,y1)y3=f(C,y1,y2)
- f为decoder非线性变换函数,再生成目标单词时,使用的输入句子语义编码C都是一样的,因此对输入token对目标token影响力都是相同的,这是不合理的,模型将无法捕捉输入序列的复杂结构和token之间的依赖关系.
3.1.2加入Attention的Encoder-Decoder框架
举例说明,为何添加Attention:
在机器翻译任务时,输入scoure:Tom chase Jerry ,输出target为:"汤姆’‘,"追逐’‘,’’ 杰瑞’'时,在翻译Jerry这个单词时,普通Encoder-Decoder框架中,source里的每个单词对杰瑞贡献相同,很明显不太合理,显然Jerry对翻译成"杰瑞"更重要.
-
引入Attention机制,在生成 杰瑞 时,应该体现英文单词翻译成中文单词不同影响程度比如给出类似给概率分布值:(Tom,0.3)(Chase,0.2) (Jerry,0.5),每个单词概率分布概率代表翻译成单词 杰瑞 时的概率,注意力分配给不同英文单词的注意力大小.
-
对于target任意单词都有对应的source中单词注意力分配概率,由于Attention加入,在生成target单词时中间语义c不在固定,会根据注意力变化在翻译时得到不同的中间语义C

-
生成目标句子单词过程形式:
y 1 = f 1 ( C 1 ) y 2 = f 2 ( C 2 ) y 3 = f 3 ( C 3 ) y_1 = f_1(C_1)\\ y_2 = f_2(C_2)\\ y_3 = f_3(C_3) y1=f1(C1)y2=f2(C2)y3=f3(C3)
- 每个Ci对应着不同的原语句单词注意力概率分布,对于上面英译汉翻译来说,其对应信息可能如下:
C T o m = g ( 0.6 ∗ f 2 ( T o m ) , 0.2 ∗ f 2 ( C h a s e ) , 0.2 ∗ f 2 ( T e r r y ) ) C C h a s e = g ( 0.2 ∗ f 2 ( T o m ) , 0.7 ∗ f 2 ( C h a s e ) , 0.1 ∗ f 2 ( T e r r y ) ) C J e r r y = g ( 0.3 ∗ f 2 ( T o m ) , 0.2 ∗ f 2 ( C h a s e ) , 0.5 ∗ f 2 ( T e r r y ) ) C_{Tom} = g(0.6 * f_2(Tom),0.2 * f_2(Chase),0.2 * f_2(Terry))\\ C_{Chase} = g(0.2 * f_2(Tom),0.7 * f_2(Chase),0.1 * f_2(Terry))\\ C_{Jerry} = g(0.3 * f_2(Tom),0.2 * f_2(Chase),0.5 * f_2(Terry)) CTom=g(0.6∗f2(Tom),0.2∗f2(Chase),0.2∗f2(Terry))CChase=g(0.2∗f2(Tom),0.7∗f2(Chase),0.1∗f2(Terry))CJerry=g(0.3∗f2(Tom),0.2∗f2(Chase),0.5∗f2(Terry))
- f2函数代表Encoder对输入英文单词的某种变换函数,比如如果使用RNN模型f2函数结果往往代表某个时刻输入后隐藏层节点状态值;g代表Encoder根据单词中间表示合成整个句子中间语义表示得到变换函数,一般做法中,g函数就是对构成元素加权求和,即公式:
C i = ∑ j = 1 L x a i j h j C_i = \sum_{j=1}^{L_x}a_{ij}h_j Ci=j=1∑Lxaijhj
-
Lx代表输入句子长度source的长度,a_ij代表Target输出第i个单词source输入句子中的第j个单词的注意力分配系数,而hj 表示source输入句子中第j个单词的语义编码,假设Ci下标i就是上面例子所说的汤姆,那么Lx就是3.
h1=f(‘Tom’), h2=f(‘Chase’),h3=f(‘jerry’)分别输入句子每个单词的语义编码,对应的注意力模型权重值分别是:0.6,0.2,0.2,所以g函数本质上就是加权求和函数.类似下图


3.1.3如何理解注意力概率分布
- 为方便说明我们假设Encoder-Decoder框架中,都采用RNN模型,如下图所示

- 注意力分配概率分布值计算过程如下:

- 图中hi表示Source中单词对应隐藏层节点状态hj,Hi表示Target中单词i隐藏层节点状态,注意力计算Target中单词Source对每个单词对其的可能性,即F(hi,Hi-1),后经过softmax归一化得到注意力分配概率.
3.1.4 Attention机制本质思想
Attention机制可以看作,Target中每个单词对Source每个单词的加权求和,而权重是Source中每个单词对Target的每个单词重要程度.因此,Attention本质思想表示如下图;

- 将Source中构成元素看作一系列数据对,给定Target中某个元素Query和各个Key的相关性或者相似性即权重系数;对Value 进行加权求和,并得到最终Attention数值,公式如下:
A t t e n t i o n ( Q u e r y , S o u r c e ) = ∑ i = 1 L x S i m i l a r i t y ( Q u r e y , K e y i ) ∗ V a l u e i Attention(Query,Source) =\sum_{i=1}^{L_x} Similarity(Qurey,Key_i) * Value_i Attention(Query,Source)=i=1∑LxSimilarity(Qurey,Keyi)∗Valuei
- 深度学习中注意力机制中提到:Source中的Key和Value合二为一,指的是同一个东西,也即是输入句子中每个单词对应的语义编码,因此Attention计算转换为下面3个阶段.
- 输入由三部分组成:Query,Key和Value,其中(Key,Value)是具有相互关联的K对,Query是输入的’问题’,attention将Query转换成与Query相关向量表示
- Attention计算分为3步,如图所示;

- Attention 3步计算过程(举例说明)
- 第一步:Query和Key进行相似度计算,得到Attention Score;

- 第二步:对Attention Score进行Softmax归一化,得到权值矩阵;

- 第三步:权重矩阵与value进行加权求和

3.2 Hard Attention(硬注意)
- 在之前使用软性注意力的方式进行Attention机制,它通过注意力分布来加权融合各个输入向量,而硬性注意力机制不采用这种方式,它是根据注意力分布选择输入向量中的一个作为输出,有两种方式:
- 选择注意力分布中:分数最大的那一项对应的输入向量作为Attention机制输出
- 根据注意力机制分步进行随机采样,采样结果为Attention机制输出
硬注意力机制通过以上两种方法选择Attention的输出,这会使得最终的损失函数与注意力之间函数关系不可导,导致无法使用反向传播算法训练模型,硬性注意力通常需要使用强化学习来训练,因此,一般深度学习算法会使用软性注意力的方式进行计算
3.3 Self Attention:自注意
上面介绍Attention发生在Target元素Query 和Source中所有元素元素之间,而self Attention指的是Source内部元素之间或者Target内部元素之间发生的Attention机制,也可以理解为Target= source这种特殊情况下的注意力机制.
-
允许模型在处理序列数据时,不仅仅关注当前的元素,还能关注序列的其他元素,计算元素之间相似性,从而更好的捕捉长距离依赖关系自注意机制是Transfromer模型的核心部分,极大提高了模型的性能.

-
Attention发展主要经历两个阶段:
从上图可以看到,self Attention可以远距离捕捉到语义层面的特征(its 代指对象 Law)
应用传统的RNN,LSTM,在获取长距离语义特征和结构特征时候,需要按照序列顺序依次计算,距离越远的联系信息损耗越大,有效提取和捕获 的可能性越小
在self Attention,计算时,会直接将句子中任意两个token的联系通过一个计算步骤直接联系起来
注意力机制介绍2
1.注意力机制规则
- 需要三个指定的输入Q(query),K(key),V(value),通过公式计算得到注意力结果,这个结果代表query在key和value作用下注意力表示输入的Q=K=V时,称作自注意计算规则;当Q,K,V不想等时,称为一般注意力计算规则
例子:seq2seq架构翻译应用中的Q K V解释

- 模型架构包括三个部分:encoder(编码器),decoder(解码器),中间语义张量C
- 机器翻译加入Attention方式有两种:
- 第一种为tensorfiow(传统版本):

- 解释
查询张量Q:解码器每一步输入或者是当前输入的x
键张量K:编码部分每个时间步结果组合而成
值张量:编码每个时间步结果组合而成
介绍:
'欢迎来北京' 经过分词得到长度为3的词表,每个token经过GRU(门控制单元结构)输K=V(1,3)
的向量后与Q(预测结果上个隐藏状态hn或初始化的s0)并行计算k*q的转置得到分数值(1,3)的source经过softmax计算每个token在预测时的概率值后,与V相乘并按位相加输出得到长度为(1,3)向量后,与解码器经过GRU输出前的值拼接得到(1,6)向量输入到下一个GRU得到下个预测值.
- 第二种Pytorch版本:

- 查询张量Q: 解码器每一步的输出或者是当前输入的x
- 键张量K: 解码器上一步的隐藏层输出
- 值张量V:编码部分每个时间步输出结果组合而成
介绍:
输入'欢迎来北京'经过GRU输出按行拼接得到(3,3)矩阵,把编码器输出的隐藏状态K当做解码器输入部分,后解码翻译得到的Welcome转换为q(1,3)向量与解码器GRU输出隐藏层K拼接得到(1,6)后经过线性层(6,3)得到(1,3)后经过softmax计算得到预测下个结果的概率值与V(3,3)矩阵点积得到(1,3)向量后与Welcome转换的(1,3)向量拼接输入到下一个GRU来翻译下一个结果.
2.常见的注意计算规则
- 将Q,K进行纵轴拼接,做一次线性变换,在使用softmax处理后获得结果与V做张量乘法
A t t e n t i o n ( Q , K , V ) = S o f t m a x ( L i n e a r ( [ Q , K ] ) ) . V Attention(Q,K,V) = Softmax(Linear([Q,K])).V Attention(Q,K,V)=Softmax(Linear([Q,K])).V
- 将Q与K的转置做点积运算,然后除以一个缩放系数,在使用softmax处理后获得结果最后与V做张量
A t t e n t i o n ( Q , K , V ) = S o f t m a x ( Q . K T d k ) . V Attention(Q,K,V) = Softmax(\frac{Q.K_T}{\sqrt{d_k}}).V Attention(Q,K,V)=Softmax(dkQ.KT).V
- 为什么要使用深度神经网络中的引入注意力机制?
1.RNN等循环神经网络,随着时间步的增长,前面单词特征会遗忘,造成句子特征提取不充分
2.RNN等循环神经网络是一个时间步一个时间步的提取序列特征,效率低下
3.映入注意力机制进行并行计算
3.注意力机制作用
- 在解码器端注意力机制:能够根据模型目标有效聚焦编码器输出结果当做解码器的输入提升效果,改善以往编码器输出的单一长张量,无法存储过多特征问题
- 在编码器端注意力机制:主要解决表特征问题,相当于特征提取过程,得到输入注意力表示,一般使用自注意力
- 注意机制在网络中实现图形表示

4.注意力机制实现步骤;
4.1步骤
- 第一步:根据注意计算规则,对Q,K,V进行相应计算
- 第二步:根据第一步采用的计算方法, 如果是拼接方法,则需要将Q与第二步的计算结果再进行拼接, 如果是转置点积, 一般是自注意力, Q与V相同, 则不需要进行与Q的拼接.
- 第三步:最后为了使整个attention机制按照指定尺寸输出, 使用线性层作用在第二步的结果上做一个线性变换, 得到最终对Q的注意力表示.
4.2代码实现
任务描述:
有QKV:v是内容比如32个单词,每个单词64个特征,k是32个单词的索引,q是查询张量
我们的任务:输入查询张量q,通过注意力机制来计算如下信息:
#1、查询张量q的注意力权重分布:查询张量q和其他32个单词相关性(相识度)
#2、查询张量q的结果表示:有一个普通的q升级成一个更强大q;用q和v做bmm运算
#3 注意:查询张量q查询的目标是谁,就是谁的查询张量。
eg:比如查询张量q是来查询单词"我",则q就是我的查询张量
import torch
import torch.nn as nn
import torch.nn.functional as F# MyAtt类实现思路分析
# 1 init函数 (self, query_size, key_size, value_size1, value_size2, output_size)
# 准备2个线性层 注意力权重分布self.attn 注意力结果表示按照指定维度进行输出层 self.attn_combine
# 2 forward(self, Q, K, V):
# 求查询张量q的注意力权重分布, attn_weights[1,32]
# 求查询张量q的注意力结果表示 bmm运算, attn_applied[1,1,64]
# q 与 attn_applied 融合,再按照指定维度输出 output[1,1,32]
# 返回注意力结果表示output:[1,1,32], 注意力权重分布attn_weights:[1,32]class MyAtt(nn.Module):# 32 32 32 64 32def __init__(self, query_size, key_size, value_size1,value_size2, output_size):super(MyAtt, self).__init__()self.query_size = query_sizeself.key_size = key_sizeself.value_size1 = value_size1self.value_size2 = value_size2self.output_size = output_size# 线性层1 注意力权重分布self.attn = nn.Linear(self.query_size + self.key_size, self.value_size1)# 线性层2 注意力结果表示按照指定维度输出层 self.attn_combineself.attn_combine = nn.Linear(self.query_size+self.value_size2, output_size)def forward(self, Q, K, V):# 1 求查询张量q的注意力权重分布, attn_weights[1,32]# [1,1,32],[1,1,32]--> [1,32],[1,32]->[1,64]# [1,64] --> [1,32]# tmp1 = torch.cat( (Q[0], K[0]), dim=1)# tmp2 = self.attn(tmp1)# tmp3 = F.softmax(tmp2, dim=1)attn_weights = F.softmax( self.attn(torch.cat( (Q[0], K[0]), dim=-1)), dim=-1)# 2 求查询张量q的结果表示 bmm运算, attn_applied[1,1,64]# [1,1,32] * [1,32,64] ---> [1,1,64]attn_applied = torch.bmm(attn_weights.unsqueeze(0), V)# 3 q 与 attn_applied 融合,再按照指定维度输出 output[1,1,64]# 3-1 q与结果表示拼接 [1,32],[1,64] ---> [1,96]output = torch.cat((Q[0], attn_applied[0]), dim=-1)# 3-2 shape [1,96] ---> [1,32]output = self.attn_combine(output).unsqueeze(0)# 4 返回注意力结果表示output:[1,1,32], 注意力权重分布attn_weights:[1,32]return output, attn_weights
if __name__ == '__main__':query_size = 32key_size = 32value_size1 = 32 # 32个单词value_size2 = 64 # 64个特征output_size = 32Q = torch.randn(1, 1, 32)K = torch.randn(1, 1, 32)V = torch.randn(1, 32, 64)# V = torch.randn(1, value_size1, value_size2)# 1 实例化注意力类 对象myattobj = MyAtt(query_size, key_size, value_size1, value_size2, output_size)# 2 把QKV数据扔给注意机制,求查询张量q的注意力结果表示、注意力权重分布output, attn_weights = myattobj(Q, K, V)print('查询张量q的注意力结果表示output--->', output.shape, output)print('查询张量q的注意力权重分布attn_weights--->', attn_weights.shape, attn_weights)
- 输出结果
查询张量q的注意力结果表示output---> torch.Size([1, 1, 32]) tensor([[[ 0.3135, -0.0539, 0.0597, -0.0046, -0.3389, -0.1238, 1.0385,0.8896, -0.0268, -0.0705, -0.8409, 0.6547, 0.5909, -0.6048,0.6303, -0.2233, 0.7678, -0.3140, 0.3635, -0.3234, -0.1053,0.5845, 0.1163, -0.2203, -0.0812, -0.0868, 0.0218, -0.0597,0.6923, -0.1848, -0.8266, -0.0614]]], grad_fn=<UnsqueezeBackward0>)
查询张量q的注意力权重分布attn_weights---> torch.Size([1, 32]) tensor([[0.0843, 0.0174, 0.0138, 0.0431, 0.0110, 0.0308, 0.0608, 0.0216, 0.0101,0.0406, 0.0462, 0.0111, 0.0349, 0.0065, 0.0383, 0.0526, 0.0151, 0.0193,0.0294, 0.0632, 0.0322, 0.0072, 0.0294, 0.0388, 0.0135, 0.0443, 0.0594,0.0332, 0.0117, 0.0168, 0.0293, 0.0344]], grad_fn=<SoftmaxBackward0>)
相关文章:
注意力机制介绍
注意力机制介绍 1.注意力机制由来,以及解决什么问题2.什么是注意力机制3.注意力机制分类及如何实现3.1 Soft Attention(常见):软注意3.1.1普通Encoder-Decoder框架3.1.2加入Attention的Encoder-Decoder框架3.1.3如何理解注意力概率分布3.1.4 Attention机制本质思想 3.2 Hard At…...
爬虫运行后数据如何存储?
爬虫运行后获取的数据可以存储在多种不同的存储系统中,具体选择取决于数据的规模、查询需求以及应用场景。以下是一些常见的数据存储方法: 1. 文件系统 对于小型项目或临时数据存储,可以直接将数据保存到本地文件中。常见的文件格式包括&…...
C# 自动自定义截图的内容
C# 自动自定义截图的内容 using System; using System.Drawing; using System.Runtime.InteropServices; class Program {[DllImport("user32.dll")]public static extern IntPtr GetDesktopWindow();[DllImport("user32.dll")]public static extern IntP…...
Java的Stream流:文件处理、排序与串并行流的全面指南
Java的Stream流:文件处理、排序与串并行流的全面指南 Java 8 引入了 Stream API,这是一个用于处理集合数据的强大工具,它提供了一种声明式的方式来进行聚合操作。Stream 不是一个数据结构,而是一种对数据进行操作的抽象ÿ…...
[Maven]下载安装、使用与简介
很多框架的下载使用的流程和思路是差不多的,这里以maven做详细介绍。 下载安装与配置变量 下载 首先,我们要使用maven,必须先下载它的相关文件。想要下载,我们可以直接搜索maven。找到它的官网。这里不绕弯子,直接给出…...
056 WXML+ WXSS+PHP+LW+校园配送商城微信小程序开发与设计 源码 文档 全套资料
校园配送微信小程序 1.项目描述2. 1.绪论3.项目技术与功能4.界面展示5.源码获取 1.项目描述 摘 要 近几年来,随着互联网和电子商务的快速发展和普及,改变了人们日常消费模式。尤其是移动互联网的相结合,使得人们日常生活中更多的是通过手机移…...
Python 在同一/或不同PPT文档之间复制幻灯片
复制幻灯片可以帮助我们更高效地完成工作,节省大量的制作时间。通过复制现有的幻灯片,可以快速创建新的演示文稿,而无需重新设计板式样式等。此外,复制幻灯片还可以帮助我们保持内容的一致性,使整个PPT演示文稿看起来更…...
C#生成CSR(CertificateSigningRequest)和密钥
使用C#原生生成CSR(CertificateSigningRequest)和密钥。 生成的私钥妥善保存,丢失无法找回。 调用 var contents X509Helper.SigningRequestHelper.CreateSigningRequest("yourdomain.com", ["*.yourdomain.com"], X509Helper.AsymmetricAl…...
Docker 安装 Oracle创建表空间并导入数据库
一、Docker 安装Oracle 1、检查docker 版本 2、docker 下载镜像 3、 docker启动容器 4、 进入容器内部 5、安装成功,使用客户端工具连接 二、创建数据库用户与表空间 1、查询数据库文件位置 2、创建表空间 3、创建用户 4、设置权限 三、导出数据库DMP …...
elementui table子级tree懒加载bug
1. 删除子级刷新列表子级依然显示 2.更新状态子级列表未刷新 3.编辑子级后刷新页面显示状态未变更 el-table 树表格load源码 首先,load可以执行,但是只剩一个子节点就有问题,那么就直接可以定位bug在load方法里: 文件路径&am…...
AI与低代码技术融合:如何加速企业智能化应用开发?
引言 随着全球数字化转型的步伐加快,企业在智能化应用开发方面面临着前所未有的挑战和机遇。传统的软件开发方式往往需要大量的技术人员、时间和资源,而在瞬息万变的市场环境中,这种模式显得效率低下且难以满足企业快速迭代和创新的需求。 与…...
【C#】新建窗体文件,Form、UserControl
从用途、功能性和架构方面进行描述。 1. 继承自 Form 的窗体(通常是窗口): 在 C# 中,Form 是用于创建应用程序的主窗口或对话框窗口的类。当您继承自 Form 时,您创建的是一个完整的窗口,可以显示内容、与…...
ansible学习笔记之02command模块与shell模块
目录 1、概述 2、模块介绍 2.1 command模块 2.2 shell模块 2.3 小结 3、实验 3.1 测试ls命令 3.2 测试环境变量 3.3 测试操作符">" 1、概述 本文介绍ansible的command模块与shell模块,并通过实验比对两个模块的异同。 2、模块介绍 2.1…...
在Docker中部署禅道,亲测可用
1、确保centos中已安装docker docker -v 2、启动docker systemctl start docker 3、可设置docker开机启动 systemctl enable docker.service 4、获取最新版禅道开源版镜像 docker pull idoop/zentao 5、运行镜像生成禅道容器【创建 /data/www /data/data 目录】 doc…...
C++(十二)
前言: 本文将进一步讲解C中,条件判断语句以及它是如何运行的以及内部逻辑。 一,if-else,if-else语句。 在if语句中,只能判断两个条件的变量,若想实现判断两个以上条件的变体,就需要使用if-else,if-else语…...
【数学建模】线性规划问题及Matlab求解
问题一 题目: 求解下列线性规划问题 解答: 先将题目中求最大值转化为求最小值,则有 我们就可以得到系数列向量: 我们对问题中所给出的不等式约束进行标准化则得到了 就有不等式约束条件下的变系数矩阵和常系数矩阵分别为: 等式…...
【JavaWeb后端学习笔记】Spring全局异常处理器
在程序运行时,不可避免的会出现异常。在三层开发架构中,当Mapper层出现异常、如果不进行处理会抛给Service层,如果Service层也不处理则会抛给Controller层,通常Controller层有许多接口,如果对每个接口单独处理异常&…...
PT8M2102 触控型 8Bit MCU
1 产品概述 ● PT8M2102 是一款基于 RISC 内核的8位 MTP 单片机,内部集成了电容式触摸感应模块、TIMER,PWM、LVR、LVD、WDT等外设,其主要用作触摸按键开关,广泛适用于触控调光、电子玩具、消费电子、家用电器等领域,具…...
4. React 性能优化技巧:如何让你的应用更快
在构建大型应用时,性能优化是一个非常重要的话题。React 提供了许多优化工具,帮助我们提高应用的渲染速度和响应能力。本文将分享一些常见的 React 性能优化技巧。 4.1. 使用 React.memo 缓存组件 当组件的 props 没有变化时,React 默认不会…...
pytest中使用conftest做测试前置和参数化
pytest中比较高阶的应用是,使用conftest去做测试前置工作、测试收尾工作和参数化。conftest是pytest的一个组件,用于配置测试环境和参数。通过conftest, 可以创建一个可复用的测试配置文件,以便在多个测试模块之间共享配置信息。即࿰…...
Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...
佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...
给网站添加live2d看板娘
给网站添加live2d看板娘 参考文献: stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下,文章也主…...
Docker拉取MySQL后数据库连接失败的解决方案
在使用Docker部署MySQL时,拉取并启动容器后,有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致,包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因,并提供解决方案。 一、确认MySQL容器的运行状态 …...
LLaMA-Factory 微调 Qwen2-VL 进行人脸情感识别(二)
在上一篇文章中,我们详细介绍了如何使用LLaMA-Factory框架对Qwen2-VL大模型进行微调,以实现人脸情感识别的功能。本篇文章将聚焦于微调完成后,如何调用这个模型进行人脸情感识别的具体代码实现,包括详细的步骤和注释。 模型调用步骤 环境准备:确保安装了必要的Python库。…...
保姆级【快数学会Android端“动画“】+ 实现补间动画和逐帧动画!!!
目录 补间动画 1.创建资源文件夹 2.设置文件夹类型 3.创建.xml文件 4.样式设计 5.动画设置 6.动画的实现 内容拓展 7.在原基础上继续添加.xml文件 8.xml代码编写 (1)rotate_anim (2)scale_anim (3)translate_anim 9.MainActivity.java代码汇总 10.效果展示 逐帧…...
运行vue项目报错 errors and 0 warnings potentially fixable with the `--fix` option.
报错 找到package.json文件 找到这个修改成 "lint": "eslint --fix --ext .js,.vue src" 为elsint有配置结尾换行符,最后运行:npm run lint --fix...
篇章一 论坛系统——前置知识
目录 1.软件开发 1.1 软件的生命周期 1.2 面向对象 1.3 CS、BS架构 1.CS架构编辑 2.BS架构 1.4 软件需求 1.需求分类 2.需求获取 1.5 需求分析 1. 工作内容 1.6 面向对象分析 1.OOA的任务 2.统一建模语言UML 3. 用例模型 3.1 用例图的元素 3.2 建立用例模型 …...
