【深度学习】注意力机制介绍,了解什么是注意力计算规则以及常见的计算规则,知道注意力机制的工作流程

news2025/1/12 6:46:45

1注意力机制介绍

1.1 注意力概念

  • 我们观察事物时,之所以能够快速判断一种事物(当然允许判断是错误的), 是因为我们大脑能够很快把注意力放在事物最具有辨识度的部分从而作出判断,而并非是从头到尾的观察一遍事物后,才能有判断结果. 正是基于这样的理论,就产生了注意力机制.

1.2 注意力计算规则 

  • 它需要三个指定的输入Q(query), K(key), V(value), 然后通过计算公式得到注意力的结果, 这个结果代表query在key和value作用下的注意力表示. 当输入的Q=K=V时, 称作自注意力计算规则.

  • Q, K, V的比喻解释:

    假如我们有一个问题: 给出一段文本,使用一些关键词对它进行描述!
    为了方便统一正确答案,这道题可能预先已经给大家写出了一些关键词作为提示.其中这些给出的提示就可以看作是key, 
    而整个的文本信息就相当于是query,value的含义则更抽象,可以比作是你看到这段文本信息后,脑子里浮现的答案信息,
    这里我们又假设大家最开始都不是很聪明,第一次看到这段文本后脑子里基本上浮现的信息就只有提示这些信息,
    因此key与value基本是相同的,但是随着我们对这个问题的深入理解,通过我们的思考脑子里想起来的东西原来越多,
    并且能够开始对我们query也就是这段文本,提取关键信息进行表示.  这就是注意力作用的过程, 通过这个过程,
    我们最终脑子里的value发生了变化,
    根据提示key生成了query的关键词表示方法,也就是另外一种特征表示方法.
    
    刚刚我们说到key和value一般情况下默认是相同,与query是不同的,这种是我们一般的注意力输入形式,
    但有一种特殊情况,就是我们query与key和value相同,这种情况我们称为自注意力机制,就如同我们的刚刚的例子, 
    使用一般注意力机制,是使用不同于给定文本的关键词表示它. 而自注意力机制,
    需要用给定文本自身来表达自己,也就是说你需要从给定文本中抽取关键词来表述它, 相当于对文本自身的一次特征提取.
    

    1.3 常见的注意力计算规则

  • 将Q,K进行纵轴拼接, 做一次线性变化, 再使用softmax处理获得结果最后与V做张量乘法.

  • 𝐴𝑡𝑡𝑒𝑛𝑡𝑖𝑜𝑛(𝑄,𝐾,𝑉)=𝑆𝑜𝑓𝑡𝑚𝑎𝑥(𝐿𝑖𝑛𝑒𝑎𝑟([𝑄,𝐾]))⋅𝑉

  • 将Q,K进行纵轴拼接, 做一次线性变化后再使用tanh函数激活, 然后再进行内部求和, 最后使用softmax处理获得结果再与V做张量乘法.

  • 𝐴𝑡𝑡𝑒𝑛𝑡𝑖𝑜𝑛(𝑄,𝐾,𝑉)=𝑆𝑜𝑓𝑡𝑚𝑎𝑥(𝑠𝑢𝑚(𝑡𝑎𝑛ℎ(𝐿𝑖𝑛𝑒𝑎𝑟([𝑄,𝐾]))))⋅𝑉

  • 将Q与K的转置做点积运算, 然后除以一个缩放系数, 再使用softmax处理获得结果最后与V做张量乘法.

  • 说明:当注意力权重矩阵和V都是三维张量且第一维代表为batch条数时, 则做bmm运算.bmm是一种特殊的张量乘法运算.

  • bmm运算演示:

# 如果参数1形状是(b × n × m), 参数2形状是(b × m × p), 则输出为(b × n × p)
>>> input = torch.randn(10, 3, 4)
>>> mat2 = torch.randn(10, 4, 5)
>>> res = torch.bmm(input, mat2)
>>> res.size()
torch.Size([10, 3, 5])

2 什么是注意力机制

  • 注意力机制是注意力计算规则能够应用的深度学习网络的载体, 同时包括一些必要的全连接层以及相关张量处理, 使其与应用网络融为一体. 使用自注意力计算规则的注意力机制称为自注意力机制.
  • 说明: NLP领域中, 当前的注意力机制大多数应用于seq2seq架构, 即编码器和解码器模型.

