【Transformer系列】深入浅出理解Attention和Self-Attention机制

news2025/1/19 23:21:03

一、参考资料

课件:10_Transformer_1.pdf
视频:Transformer模型(1/2): 剥离RNN,保留Attention

二、Attention without RNN

Attention模型可以看到全局的信息
本章节以 Seq2Seq( (encoder + decoder)) 模型为例,介绍Attention机制。

1. Keys&Values&Query定义

  • Encoder’s inputs are vectors x 1 , x 2 , ⋯   , x m \mathbf{x}_1,\mathbf{x}_2,\cdots,\mathbf{x}_m x1,x2,,xm.

  • Decoder’s inputs are vectors x 1 ′ , x 2 ′ , ⋯   , x t ′ \color{red}{\mathbf{x}_1^{\prime}},\color{red}{\mathbf{x}_2^{\prime}},\cdots,\color{red}{\mathbf{x}_t^{\prime}} x1,x2,,xt.
    在这里插入图片描述

  • K e y s \color{red}{Keys} Keys and V a l u e s \color {red}{Values} Values are based on encoder’s inputs x 1 , x 2 , ⋯   , x m \mathbf{x}_1,\mathbf{x}_2,\cdots,\mathbf{x}_m x1,x2,,xm.

  • Q u e r i e s \color {red}{Queries} Queries are based on decoder’s inputs x 1 ′ , x 2 ′ , ⋯   , x t ′ \color{red}{\mathbf{x}_1^{\prime}},\color{red}{\mathbf{x}_2^{\prime}},\cdots,\color{red}{\mathbf{x}_t^{\prime}} x1,x2,,xt.

  • K e y s \color{red}{Keys} Keys k : i = W K x i \mathbf{k}_{:i}=\mathbf{W}_K\mathbf{x}_i k:i=WKxi.

  • V a l u e s \color {red}{Values} Values v : i = W V x i \mathbf{v}_{:i}=\mathbf{W}_V\mathbf{x}_i v:i=WVxi.

  • Q u e r y \color {red}{Query} Query q : j = W Q x j ′ {\mathbf{q}_{:j}=\mathbf{W}_Q}{\mathbf{x}_j^{\prime}} q:j=WQxj.
    在这里插入图片描述
    在这里插入图片描述

2. Attention机制的原理

2.1 Compute weights

α : 1 = S o f t m a x ( K T q : 1 ) ∈ R m {\alpha_{:1}=\mathrm{Softmax}(\mathbb{K}^T{q_{:1}})\in\mathbb{R}^m} α:1=Softmax(KTq:1)Rm
在这里插入图片描述

α : 2 = S o f t m a x ( K T q : 2 ) ∈ R m {\alpha_{:2}=\mathrm{Softmax}(\mathbb{K}^T{q_{:2}})\in\mathbb{R}^m} α:2=Softmax(KTq:2)Rm
在这里插入图片描述

2.2 Compute context vector

c : 1 = α : 1 v : 1 + ⋯ + α : m v : m = V α : 1 {\mathbf{c}_{:1}=\alpha_{:1}\mathbf{v}_{:1}+\cdots+\alpha_{:m}\mathbf{v}_{:m}=\mathbf{V}\mathbf{\alpha}_{:1}} c:1=α:1v:1++α:mv:m=Vα:1
在这里插入图片描述

c : 2 = α 12 v : 1 + ⋯ + α : m v : m = V α : 2 {c_{:2}=\alpha_{12}v_{:1}+\cdots+\alpha_{:m}v_{:m}=V\alpha_{:2}} c:2=α12v:1++α:mv:m=Vα:2
在这里插入图片描述

c : j = α 1 j v : 1 + ⋯ + α m j v : m = V α : j {\mathrm{c}_{:j}}=\alpha_{1j}\mathbf{v}_{:1}+\cdots+\alpha_{mj}\mathbf{v}_{:m}=\mathbf{V}\mathbf{\alpha}_{:j} c:j=α1jv:1++αmjv:m=Vα:j
在这里插入图片描述