3 注意力机制的作用 

  • 在解码器端的注意力机制: 能够根据模型目标有效的聚焦编码器的输出结果, 当其作为解码器的输入时提升效果. 改善以往编码器输出是单一定长张量, 无法存储过多信息的情况.
  • 在编码器端的注意力机制: 主要解决表征问题, 相当于特征提取过程, 得到输入的注意力表示. 一般使用自注意力(self-attention). 

注意力机制在网络中实现的图形表示:

 

4 注意力机制实现步骤 

4.1 步骤

  • 第一步: 根据注意力计算规则, 对Q,K,V进行相应的计算.
  • 第二步: 根据第一步采用的计算方法, 如果是拼接方法,则需要将Q与第二步的计算结果再进行拼接, 如果是转置点积, 一般是自注意力, Q与V相同, 则不需要进行与Q的拼接.
  • 第三步: 最后为了使整个attention机制按照指定尺寸输出, 使用线性层作用在第二步的结果上做一个线性变换, 得到最终对Q的注意力表示.

4.2 代码实现

  • 常见注意力机制的代码分析:
    import torch
    import torch.nn as nn
    import torch.nn.functional as F
    
    class Attn(nn.Module):
        def __init__(self, query_size, key_size, value_size1, value_size2, output_size):
            """初始化函数中的参数有5个, query_size代表query的最后一维大小
               key_size代表key的最后一维大小, value_size1代表value的导数第二维大小, 
               value = (1, value_size1, value_size2)
               value_size2代表value的倒数第一维大小, output_size输出的最后一维大小"""
            super(Attn, self).__init__()
            # 将以下参数传入类中
            self.query_size = query_size
            self.key_size = key_size
            self.value_size1 = value_size1
            self.value_size2 = value_size2
            self.output_size = output_size
    
            # 初始化注意力机制实现第一步中需要的线性层.
            self.attn = nn.Linear(self.query_size + self.key_size, value_size1)
    
            # 初始化注意力机制实现第三步中需要的线性层.
            self.attn_combine = nn.Linear(self.query_size + value_size2, output_size)
    
    
        def forward(self, Q, K, V):
            """forward函数的输入参数有三个, 分别是Q, K, V, 根据模型训练常识, 输入给Attion机制的
               张量一般情况都是三维张量, 因此这里也假设Q, K, V都是三维张量"""
    
            # 第一步, 按照计算规则进行计算, 
            # 我们采用常见的第一种计算规则
            # 将Q,K进行纵轴拼接, 做一次线性变化, 最后使用softmax处理获得结果
            attn_weights = F.softmax(
                self.attn(torch.cat((Q[0], K[0]), 1)), dim=1)
    
            # 然后进行第一步的后半部分, 将得到的权重矩阵与V做矩阵乘法计算, 
            # 当二者都是三维张量且第一维代表为batch条数时, 则做bmm运算
            attn_applied = torch.bmm(attn_weights.unsqueeze(0), V)
    
            # 之后进行第二步, 通过取[0]是用来降维, 根据第一步采用的计算方法, 
            # 需要将Q与第一步的计算结果再进行拼接
            output = torch.cat((Q[0], attn_applied[0]), 1)
    
            # 最后是第三步, 使用线性层作用在第三步的结果上做一个线性变换并扩展维度,得到输出
            # 因为要保证输出也是三维张量, 因此使用unsqueeze(0)扩展维度
            output = self.attn_combine(output).unsqueeze(0)
            return output, attn_weights

    调用:

    query_size = 32
    key_size = 32
    value_size1 = 32
    value_size2 = 64
    output_size = 64
    attn = Attn(query_size, key_size, value_size1, value_size2, output_size)
    Q = torch.randn(1,1,32)
    K = torch.randn(1,1,32)
    V = torch.randn(1,32,64)
    out = attn(Q, K ,V)
    print(out[0])
    print(out[1])

    输出结果:

    tensor([[[ 0.4477, -0.0500, -0.2277, -0.3168, -0.4096, -0.5982,  0.1548,
              -0.0771, -0.0951,  0.1833,  0.3128,  0.1260,  0.4420,  0.0495,
              -0.7774, -0.0995,  0.2629,  0.4957,  1.0922,  0.1428,  0.3024,
              -0.2646, -0.0265,  0.0632,  0.3951,  0.1583,  0.1130,  0.5500,
              -0.1887, -0.2816, -0.3800, -0.5741,  0.1342,  0.0244, -0.2217,
               0.1544,  0.1865, -0.2019,  0.4090, -0.4762,  0.3677, -0.2553,
              -0.5199,  0.2290, -0.4407,  0.0663, -0.0182, -0.2168,  0.0913,
              -0.2340,  0.1924, -0.3687,  0.1508,  0.3618, -0.0113,  0.2864,
              -0.1929, -0.6821,  0.0951,  0.1335,  0.3560, -0.3215,  0.6461,
               0.1532]]], grad_fn=<UnsqueezeBackward0>)
    
    
    tensor([[0.0395, 0.0342, 0.0200, 0.0471, 0.0177, 0.0209, 0.0244, 0.0465, 0.0346,
             0.0378, 0.0282, 0.0214, 0.0135, 0.0419, 0.0926, 0.0123, 0.0177, 0.0187,
             0.0166, 0.0225, 0.0234, 0.0284, 0.0151, 0.0239, 0.0132, 0.0439, 0.0507,
             0.0419, 0.0352, 0.0392, 0.0546, 0.0224]], grad_fn=<SoftmaxBackward>)

 5注意力机制原理

5.1 注意力机制示意图

Attention机制的工作原理并不复杂,我们可以用下面这张图做一个总结

 

5.2 Attention计算过程 

  • 阶段一: query 和 key 进行相似度计算,得到一个query 和 key 相关性的分值
  • 阶段二: 将这个分值进行归一化(softmax),得到一个注意力的分布
  • 阶段三: 使用注意力分布和 value 进行计算,得到一个融合注意力的更好的 value 值

为了更好的说明上面的情况, 我们通过注意力来做一个机器翻译(NMT) 的任务,机器翻译中,我们会使用 seq2seq 的架构,每个时间步从词典里生成一个翻译的结果。就像下面这张图一样.

在没有注意力之前,我们每次都是根据 Encoder 部分的输出结果来进行生成,提出注意力后,就是想在生成翻译结果时并不是看 Encoder 中所有的输出结果,而是先来看看想生成的这部分和哪些单词可能关系会比较大,关系大的我多借鉴些;关系小的,少借鉴些。就是这样一个想法,我们看看该如何操作。

  • 这里为了生成单词,我们把 Decoder 部分输入后得到的向量作为 query;把 Encoder 部分每个单词的向量作为 key。首先我们先把 query 和 每一个单词进行点乘𝑠𝑐𝑜𝑟𝑒=𝑞𝑢𝑒𝑟𝑦⋅𝑘𝑒𝑦,得到相关性的分值;
  • 有了这些分值后,我们对这些分值做一个𝑠𝑜𝑓𝑡𝑚𝑎𝑥 ,得到一个注意力的分布
  • 有了这个注意力,我们就可以用它和 Encoder 的输出值 (value) 进行相乘,得到一个加权求和后的值,这个值就包含注意力的表示,我们用它来预测要生成的词。

 5.3 Attention计算逻辑

当然,Attention 并不是只有这一种计算方式,后来还有很多人找到了各种各样的计算注意力的方法, 比如我们上面介绍的三种计算规则, 但是从本质上,它们都遵循着这个三步走的逻辑:

  • query 和 key 进行相似度计算,得到一个query 和 key 相关性的分值
  • 将这个分值进行归一化(softmax),得到一个注意力的分布
  • 使用注意力分布和 value 进行计算,得到一个融合注意力的更好的 value 值

5.4 有无attention模型对比 