2.3 Output of attention layer

  • C = [ c : 1 , c : 2 , c : 3 , ⋯   , c : t ] {C=[c_{:1},c_{:2},c_{:3},\cdots,c_{:t}]} C=[c:1,c:2,c:3,,c:t].

  • c : j = V ⋅ S o f t m a x ( K T q : j ) {\mathrm{c}_{:j}=\mathrm{V}\cdot\mathrm{Softmax}(\mathrm{K}^T {\mathbf{q}_{:j}})} c:j=VSoftmax(KTq:j).

  • c : j \mathrm{c}_{:j} c:j is a function of X j ′ \mathbf{X}_j^{\prime} Xj and [ x 1 , ⋯   , x m ] [\mathbf{x}_1,\cdots,\mathbf{x}_m] [x1,,xm].
    在这里插入图片描述

2.4 Attention Layer

  • Attention layer: C = A t t n ( X , X ′ ) \mathrm{C}=\mathrm{Attn}(\mathbf{X},\mathbf{X}^{\prime}) C=Attn(X,X).
  • Encoder’s inputs: X = [ x 1 , x 2 , ⋯   , x m ] \mathbf{X}=[\mathbf{x}_1,\mathbf{x}_2,\cdots,\mathbf{x}_m] X=[x1,x2,,xm].
  • Decoder’s inputs: X ′ = [ x 1 ′ , x 2 ′ , ⋯   , x t ′ ] \mathbf{X}^{\prime}=[x_1^{\prime},x_2^{\prime},\cdots,x_t^{\prime}] X=[x1,x2,,xt].
  • Parameters: W Q ,   W K ,   W V \mathbf{W}_Q\textbf{, W}_K\textbf{, W}_V WQ, WK, WV.
    在这里插入图片描述

2.5 Machine Translation

本章节介绍Attention机制在Machine Translation机器翻译任务中的应用。将English翻译成German。
在这里插入图片描述
在这里插入图片描述

3. Attention最新研究

比标准Attention快197倍!Meta推出多头注意力机制“九头蛇”
Hydra Attention: Efficient Attention with Many Heads

三、Self-Attention without RNN

The Illustrated Transformer

Attention机制详解(二)——Self-Attention与Transformer

1. 引言

在介绍Self-Attention之前,先举了一个语义处理的例子:

“The animal didn’t cross the street because it was too tired.”

我们人很容易理解,后面的it是指animal,但是要怎么让机器能够把it和animal关联起来呢?
在这里插入图片描述

Self-attention就是在这种需求下产生的,如上图所示,我们应当有一个结构能够表达每个单词和其他每个单词的关系

2. Self-Attention机制的原理

2.0 Keys&Values&Query定义

  • 输入为 x 1 , x 2 , x 3 , . . , x m \color{red}{x_1, x_2, x_3,..,x_m} x1,x2,x3,..,xm

  • Q u e r y \color{red}{Query} Query: q : i = W Q x i \mathbf{q}_{:i}=\mathbf{W}_Q\mathbf{x}_i q:i=WQxi;

  • K e y \color{red}{Key} Key: k : i = W K x i \mathbf{k}_{:i}=\mathbf{W}_K\mathbf{x}_i k:i=WKxi;

  • V a l u e \color{red}{Value} Value: v : i = W V x i \mathbf{v}_{:i}=\mathbf{W}_V\mathbf{x}_i v:i=WVxi;
    在这里插入图片描述

2.1 Compute Weights

α : j = S o f t m a x ( K T q : j ) ∈ R m \alpha_{:j}=\mathrm{Softmax}(\mathbb{K}^T{q}_{:j})\in\mathbb{R}^m α:j=Softmax(KTq:j)Rm
在这里插入图片描述

α : 2 = S o f t m a x ( K T q : 2 ) ∈ R m \alpha_{:2}=\mathrm{Softmax}(\mathbb{K}^T\mathbf{q}_{:2})\in\mathbb{R}^m α:2=Softmax(KTq:2)Rm
在这里插入图片描述