1 无attention机制的模型 

  • 文本处理领域的Encoder-Decoder框架可以这么直观地去理解:可以把它看作适合处理由一个句子(或篇章)生成另外一个句子(或篇章)的通用处理模型。对于句子对,我们的目标是给定输入句子Source,期待通过Encoder-Decoder框架来生成目标句子Target。Source和Target可以是同一种语言,也可以是两种不同的语言。而Source和Target分别由各自的单词序列构成:𝑆𝑜𝑢𝑟𝑐𝑒=〈𝑋1,𝑋2⋯𝑋𝑚〉,𝑇𝑎𝑟𝑔𝑒𝑡=〈𝑦1,𝑦2⋯𝑦𝑛〉

  • encoder顾名思义就是对输入句子Source进行编码,将输入句子通过非线性变换转化为中间语义表示C:𝐶=𝐹(𝑋1,𝑋2⋯𝑋𝑚)

  • 对于解码器Decoder来说,其任务是根据句子Source的中间语义表示C和之前已经生成的历史信息,y_1, y_2…y_i-1来生成i时刻要生成的单词y_i,𝑦𝑖=𝐺(𝐶,𝑦1,𝑦2⋯𝑦𝑖−1)

  • 上述图中展示的Encoder-Decoder框架是没有体现出“注意力模型”的,所以可以把它看作是注意力不集中的分心模型。为什么说它注意力不集中呢?请观察下目标句子Target中每个单词的生成过程如下:𝑦1=𝑓(𝐶),𝑦2=𝑓(𝐶,𝑦1),𝑦3=𝑓(𝐶,𝑦1,𝑦2)

  • 其中f是Decoder的非线性变换函数。从这里可以看出,在生成目标句子的单词时,不论生成哪个单词,它们使用的输入句子Source的语义编码C都是一样的,没有任何区别。

  • 每个yi都依次这么产生,那么看起来就是整个系统根据输入句子Source生成了目标句子Target。如果Source是中文句子,Target是英文句子,那么这就是解决机器翻译问题的Encoder-Decoder框架;如果Source是一篇文章,Target是概括性的几句描述语句,那么这是文本摘要的Encoder-Decoder框架;如果Source是一句问句,Target是一句回答,那么这是问答系统或者对话机器人的Encoder-Decoder框架。由此可见,在文本处理领域,Encoder-Decoder的应用领域相当广泛。

  • 问题点是: 语义编码C是由句子Source的每个单词经过Encoder 编码产生的,这意味着不论是生成哪个单词,还是,其实句子Source中任意单词对生成某个目标单词yi来说影响力都是相同的,这是为何说这个模型没有体现出注意力的缘由。这类似于人类看到眼前的画面,但是眼中却没有注意焦点一样.

2 有attention机制的模型 
  • 如果拿机器翻译来解释这个分心模型的Encoder-Decoder框架更好理解,比如输入的是英文句子:Tom chase Jerry,Encoder-Decoder框架逐步生成中文单词:“汤姆”,“追逐”,“杰瑞”。在翻译“杰瑞”这个中文单词的时候,分心模型里面的每个英文单词对于翻译目标单词“杰瑞”贡献是相同的,很明显这里不太合理,显然“Jerry”对于翻译成“杰瑞”更重要,但是分心模型是无法体现这一点的,这就是为何说它没有引入注意力的原因。

  • 没有引入注意力的模型在输入句子比较短的时候问题不大,但是如果输入句子比较长,此时所有语义完全通过一个中间语义向量来表示,单词自身的信息已经消失,可想而知会丢失很多细节信息,这也是为何要引入注意力模型的重要原因。

  • 上面的例子中,如果引入Attention模型的话,应该在翻译“杰瑞”的时候,体现出英文单词对于翻译当前中文单词不同的影响程度,比如给出类似下面一个概率分布值:(Tom,0.3)(Chase,0.2) (Jerry,0.5).每个英文单词的概率代表了翻译当前单词“杰瑞”时,注意力分配模型分配给不同英文单词的注意力大小。这对于正确翻译目标语单词肯定是有帮助的,因为引入了新的信息。

  • 同理,目标句子中的每个单词都应该学会其对应的源语句子中单词的注意力分配概率信息。这意味着在生成每个单词的时候,原先都是相同的中间语义表示C会被替换成根据当前生成单词而不断变化的。理解Attention模型的关键就是这里,即由固定的中间语义表示C换成了根据当前输出单词来调整成加入注意力模型的变化的。增加了注意力模型的Encoder-Decoder框架理解起来如下图所示:

  • 即生成目标句子单词的过程成了下面的形式:𝑦1=𝑓1(𝐶1),𝑦2=𝑓1(𝐶2,𝑦1),𝑦3=𝑓1(𝐶3,𝑦1,𝑦2)

  • 而每个Ci可能对应着不同的源语句子单词的注意力分配概率分布,比如对于上面的英汉翻译来说,其对应的信息可能如下:𝐶𝑇𝑜𝑚=𝑔(0.6∗𝑓2(𝑇𝑜𝑚),0.2∗𝑓2(𝐶ℎ𝑎𝑠𝑒),0.2∗𝑓2(𝐽𝑒𝑟𝑟𝑦)),𝐶𝐶ℎ𝑎𝑠𝑒=𝑔(0.2∗𝑓2(𝑇𝑜𝑚),0.7∗𝑓2(𝐶ℎ𝑎𝑠𝑒),0.1∗𝑓2(𝐽𝑒𝑟𝑟𝑦)),𝐶𝐽𝑒𝑟𝑟𝑦=𝑔(0.3∗𝑓2(𝑇𝑜𝑚),0.2∗𝑓2(𝐶ℎ𝑎𝑠𝑒),0.5∗𝑓2(𝐽𝑒𝑟𝑟𝑦))

  • f2函数代表Encoder对输入英文单词的某种变换函数,比如如果Encoder是用的RNN模型的话,这个f2函数的结果往往是某个时刻输入后隐层节点的状态值;g代表Encoder根据单词的中间表示合成整个句子中间语义表示的变换函数,一般的做法中,g函数就是对构成元素加权求和,即下列公式

 

  • 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函数本质上就是加权求和函数, 如果形象表示的话, 翻译中文单词'汤姆'的时候, 数学公式对应的中间语义表示Ci的形成过程类似下图:

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