α : j = S o f t m a x ( K T q : j ) ∈ R m \alpha_{:j}=\mathrm{Softmax}(\mathbb{K}^T\mathbf{q}_{:j})\in\mathbb{R}^m α:j=Softmax(KTq:j)Rm
在这里插入图片描述

2.2 Compute Context vector

c : 1 = α 11 v : 1 + ⋯ + α m 1 v : m = V α : 1 \mathbf{c}_{:1}=\alpha_{11}\mathbf{v}_{:1}+\cdots+\alpha_{m1}\mathbf{v}_{:m}=\mathbf{V}\mathbf{\alpha}_{:1} c:1=α11v:1++αm1v:m=Vα:1
在这里插入图片描述

c : 2 = α 12 v : 1 + ⋯ + α m 2 v : m = V α : 2 c_{:2}=\alpha_{12}v_{:1}+\cdots+\alpha_{m2}v_{:m}=V\alpha_{:2} c:2=α12v:1++αm2v:m=Vα:2
在这里插入图片描述

c : j = α 1 j v : 1 + ⋯ + α m j v : m = V α : j \mathrm{c}_{:j}=\alpha_{1j}\mathrm{v}_{:1}+\cdots+\alpha_{mj}\mathrm{v}_{:m}=\mathrm{V}\alpha_{:j} c:j=α1jv:1++αmjv:m=Vα:j
在这里插入图片描述

2.3 Output of self-attention layer

  • c : j = V ⋅ S o f t m a x ( K T q : j ) \mathrm{c}_{:j}=\mathrm{V}\cdot\mathrm{Softmax}(\mathbb{K}^T\mathbf{q}_{:j}) c:j=VSoftmax(KTq:j).
  • c : j \mathrm{c}_{:j} c:j is a function of all the 𝑚 vectors x 1 , ⋯   , X m \mathbf{x}_1,\cdots,\mathbf{X}_m x1,,Xm.
    在这里插入图片描述

2.4 Self-Attention Layer

  • Self-attention layer: C = A t t n ( X , X ) \mathrm{C}=\mathrm{Attn}(\mathbf{X},\mathbf{X}) C=Attn(X,X).
  • Inputs: X = [ x 1 , x 2 , ⋯   , x m ] \mathbf{X}=[\mathbf{x}_1,\mathbf{x}_2,\cdots,\mathbf{x}_m] X=[x1,x2,,xm].
  • Parameters: W Q ,   W K ,   W V \mathbf{W}_Q\textbf{, W}_K\textbf{, W}_V WQ, WK, WV.

在这里插入图片描述

3. Self-Attention的通俗理解

Self-Attention机制,最先在NLP中提出,其核心是利用文本中的其他词来增强目标词特征的表征能力,从而得到一个聚焦重点的句子特征。

如果看代码就会发现,QKV仅仅是对X做了三次线性变换(三个不同的全连接层),然后得到了QKV三个X变换之后的输出。它们三个在计算的时候,任意指定一个为QKV都可以(当然,指定后就不能变了)。得到QKV之后, s o f t m a x ( Q K T d k ) V softmax(\frac{QK^{T}}{\sqrt{d_{k}}})V softmax(dk QKT)V 才是真正的计算注意力的过程。所谓QKV,不过是为了引入可训练的参数,同时对X进行特征空间变换。所以,我们关心得到的三个全连接层的参数矩阵就好了,不用给QKV多么直观的解释,QKV仅仅是线性变换

4. Self-Attention的计算过程

4.1 主要步骤

对于self-attention来说,Q(Query)、K(Key)、 V(Value)三个矩阵均来自同一输入。
在这里插入图片描述