动物检测系统源码分享

动物检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vision …

el-tree父子不互相关联时,手动实现全选、反选、子级全选、清空功能

el-tree父子不互相关联时&#xff0c;手动实现全选、反选、子级全选、清空功能 1、功能实现图示 2、实现思路 当属性check-strictly为true时&#xff0c;父子节点不互相关联&#xff0c;如果需要全部选中或选择某一节点下的全部节点就必须手动选择每个节点&#xff0c;十分麻…

速卖通在哪些国家受欢迎?速卖通怎么选品?选品方式有哪些?

速卖通&#xff08;AliExpress&#xff09;是阿里巴巴集团旗下的一家跨境电商平台&#xff0c;也是全球第三大英文在线购物网站&#xff0c;为全球消费者提供了一个方便、多样化的购物平台&#xff0c;在中国跨境出口B2C平台中占据领先地位。相关数据统计&#xff0c;今年上半年…

砥砺前行 智护健康:衢州骨伤科医院建院十五周年庆典圆满启动

2024年9月12日&#xff0c;衢州骨伤科医院建院十五周年庆典圆满启动。作为邦尔骨科医院集团的第二家医院&#xff0c;衢州骨伤科医院创办于2009年&#xff0c;建院十五年来坚持集团宗旨与愿景&#xff0c;致力于将骨科领先技术和优质服务带给老百姓&#xff0c;现已成为区域领先…

input输入框之间有间隙的解决方案

1&#xff0c;浮动 浮动是处理元素排列方式的方法之一&#xff0c;使用浮动&#xff08;float&#xff09;可以帮助更好的排列元素位置 <p>源代码</p> <input type"text" name"name1" /> <input type"text" name"na…

JAVA宠物界的Uber同城遛狗兼职系统小程序源码

宠物界的Uber同城遛狗兼职系统&#xff0c;让爱宠自由奔跑&#xff01; &#x1f43e; 开篇&#xff1a;解锁宠物新生活方式 在这个快节奏的城市里&#xff0c;我们的爱宠是否也常常因为主人的忙碌而错失户外的欢乐时光&#xff1f;别担心&#xff0c;宠物界的“Uber”——同…

ArgoWorkflow教程(四)---Workflow 日志归档

上一篇我们分析了argo-workflow 中的 artifact&#xff0c;包括 artifact-repository 配置以及 Workflow 中如何使用 artifact。本篇主要分析流水线 GC 以及归档,防止无限占用集群中 etcd 的空间。 **【ArgoWorkflow 系列】**持续更新中&#xff0c;搜索公众号【探索云原生】订…

nlohmann::json中有中文时调用dump转string抛出异常的问题

问题描述 Winodows下C开发想使用一个json库&#xff0c;使用的nlohmann::json&#xff0c;但是遇到json中使用中文时&#xff0c;转成string&#xff0c;会抛出异常。 nlohmann::json contentJson;contentJson["chinese"] "哈哈哈";std::string test con…

从卫星和飞机等不同传感器方面由QGIS 遥感分析

在地理信息科学 (GIS) 中,遥感是指从远处获取有关地球表面特征信息的行为。遥感数据是从许多不同的平台获取而来,包括卫星、飞机和具有许多不同传感器的固定仪器,包括光谱图像(相机)和激光雷达。最常见的遥感数据形式是卫星和航空图像。 为了充分实现这些照片的价值,需要…