计算Thinking的self-attention(自注意力),主要步骤有:

  1. 首先计算Q向量与K向量之间的点乘;
  2. 然后为了防止其结果过大,会除以一个尺度标度(缩放因子) d k \sqrt{d_{k}} dk ,其中 d k d_{k} dk 为一个query和key向量的维度;
  3. 再利用Softmax操作其结果归一化为概率分布(注意力向量)。比如,[0.88, 0.12]这个向量的意思是,要解释Thinking这个词在这个句子中的意思,应当取0.88份Thinking原本的意思,再取0.12份Machine原本的意思,这样加权就是Thinking在这个句子中的意思;
  4. 然后乘以V向量,得到加权向量(权重求和的表示);

self-attention操作可以表示为:
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{QK^{T}}{\sqrt{d_{k}}})V Attention(Q,K,V)=softmax(dk QKT)V

4.2 举例说明

假如我们要翻译一个词组Thinking Machines,其中Thinking输入的Embedding vector用 X 1 X_1 X1 表示,Machines的Embedding vector用 X 2 X_2 X2 表示。在CV领域,Thinking和Machine可以理解为图片被切分的两个patch
在这里插入图片描述

当我们处理Thinking这个词时,我们需要计算句子中所有词与它的Attention Score。简单理解,就是将当前词当作搜索的query,去和句子中所有词(包含该词本身)的key去匹配,看看相关度有多高。 W Q W^Q WQ 矩阵是 X 1 X_1 X1 的权重矩阵, q 1 = X 1 ∗ W Q q_1 = X1 * W^Q q1=X1WQ,所以我们用 q 1 q_1 q1 代表 Thinking 对应的 query vector, k 1 k_1 k1 k 2 k_2 k2 分别代表 Thinking以及Machines对应的 key vector,则计算 Thinking 的 Attention Score的时候需要计算 q 1 q_1 q1 k 1 , k 2 k_1,k_2 k1,k2 的点乘,同理,我们计算Machines 的 Attention Score的时候需要计算 q 2 q_2 q2 k 1 , k 2 k_1,k_2 k1,k2 的点乘。如下图所示,我们分别得到 q 1 q_1 q1 k 1 , k 2 k_1,k_2 k1,k2 的点乘积,然后进行尺度缩放,再进行softmax归一化。
在这里插入图片描述

虽然,当前单词与其自身的Attention Score一般最大,其他单词根据与当前单词重要程度有相应的Attention Score。然后我们再用这些Attention Score与V向量相乘,得到加权的向量。最后图中Sum之后的结果所表达的就是每个单词在这个句子当中的意思。
在这里插入图片描述

4.3 QKV矩阵的概念

如果将输入的所有向量合并为矩阵形式,则所有QKV向量可以合并为QKV矩阵形式表示:
在这里插入图片描述

其中, W Q , W K , W V W^{Q},W^{K},W^{V} WQ,WK,WV 是模型训练过程学习到的合适的参数。

需要知道一个数学的先验知识,两个向量a和b同向, a ∗ b = ∣ a ∣ ∣ b ∣ a*b=|a||b| ab=a∣∣b;如果a和b垂直,则 a ∗ b = 0 a*b=0 ab=0;如果a和b反向,则 a ∗ b = − ∣ a ∣ ∣ b ∣ a*b=-|a||b| ab=a∣∣b。所以,两个向量的点乘(点积)可以表示两个向量的相似度,越相似则方向越趋于一致,a点乘b数值越大。则Self-Attention计算过程可以简化为:
在这里插入图片描述

上式是Self-Attention的公式,Q和K的点乘表示Q和K矩阵之间的相似程度,但是这个相似度不是归一化的,所以需要一个softmax将Q和K的结果进行归一化,那么softmax后的结果就是一个所有数值为0-1的mask矩阵(可以理解为Attention Score矩阵),而V矩阵表示输入线性变化后的特征,那么将mask矩阵乘上V矩阵就能得到加权后的特征。总结一下,Q和K矩阵的引入是为了得到一个所有数值为0-1的mask矩阵,V矩阵的引入是为了保留输入的特征(原始特征)