搜狗翻译+3款工具安利,让语言不再是加班路上的绊脚石

现在不管是开跨国会议、搞国际项目合作&#xff0c;还是平时发个邮件啥的&#xff0c;语言问题常常是让人加班的主要由头。不过还算幸运&#xff0c;随着科技不断发展&#xff0c;出现了一堆既高效又智能的翻译工具。这些工具老厉害了&#xff0c;不但能大大提升我们的工作效率…

线程--线程同步

这里写目录标题 同步概念线程同步概念数据混乱原因 互斥量原理锁的注意事项1、cpu时间轮片2、建议锁总结 使用锁来管理线程同步问题产生主要函数init、destorylock、unlock代码注意事项 条件变量二级目录二级目录二级目录 信号量二级目录二级目录二级目录 一级目录二级目录二级…

算法:数字化系统的智慧核心

在当今快速发展的数字化时代&#xff0c;算法在数字化系统中扮演着至关重要的角色。从数字孪生系统到物联网应用&#xff0c;算法不仅是技术进步的推动力&#xff0c;更是实现智能化、自动化的核心。本文将探讨数字化系统中算法的重要性&#xff0c;以及它们是如何被实现和集成…

spring容器创建bean过程中使用到的几个factory

文章目录 前述BeanFactoryFactoryBeanObjectFactory 前述 spring我们可以理解为一个帮我们管理bean的容器&#xff0c;使用spring框架之前创建bean都是通过new的方式&#xff0c;使用spring框架之后&#xff0c; 我们只需要告诉spring框架我们有那些bean&#xff0c;它会帮我们…

Linux:命令行参数

目录 一、命令行参数是什么&#xff1f; 二、命令行参数作用 三、命令行参数如何传递给main函数&#xff1f; 一、命令行参数是什么&#xff1f; C语言中的main函数&#xff0c;我们发现既可以带参数&#xff0c;也可以不带参数。带参数的main函数如下&#xff1a; 参数为一…

Matplotlib - Statistical Distribution作图

1. 前言 在数据分析和统计学中&#xff0c;绘制统计分布图是非常重要的&#xff0c;因为它帮助我们直观地理解数据的特性&#xff0c;并为进一步的分析提供基础。统计分布图能够揭示数据集的结构、趋势、集中趋势和离散程度等信息&#xff0c;从而使我们更容易做出合理的假设、…

监控系统添加vcenter上的esxi主机

监控系统的软件选择&#xff1a; 监控系统要求 快速搭建 能快捷地添加vcenter上的主机&#xff08;esxi&#xff09; 能实现动态添加主机监控 可供选择的监控软件 Prometheus vmware_exporter添加 vcenter及esxi监控&#xff0c;报奇怪的错误&#xff0c;解决时间比较长&a…

高阶数据结构之哈希表基础讲解与模拟实现

程序猿的读书历程&#xff1a;x语言入门—>x语言应用实践—>x语言高阶编程—>x语言的科学与艺术—>编程之美—>编程之道—>编程之禅—>颈椎病康复指南。 前言&#xff1a; 哈希表&#xff08;Hash Table&#xff09;是一种高效的键值对存储数据结构&…

C++(进阶) ─── 继承

目录 1.继承的概念及定义 1.1继承的概念 1.2 继承定义 1.2.1定义格式 1.2.2继承关系和访问限定符 1.2.3继承基类成员访问方式的变化 2.基类和派生类对象赋值转换 3.继承中的作用域 4.派生类的默认成员函数 5.继承与友元 6. 继承与静态成员 7.复杂的菱形继承及菱形虚拟继承 8.继…

ARCGIS PRO DSK MapTool

MapTool用于自定义地图操作工具&#xff0c;使用户能够在ArcGIS Pro中执行特定的地图交互操作。添加 打开MapTool1.vb文件&#xff0c;可以看到系统已经放出MapTool1类&#xff1a; Public Sub New()将 IsSketchTool 设置为 true 以使此属性生效IsSketchTool TrueSketchTyp…

秋招测评为什么有行测题型?有没有训练题库?

为什么有行测题型&#xff0c;那这就得看看行测题型的作用了。 1、行测题可以比较全面评估应聘者的基本素质&#xff0c;包括数学能力、语言能力、逻辑思维能力等。这些能力是从事各类职业所必需的基本能力&#xff0c;对于判断应聘者的学习潜力和工作效率具有重要意义。 2、…