QKV来自于同一个句子表征,Q是目标词矩阵,K是关键词矩阵,V是原始特征,通过三步计算:

  1. Q和K进行点积计算,得到相似度矩阵;
  2. softmax归一化相似度矩阵,得到相似度权重;
  3. 将相似度权重和V矩阵加权求和,得到强化表征Z。

4.4 Multihead Attention单元

而multihead就是有不同的Q,K,V表示,最后将其结果结合起来,如下图表示:
在这里插入图片描述

这就是基本的Multihead Attention单元,对于encoder来说,就是利用这些基本单元叠加。其中K,Q,V均来自前一层encoder的输出,即encoder的每个位置都可以注意到之前一层encoder的所有位置

对于decoder来说,有两个与encoder不同的地方。一个是第一级的Masked Multihead,另一个是第二级的Multi-Head Attention不仅接收来自前一级的输出,还要接收encoder的输出。
在这里插入图片描述

第一级decoder的key,query,value均来自前一层decoder的输出,但加入了Mask操作,即我们只能attend到前面已经翻译过的输出的词语,因为当前的翻译过程并不知道下一个输出词语,这是之后才会推测到的。

第二级decoder也被称作encoder-decoder attention layer,即它的Q来自于之前一级的decoder层的输出,但其key和value来自于encoder的输出,这使得decoder的每一个位置都可以attend到输入序列的每一个位置。
在这里插入图片描述

总结一下,key和value的来源总是相同的,q在encoder以及第一级decoder中与key,value来源相同,在encoder-decoder attention layer中与key,value来源不同

5. Self-Attention的缺陷

在self-attention模型中,输入是一整排tokens,对于人类来说,我们很容易知道tokens的位置信息,比如:

  1. 绝对位置信息。a1是第一个token,a2是第二个token…
  2. 相对位置信息。a2在a1的后面一位,a4在a2的后面两位…
  3. 不同位置间的距离。a1和a3相差两个位置,a1和a4相差三个位置…

这些对于self-attention来说,是无法分辨的信息,因为self-attention的运算是无向的

6. Attention与Self-Attention对比

6.1 Attention layer

  • Attention layer: C = A t t n ( X , X ′ ) \mathrm{C}=\mathrm{Attn}(\mathbf{X},\mathbf{X}^{\prime}) C=Attn(X,X).
  • Query: q : j = W Q x j ′ \mathbf{q}_{:j}=\mathbf{W}_Q\mathbf{x}_j^{\prime} q:j=WQxj.
  • Key: k : i = W K x i \mathbf{k}_{:i}=\mathbf{W}_K\mathbf{x}_i k:i=WKxi.
  • Value: v : i = W V x i \mathbf{v}_{:i}=\mathbf{W}_V\mathbf{x}_i v:i=WVxi.
  • Output: c ; j = V ⋅ S o f t m a x ( K T q : j ) \mathrm{c}_{;j}=\mathrm{V}\cdot\mathrm{Softmax}(\mathbb{K}^T\mathbf{q}_{:j}) c;j=VSoftmax(KTq:j).
    在这里插入图片描述

6.2 Self-Attention Layer

  • Attention layer: C = A t t n ( X , X ′ ) \mathcal{C}=\mathrm{Attn}(\mathbf{X},\mathbf{X}^{\prime}) C=Attn(X,X).
  • Self-Attention layer: C = Attn ⁡ ( X , X ) C=\operatorname{Attn}(\mathbf{X},\mathbf{X}) C=Attn(X,X).
    在这里插入图片描述

7. Self-Attention代码实现

这里仅分析核心代码,详细代码请查阅:tensor2tensor/layers/common_attention.py

multihead_attention()

def multihead_attention(query_antecedent,
                        memory_antecedent,
                        ...):
    """Multihead scaled-dot-product attention with input/output transformations.
  Args:
    query_antecedent: a Tensor with shape [batch, length_q, channels]
    memory_antecedent: a Tensor with shape [batch, length_m, channels] or None
    ...
  Returns:
    The result of the attention transformation. The output shape is
        [batch_size, length_q, hidden_dim]  
  """
    #计算q, k, v矩阵
    q, k, v = compute_qkv(query_antecedent, memory_antecedent, ...)
    #计算dot_product的attention
    x = dot_product_attention(q, k, v, ...)
    x = common_layers.dense(x, ...)
    return x

compute_qkv()

def compute_qkv(query_antecedent,
                memory_antecedent,
                ...):
    """Computes query, key and value.
  Args:
    query_antecedent: a Tensor with shape [batch, length_q, channels]
    memory_antecedent: a Tensor with shape [batch, length_m, channels]
    ...
  Returns:
    q, k, v : [batch, length, depth] tensors
  """
    # 注意这里如果memory_antecedent是None,它就会设置成和query_antecedent一样,encoder的
    # self-attention调用时memory_antecedent 传进去的就是None。
    if memory_antecedent is None:
        memory_antecedent = query_antecedent
        q = compute_attention_component(
            query_antecedent,
            ...)
        # 注意这里k,v均来自于memory_antecedent。
        k = compute_attention_component(
            memory_antecedent,
            ...)
        v = compute_attention_component(
            memory_antecedent,
            ...)
        return q, k, v

    def compute_attention_component(antecedent,
                                    ...):
        """Computes attention compoenent (query, key or value).
  Args:
    antecedent: a Tensor with shape [batch, length, channels]
    name: a string specifying scope name.
    ...
  Returns:
    c : [batch, length, depth] tensor
  """
        return common_layers.dense(antecedent, ...)

dot_product_attention()

def dot_product_attention(q,
                          k,
                          v,
                          ...):
    """Dot-product attention.
  Args:
    q: Tensor with shape [..., length_q, depth_k].
    k: Tensor with shape [..., length_kv, depth_k]. Leading dimensions must
      match with q.
    v: Tensor with shape [..., length_kv, depth_v] Leading dimensions must
      match with q.
  Returns:
    Tensor with shape [..., length_q, depth_v].
  """
    # 计算Q, K的矩阵乘积。
    logits = tf.matmul(q, k, transpose_b=True)
    # 利用softmax将结果归一化。
    weights = tf.nn.softmax(logits, name="attention_weights")
    # 与V相乘得到加权表示。
    return tf.matmul(weights, v)

transformer_encoder()

def transformer_encoder(encoder_input,
                        hparams,
                        ...):
    """A stack of transformer layers.
  Args:
    encoder_input: a Tensor
    hparams: hyperparameters for model
    ...
  Returns:
    y: a Tensors
  """
    x = encoder_input
    with tf.variable_scope(name):
        for layer in range(hparams.num_encoder_layers or hparams.num_hidden_layers):
            with tf.variable_scope("layer_%d" % layer):
                with tf.variable_scope("self_attention"):
                    # layer_preprocess及layer_postprocess包含了一些layer normalization
                    # 及residual connection, dropout等操作。
                    y = common_attention.multihead_attention(
                        common_layers.layer_preprocess(x, hparams),
                        #这里注意encoder memory_antecedent设置为None
                        None,
                        ...)
                    x = common_layers.layer_postprocess(x, y, hparams)
                    with tf.variable_scope("ffn"):
                        # 前馈神经网络部分。
                        y = transformer_ffn_layer(
                            common_layers.layer_preprocess(x, hparams),
                            hparams,
                            ...)
                        x = common_layers.layer_postprocess(x, y, hparams)
                        return common_layers.layer_preprocess(x, hparams)

transformer_decoder()

def transformer_decoder(decoder_input,
                        encoder_output,
                        hparams,
                        ...):
    """A stack of transformer layers.
  Args:
    decoder_input: a Tensor
    encoder_output: a Tensor
    hparams: hyperparameters for model
    ...
  Returns:
    y: a Tensors
  """
    x = decoder_input
    with tf.variable_scope(name):
        for layer in range(hparams.num_decoder_layers or hparams.num_hidden_layers):
            layer_name = "layer_%d" % layer
            with tf.variable_scope(layer_name):
                with tf.variable_scope("self_attention"):
                    # decoder一级memory_antecedent设置为None
                    y = common_attention.multihead_attention(
                        common_layers.layer_preprocess(x, hparams),
                        None,
                        ...)
                    x = common_layers.layer_postprocess(x, y, hparams)
                    if encoder_output is not None:
                        with tf.variable_scope("encdec_attention"):
                            # decoder二级memory_antecedent设置为encoder_output
                            y = common_attention.multihead_attention(
                                common_layers.layer_preprocess(x, hparams),
                                encoder_output,
                                ...)
                            x = common_layers.layer_postprocess(x, y, hparams)
                            with tf.variable_scope("ffn"):
                                y = transformer_ffn_layer(
                                    common_layers.layer_preprocess(x, hparams),
                                    hparams,
                                    ...)
                                x = common_layers.layer_postprocess(x, y, hparams)
                                return common_layers.layer_preprocess(x, hparams)

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

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

相关文章

算法通关18关 | 回溯模板如何解决复原IP问题

18关的前几篇文章看过之后,对回溯的模板问题基本解题思路就知道了,就是固定的for循环问题,外层for循环控制横向,递归控制纵向,还要考虑撤销操作和元素是否能被重复利用问题,重复利用的情景较少,…

【物联网】简要解释RTK(Real-Time Kinematic)>>实时动态差分定位

引言: RTK(Real-Time Kinematic)技术是一种基于差分GPS的高精度定位技术,它通过实时通信和数据处理,能够提供厘米级甚至亚米级的定位精度。RTK技术在许多领域都得到了广泛应用,如测绘、航空航天、农业等。本…

C++ 内存模型 Memory Model

CPU 现在CPU都是多核结构,每个核心都有自己的一级缓存,二级缓存,以及共享的三级缓存。如下图,其中一级缓存分为指令缓存IL1和数据缓存DL1,二级缓存L2 256kB,三级缓存 L3 8MB。 从上图可以看出L3比L2大得多…

从零开始:PostgreSQL入门完全指南

🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🐅🐾猫头虎建议程序员必备技术栈一览表📖: 🛠️ 全栈技术 Full Stack: &#x1f4da…

【漏洞复现】大华智慧园区综合管理平台前台任意文件上传漏洞

文章目录 前言声明一、简介二、影响范围三、资产搜索四、漏洞测试四、修复建议前言 大华智慧园区综合管理平台存在前台任意文件上传漏洞,攻击者可通过特定Payload获取服务器敏感信息,进而获取服务器控制权限。 声明 请勿利用文章内的相关技术从事非法测试,由于传播、利用…

树和二叉树的相关概念及结构

目录 1.树的概念及结构 1.1 树的概念 1.2 树的相关概念 1.3 树的表示 1.3.1 孩子兄弟表示法 1.3.2 双亲表示法 1.4 树的实际应用 2.二叉树的概念及结构 2.1 二叉树的概念 2.2 特殊的二叉树 2.3 二叉树的性质 2.4 二叉树的存储 2.4.1 顺序存储 2.4.2 链式存储 1.树…

idea内存不足

The IDE is running low on memory and this might affect performance. Please consider increasing available heap. 参考 【IDEA】The IDE is running low on memory and this might affect performance._datagrip提示ide內存不足_Coder_贾俊浩的博客-CSDN博客 (亲测好用…

零基础教你搭建日用百货线上商城小程序

在当今的数字化时代,小程序商城已成为许多企业和商家的首选平台,尤其是日用百货行业。通过小程序商城,消费者可以更方便地购买各类日用品,商家也可以提高销售效率、扩大市场影响力。本文将详细介绍如何从零开始制作一个日用百货小…

论文解读 | MVSNet:非结构化多视图立体的深度推理

原创 | 文 BFT机器人 这篇论文的题目是《MVSNet: Depth Inference for Unstructured Multi-view Stereo》。这是一篇关于深度学习在多视角立体视觉(MVS)中的应用的研究论文。MVS任务的目标是从多个视角的图像中还原出三维场景的深度信息,从而…

佛山融资融券(两融)开户利率最低能做到多少?5%!

佛山融资融券(两融)开户利率最低能做到多少?5%! 具体佛山融资融券(两融)开户利率最低能做到多少,需要根据不同的券商政策而定。不同的券商可能具有不同的优惠政策和开户条件,因此开户前应该仔细了解券商的政策和条件。 融资融券是投资者通过证券公司向…

VScode配置Ros环境

VScode配置Ros环境 VScode配置Ros环境 1. VSCode下载 直接百度搜索VScode,去官网安装Ubuntu版本的VScode,下载完成之后用Ububtu Software进行安装。 2. VScode配置 2.1 功能包配置 下载完成之后直接打开ROS的工作目录,之后安装ROS包。 …

LeetCode 238. 除自身以外数组的乘积

题目链接 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 题目解析 使用前缀和进行解决该题,只不过与之前前缀和不同的是这个题目计算前缀和的时候不需要计算当前元素,也就是当前位置前缀和的值其实是不包含当前元素的前缀和。…

递归二进制【典中典】

洛谷 #include<iostream> #include<algorithm> using namespace std; const int N3e7; int path[N]; int n,idx;//我们使用二进制的形式来解决这个问题 //移位运算的优先级高于按位与的优先级 void dfs(int x,int st) {if(xn){path[idx]st;return;}//选----1dfs(x1…

C语言之指针进阶篇(3)

目录 思维导图 回调函数 案例1—计算器 案例2—qsort函数 关于qsort函数 演示qsort函数的使用 案例3—冒泡排序 整型数据冒泡排序 回调函数搞定各类型冒泡排序 cmp_int比较大小 cmp传参数 NO1. NO2. 解决方案 交换swap 总代码 今天我们学习指针难点之回调函数…

网站搭建从零开始(0)--域名的选择与解析

目录 确定用途 购买域名 使用可靠的注册商购买域名 想好域名关键词 检查域名是否可用 添加域名到购物车并完成购买 域名的解析 登录注册商账户 选择要配置的域名 进入DNS解析设置 添加DNS记录 保存配置 检查解析是否生效 提示 确定用途 在购买域名之前&#xf…

基于 MATLAB 的电力系统动态分析研究【IEEE9、IEEE68系节点】

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

TypeScript接口和类

&#x1f3ac; 岸边的风&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! 目录 接口 类 在 TypeScript 中&#xff0c;接口&#xff08;Interfaces&#xff09;和类&#xff08;Classes&#xff…

长尾关键词挖掘软件-免费的百度搜索关键词挖掘

嗨&#xff0c;大家好&#xff01;今天&#xff0c;我想和大家聊一聊长尾关键词挖掘工具。作为一个在网络世界里摸爬滚打多年的人&#xff0c;我对这个话题有着一些个人的感悟和见解&#xff0c;希望能与大家分享。 首先&#xff0c;让我坦白一点&#xff0c;长尾关键词挖掘工具…

零基础学前端(二)用简单案例去理解 HTML 、CSS 、JavaScript 概念

该篇适用于从零基础学习前端的小白 初学者不懂代码得含义也要坚持模仿逐行敲代码&#xff0c;以身体感悟带动头脑去理解新知识 一、导言 HTML&#xff0c;CSS&#xff0c;JavaScript 都是单独的语言&#xff1b;他们构成前端技术基础&#xff1b; &#xff08;1&#xff09;HTM…

【操作系统】进程控制

进程控制&#xff1a;创建新进程&#xff0c;撤销已有进程&#xff0c;实现进程状态转换等。 原语&#xff1a;进程控制用的程序段。执行期间不允许中断&#xff0c;用&#xff02;关中断&#xff02;和&#xff02;开中断&#xff02;指令&#xff08;特权指令&#xff09;实…