Transform模型详解

Transformer模型详解

  • Encoder与Decoder
  • 输入
    • 单词Embedding
    • 位置 Embedding
  • 自注意力机制
    • Self-Attention 结构
    • Self-Attention 的输出
    • Multi-Head Attention
  • Encoder 结构
    • Add & Norm
    • Feed Forward
    • 组成 Encoder
  • Decoder结构
    • Decoder第一个 Multi-Head Attention
    • Decoder第二个 Multi-Head Attention
    • Softmax 预测输出单词
  • Transformer 总结

Encoder与Decoder

在这里插入图片描述
可以看到 Transformer 由 Encoder 和 Decoder 两个部分组成,Encoder 和 Decoder 都包含 6 个 block。Transformer 的工作流程大体如下:
第一步:获取输入句子的每一个单词的表示向量 X,X由单词的 Embedding(Embedding就是从原始数据提取出来的Feature) 和单词位置的 Embedding 相加得到。
在这里插入图片描述
第二步:将得到的单词表示向量矩阵 (如上图所示,每一行是一个单词的表示 x) 传入 Encoder 中,经过 6 个 Encoder block 后可以得到句子所有单词的编码信息矩阵 C,如下图。单词向量矩阵用 X n × d X_{n×d} Xn×d表示, n 是句子中单词个数,d 是表示向量的维度 (论文中 d=512)。每一个 Encoder block 输出的矩阵维度与输入完全一致。
在这里插入图片描述
第三步:将 Encoder 输出的编码信息矩阵 C传递到 Decoder 中,Decoder 依次会根据当前翻译过的单词 1~ i 翻译下一个单词 i+1,如下图所示。在使用的过程中,翻译到单词 i+1 的时候需要通过 Mask (掩盖) 操作遮盖住 i+1 之后的单词。
在这里插入图片描述
上图 Decoder 接收了 Encoder 的编码矩阵 C,然后首先输入一个翻译开始符 “”,预测第一个单词 “I”;然后输入翻译开始符 “” 和单词 “I”,预测单词 “have”,以此类推。这是 Transformer 使用时候的大致流程,接下来是里面各个部分的细节。

输入

单词Embedding

单词的 Embedding 有很多种方式可以获取,例如可以采用 Word2Vec、Glove 等算法预训练得到,也可以在 Transformer 中训练得到。

位置 Embedding

Transformer 中除了单词的 Embedding,还需要使用位置 Embedding 表示单词出现在句子中的位置。因为Transformer 不采用 RNN 的结构,而是使用全局信息,不能利用单词的顺序信息,而这部分信息对于 NLP 来说非常重要。所以 Transformer 中使用位置 Embedding 保存单词在序列中的相对或绝对位置。位置 Embedding 用 PE表示,PE 的维度与单词 Embedding 是一样的。PE 可以通过训练得到,也可以使用某种公式计算得到。在 Transformer 中采用了后者,计算公式如下:
P E ( p o s , 2 i ) = sin ⁡ ( p o s 1000 0 2 i / d ) P E ( p o s , 2 i + 1 ) = cos ⁡ ( p o s 1000 0 2 i / d ) \begin{aligned}&\mathrm{PE}_{(pos,2i)}=\sin\left(\frac{pos}{10000^{2i/d}}\right)\\&\mathrm{PE}_{(pos,2i+1)}=\cos\left(\frac{pos}{10000^{2i/d}}\right)\end{aligned} PE(pos,2i)=sin(100002i/dpos)PE(pos,2i+1)=cos(100002i/dpos)
其中,pos 表示单词在句子中的位置,d 表示 PE的维度 (与词 Embedding 一样),2i 表示偶数的维度,2i+1 表示奇数维度 (即 2i≤d, 2i+1≤d)。使用这种公式计算 PE 有以下的好处:

  1. 使 PE 能够适应比训练集里面所有句子更长的句子,假设训练集里面最长的句子是有 20 个单词,突然来了一个长度为 21 的句子,则使用公式计算的方法可以计算出第 21 位的 Embedding。
  2. 可以让模型容易地计算出相对位置,对于固定长度的间距 k,PE(pos+k) 可以用 PE(pos) 计算得到。因为 Sin(A+B) = Sin(A)Cos(B) + Cos(A)Sin(B), Cos(A+B) = Cos(A)Cos(B) - Sin(A)Sin(B)。

将单词的词 Embedding 和位置 Embedding 相加,就可以得到单词的表示向量 x,x 就是 Transformer 的输入。

自注意力机制

在这里插入图片描述
上图是论文中 Transformer 的内部结构图,左侧为 Encoder block,右侧为 Decoder block。红色圈中的部分为 Multi-Head Attention,是由多个 Self-Attention组成的,可以看到 Encoder block 包含一个 Multi-Head Attention,而 Decoder block 包含两个 Multi-Head Attention (其中有一个用到 Masked)。Multi-Head Attention 上方还包括一个 Add & Norm 层,Add 表示残差连接 (Residual Connection) 用于防止网络退化,Norm 表示 Layer Normalization,用于对每一层的激活值进行归一化

因为 Self-Attention是 Transformer 的重点,所以我们重点关注 Multi-Head Attention 以及 Self-Attention,首先详细了解一下 Self-Attention 的内部逻辑。

Self-Attention 结构

下图是 Self-Attention 的结构,在计算的时候需要用到矩阵Q(查询),K(键值),V(值)。在实际中,Self-Attention 接收的是输入(单词的表示向量x组成的矩阵X) 或者上一个 Encoder block 的输出。而Q,K,V正是通过 Self-Attention 的输入进行线性变换得到的。
在这里插入图片描述
Self-Attention 的输入用矩阵X进行表示,则可以使用线性变阵矩阵 W Q , W K , W V W_Q,W_K,W_V WQ,WK,WV计算得到Q,K,V。计算如下图所示,注意 X, Q, K, V 的每一行都表示一个单词。
在这里插入图片描述

Self-Attention 的输出

得到矩阵 Q, K, 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 \mathrm{Attention}(Q,K,V)=\mathrm{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V Attention(Q,K,V)=softmax(dk QKT)V
d k d_k dk Q , K Q,K Q,K矩阵的列数,即向量维度,公式中计算矩阵Q和K每一行向量的内积,为了防止内积过大,因此除以 d k d_k dk的平方根。Q乘以K的转置后,得到的矩阵行列数都为 n,n 为句子单词数,这个矩阵可以表示单词之间的 attention 强度。下图为Q乘以 K T K^T KT,1234 表示的是句子中的单词。
在这里插入图片描述
得到 Q K T QK^T QKT 之后,使用 Softmax 计算每一个单词对于其他单词的 attention 系数,公式中的 Softmax 是对矩阵的每一行进行 Softmax,即每一行的和都变为 1。对于每一行的向量 z = ( z 1 , z 2 , . . . , z k ) z=(z_1,z_2,...,z_k) z=(z1,z2,...,zk),softmax计算如下:
Softmax ⁡ ( z ) i = e z i / τ ∑ j = 1 k e z j / τ ,   f o r   i = 1 , 2 , . . . , k \operatorname{Softmax}(z)_i=\frac{e^{z_i/\tau}}{\sum_{j=1}^ke^{z_j/\tau}},\quad\mathrm{~for~}i=1,2,...,k Softmax(z)i=j=1kezj/τezi/τ, for i=1,2,...,k
τ \tau τ是温度参数,原论文设置为1,当 τ \tau τ较大时,Softmax 函数输出的概率分布更趋向于均匀分布,因为指数函数的输出更接近原始输入的比例。而当 τ \tau τ较小时,Softmax 函数输出的概率分布更趋向于对最大输入的强调,即更集中在最大输入对应的类别上。这个温度参数可以控制 softmax 操作的输出分布的 “平滑度”,调整模型对不同位置的关注程度。得到 Softmax 矩阵之后可以和V相乘,得到最终的输出Z。
在这里插入图片描述
在这里插入图片描述

上图中 Softmax 矩阵的第 1 行表示单词 1 与其他所有单词的 attention 系数,最终单词 1 的输出 Z 1 Z_1 Z1等于所有单词 i 的值 V i V_i Vi根据 attention 系数的比例加在一起得到,如下图所示:在这里插入图片描述

Multi-Head Attention

在上一步,我们已经知道怎么通过 Self-Attention 计算得到输出矩阵 Z,而 Multi-Head Attention 是由多个 Self-Attention 组合形成的,下图是论文中 Multi-Head Attention 的结构图。
在这里插入图片描述

从上图可以看到 Multi-Head Attention 包含多个 Self-Attention 层,首先将输入X分别传递到 h 个不同的 Self-Attention 中,计算得到 h 个输出矩阵Z。下图是 h=8 时候的情况,此时会得到 8 个输出矩阵Z。
在这里插入图片描述
得到 8 个输出矩阵 Z 1 Z_1 Z1 Z 8 Z_8 Z8 之后,Multi-Head Attention 将它们拼接在一起 (Concat),然后传入一个Linear层,得到 Multi-Head Attention 最终的输出Z。可以看到 Multi-Head Attention 输出的矩阵Z与其输入的矩阵X的维度是一样的。

Encoder 结构

在这里插入图片描述
上图红色部分是 Transformer 的 Encoder block 结构,可以看到是由 Multi-Head Attention, Add & Norm, Feed Forward, Add & Norm 组成的。刚刚已经了解了 Multi-Head Attention 的计算过程,现在了解一下 Add & Norm 和 Feed Forward 部分。

Add & Norm

Add & Norm 层由 Add 和 Norm 两部分组成,其计算公式如下:
L a y e r N o r m ( X + M u l t i H e a d A t t e n t i o n ( X ) ) L a y e r N o r m ( X + F e e d F o r w a r d ( X ) ) \begin{aligned}\mathrm{LayerNorm}&\big(X+\mathrm{MultiHeadAttention}(X)\big)\\\mathrm{LayerNorm}&\big(X+\mathrm{FeedForward}(X)\big)\end{aligned} LayerNormLayerNorm(X+MultiHeadAttention(X))(X+FeedForward(X))
其中 X表示 Multi-Head Attention 或者 Feed Forward 的输入,MultiHeadAttention(X) 和 FeedForward(X) 表示输出 (输出与输入 X 维度是一样的,所以可以相加)。Add指 X+MultiHeadAttention(X),是一种残差连接,通常用于解决多层网络训练的问题,可以让网络只关注当前差异的部分,在 ResNet 中经常用到:
在这里插入图片描述
Norm指 Layer Normalization,通常用于 RNN 结构,Layer Normalization 会将每一层神经元的输入都转成均值方差都一样的,这样可以加快收敛。

Feed Forward

Feed Forward 层比较简单,是一个两层的全连接层,第一层的激活函数为 Relu,第二层不使用激活函数,对应的公式如下 m a x ( 0 , X W 1 + b 1 ) W 2 + b 2 max(0,XW_1+b_1)W_2+b_2 max(0,XW1+b1)W2+b2
X是输入,Feed Forward 最终得到的输出矩阵的维度与X一致。

组成 Encoder

通过上面描述的 Multi-Head Attention, Feed Forward, Add & Norm 就可以构造出一个 Encoder block,Encoder block 接收输入矩阵 ,并输出一个矩阵 。通过多个 Encoder block 叠加就可以组成 Encoder。
在这里插入图片描述
第一个 Encoder block 的输入为句子单词的表示向量矩阵,后续 Encoder block 的输入是前一个 Encoder block 的输出,最后一个 Encoder block 输出的矩阵就是编码信息矩阵 C,这一矩阵后续会用到 Decoder 中。

Decoder结构

在这里插入图片描述
上图红色部分为Transformer 的 Decoder block 结构,与 Encoder block 相似,但是存在一些区别:

  1. 包含两个 Multi-Head Attention 层。
  2. 第一个 Multi-Head Attention 层采用了 Masked 操作。
  3. 第二个 Multi-Head Attention 层的K, V矩阵使用 Encoder 的编码信息矩阵C进行计算,而Q使用上一个Decoder block 的输出计算。
  4. 最后有一个 Softmax 层计算下一个翻译单词的概率。

Decoder第一个 Multi-Head Attention

Decoder block 的第一个 Multi-Head Attention 采用了 Masked 操作,因为在翻译的过程中是顺序翻译的,即翻译完第 i 个单词,才可以翻译第 i+1 个单词。通过 Masked 操作可以防止第 i 个单词知道 i+1 个单词之后的信息。下面以 “我有一只猫” 翻译成 “I have a cat” 为例,了解一下 Masked 操作。

下面的描述中使用了类似 Teacher Forcing 的概念,在 Decoder 的时候,是需要根据之前的翻译,求解当前最有可能的翻译,如下图所示。首先根据输入 “” 预测出第一个单词为 “I”,然后根据输入 “ I” 预测下一个单词 “have”。
在这里插入图片描述
Decoder 可以在训练的过程中使用 Teacher Forcing 并且并行化训练,即将正确的单词序列 ( I have a cat) 和对应输出 (I have a cat ) 传递到 Decoder。那么在预测第 i 个输出时,就要将第 i+1 之后的单词掩盖住,注意 Mask 操作是在 Self-Attention 的 Softmax 之前使用的,下面用 0 1 2 3 4 5 分别表示 “ I have a cat ”。

第一步:是 Decoder 的输入矩阵和 Mask 矩阵,输入矩阵包含 “ I have a cat” (0, 1, 2, 3, 4) 五个单词的表示向量,Mask 是一个 5×5 的矩阵。在 Mask 可以发现单词 0 只能使用单词 0 的信息,而单词 1 可以使用单词 0, 1 的信息,即只能使用之前的信息。
在这里插入图片描述
第二步:接下来的操作和之前的 Self-Attention 一样,通过输入矩阵X计算得到Q,K,V矩阵。然后计算Q和 K T K^T KT 的乘积 Q K T QK^T QKT
在这里插入图片描述
第三步:在得到 Q K T QK^T QKT之后需要进行 Softmax,计算 attention score,我们在 Softmax 之前需要使用Mask矩阵遮挡住每一个单词之后的信息,遮挡操作如下,注意是按位相乘:

在这里插入图片描述
Softmax 之前 Mask:得到 Mask之后在 Mask上进行 Softmax,每一行的和都为 1。但是单词 0 在单词 1, 2, 3, 4 上的 attention score 都为 0。

第四步:使用 Mask Q K T QK^T QKT与矩阵 V相乘,得到输出 Z,则单词 1 的输出向量 Z 1 Z_1 Z1是只包含单词 1 信息的。
在这里插入图片描述
第五步:通过上述步骤就可以得到一个 Mask Self-Attention 的输出矩阵,然后和 Encoder 类似,通过 Multi-Head Attention 拼接多个输出,然后计算得到第一个 Multi-Head Attention 的输出Z,Z与输入X维度一样。

Decoder第二个 Multi-Head Attention

Decoder block 第二个 Multi-Head Attention 变化不大, 主要的区别在于其中 Self-Attention 的 K, V矩阵不是使用 上一个 Decoder block 的输出计算的,而是使用 Encoder 的编码信息矩阵 C 计算的。

根据 Encoder 的输出 C计算得到 K, V,根据上一个 Decoder block 的输出 Z 计算 Q (如果是第一个 Decoder block 则使用输入矩阵 X 进行计算),后续的计算方法与之前描述的一致。

这样做的好处是在 Decoder 的时候,每一位单词都可以利用到 Encoder 所有单词的信息 (这些信息无需 Mask)。

Softmax 预测输出单词

Decoder block 最后的部分是利用 Softmax 预测下一个单词,在之前的网络层我们可以得到一个最终的输出 Z,因为 Mask 的存在,使得单词 0 的输出 Z 0 Z_0 Z0 只包含单词 0 的信息,如下:
在这里插入图片描述
Softmax 根据输出矩阵的每一行预测下一个单词:
在这里插入图片描述
这就是 Decoder block 的定义,与 Encoder 一样,Decoder 是由多个 Decoder block 组合而成。

Transformer 总结

Transformer 与 RNN 不同,可以比较好地并行训练。
Transformer 本身是不能利用单词的顺序信息的,因此需要在输入中添加位置 Embedding,否则 Transformer 就是一个词袋模型了。
Transformer 的重点是 Self-Attention 结构,其中用到的 Q, K, V矩阵通过输出进行线性变换得到。
Transformer 中 Multi-Head Attention 中有多个 Self-Attention,可以捕获单词之间多种维度上的相关系数 attention score。

Transformer 模型的详细数学表述涉及编码器(Encoder)和解码器(Decoder)两个主要组件。以下是它们的数学表达:
编码器(Encoder):

  1. 输入表示: 假设输入序列为 X = ( x 1 , x 2 , . . . , x T ) X=(x_1,x_2,...,x_T) X=(x1,x2,...,xT),其中 x i x_i xi是输入系列的第 i i i个元素
  2. 嵌入层(Embedding Layer): 将输入序列中的每个元素 x i x_i xi映射到高维的嵌入空间,得到序列的嵌入表示 E = ( e 1 , e 2 , . . . , e T ) E=(e_1,e_2,...,e_T) E=(e1,e2,...,eT),这可以用一个嵌入矩阵 W e W_e We来实现: e i = W e ⋅ x i e_i = W_e \cdot x_i ei=Wexi
  3. 位置编码(Positional Encoding): 为了引入位置信息,将嵌入表示 E E E与位置编码矩阵相加,得到带有位置信息的输入表示 X e m b X_{emb} Xemb。位置编码可以通过以下公式得到:
    X e m b = E + P o s i t i o n a l E n c o d i n g X_{emb}=E+PositionalEncoding Xemb=E+PositionalEncoding
  4. 其中, P o s i t i o n a l E n c o d i n g PositionalEncoding PositionalEncoding是位置编码矩阵。多层自注意力机制(Multi-Head Self Attention): 对带有位置编码的输入序列 X e m b X_{emb} Xemb进行多头自注意力操作。对于每个头 i i i,计算注意力权重 A i A_{i} Ai和加权和 Z i Z_{i} Zi
    A i = softmax ( ( X e m b ⋅ W Q i ) ⋅ ( ( X e m b ⋅ W K i ) T ) d k ) Z i = A i ⋅ ( X e m b ⋅ W V i ) \begin{gathered}A_i=\text{softmax}\left(\frac{(X_{\mathrm{emb}}\cdot W_{Qi})\cdot((X_{\mathrm{emb}}\cdot W_{Ki})^T)}{\sqrt{d_k}}\right)\\Z_i=A_i\cdot(X_{\mathrm{emb}}\cdot W_{Vi})\end{gathered} Ai=softmax(dk (XembWQi)((XembWKi)T))Zi=Ai(XembWVi)
    其中, W Q i 、 W K i 、 W V i W_{Qi}、W_{Ki}、W_{Vi} WQiWKiWVi是注意力头的权重矩阵, d k d_k dk是头的维度。
  5. 多头注意力的拼接和线性变换: 将多头注意力的输出拼接并进行线性变换,得到编码器层的输出 X e n c X_{enc} Xenc
    X e n c = C o n c a t ( Z 1 , Z 2 , . . . , Z h ) ⋅ W O X_{\mathrm{enc}}=\mathrm{Concat}(Z_1,Z_2,...,Z_h)\cdot W_O Xenc=Concat(Z1,Z2,...,Zh)WO
    其中 W O W_O WO是线性变换的权重矩阵
  6. 前馈神经网络(Feedforward Neural Network): 对编码器层的输出 X e n c X_{enc} Xenc应用前馈神经网络,得到最终的编码表示 X e n c ′ X_{\mathrm{enc}}^{\prime} Xenc
    X e n c ′ = R e L U ( X e n c ⋅ W F F N 1 + b F F N 1 ) ⋅ W F F N 2 + b F F N 2 X_{\mathrm{enc}}^{\prime}=\mathrm{ReLU}(X_{\mathrm{enc}}\cdot W_{\mathrm{FFN1}}+b_{\mathrm{FFN1}})\cdot W_{\mathrm{FFN2}}+b_{\mathrm{FFN2}} Xenc=ReLU(XencWFFN1+bFFN1)WFFN2+bFFN2
    其中, W F F N 1 、 b F F N 1 、 W F F N 2 、 b F F N 2 W_{\mathrm{FFN1}}、b_{\mathrm{FFN1}}、W_{\mathrm{FFN2}}、b_{\mathrm{FFN2}} WFFN1bFFN1WFFN2bFFN2是前馈神经网络的权重和偏置。

解码器:
解码器(Decoder):
解码器的数学表达与编码器类似,但有一些区别:

  1. 输入表示: 假设解码器的输入序列为 Y = ( y 1 , y 2 , . . . , y S ) Y=(y_1,y_2,...,y_S) Y=(y1,y2,...,yS),其中 y i y_i yi是输出序列的第 i i i个元素
  2. 嵌入层和位置编码: 类似于编码器,解码器对输入序列进行嵌入和位置编码。
  3. 多层自注意力和编码器-解码器注意力: 解码器包含多层自注意力机制和编码器-解码器注意力机制。编码器-解码器注意力用于在生成每个输出时关注输入序列的不同位置。
  4. 前馈神经网络: 与编码器类似,解码器包含前馈神经网络。
  5. 输出层: 解码器的最终输出通过一个线性变换和 softmax 操作得到概率分布,用于预测下一个输出元素:
    P ( Y ) = softmax ( ( X d e c ′ ⋅ W o u t p u t ) + b o u t p u t ) P(Y)=\text{softmax}((X_{\mathrm{dec}}^{\prime}\cdot W_{\mathrm{output}})+b_{\mathrm{output}}) P(Y)=softmax((XdecWoutput)+boutput)
    其中, X d e c X_{\mathrm{dec}} Xdec是解码器层的输出, W o u t p u t W_{\mathrm{output}} Woutput b o u t p u t b_{\mathrm{output}} boutput是输出层的权重和偏置。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

响应式Web开发项目教程(HTML5+CSS3+Bootstrap)第2版 例4-9 HTML5 表单验证

代码 <!doctype html> <html> <head> <meta charset"utf-8"> <title>HTML5 表单验证</title> </head><body> <form action"#" method"get">请输入您的邮箱:<input type"email&q…

【AI的未来 - AI Agent系列】【MetaGPT】6. 用ActionNode重写技术文档助手

文章目录 0. 前置推荐阅读1. 重写WriteDirectory Action1.1 实现WriteDirectory的ActionNode&#xff1a;DIRECTORY_WRITE1.2 将 DIRECTORY_WRITE 包进 WriteDirectory中 2. 重写WriteContent Action2.1 思考重写方案2.2 实现WriteContent的ActionNode2.3 改写WriteContent Act…

记录一下对集合排序,处理属性为空且参与排序方法

一、需求 实际项目中经常存在对集合某个或多个属性进行排序&#xff0c;例如根据姓名排序&#xff0c;根据金额排序&#xff1b;或者多个字段排序&#xff0c;例如姓名首字母升序金额降序两个字段排序等等。 但是有时候姓名或金额会为空&#xff0c;之前我们排序的时候需要拿出…

(Bean工厂的后处理器入门)学习Spring的第七天

一 . Bean工厂的后处理器入门 : 直接上图 BeanDefinitionRegistyPostProcessor 为 BeanFactoryProcessor的子接口 , 前者先执行(图里只有Bean工厂的后处理器第一个类型) 如下图 : 这两个接口可改变两个Map(BeanDefinitionMap , singletonObject)里的信息 (黑马只讲了BeanFact…

linux LPT和COM回路测试(基于python+Qt+C++)

软件UI: 回路治具&#xff08;COMLPT&#xff09;&#xff1a; lpt_test.cpp&#xff08;c 源代码&#xff09;&#xff1a; #include <iostream> #include <fstream> #include <sstream> #include <unistd.h> #include <fcntl.h> #include <…

SCDN高防如何保护你的服务器

随着互联网的发展&#xff0c;如今的网络世界&#xff0c;虽说给我们的衣食住行带来了非常大的便利&#xff0c;但同时它存在着各种各样的威胁。比如我们的网站&#xff0c;如果不做任何保护措施的话&#xff0c;就很容易被DDoS、CC等攻击堵塞网络、窃取目标系统的信息&#xf…

惬意上手Python —— 装饰器和内置函数

1. Python装饰器 Python中的装饰器是一种特殊类型的函数&#xff0c;它允许用户在不修改原函数代码的情况下&#xff0c;增加或修改函数的行为。 具体来说,装饰器的工作原理基于Python的函数也是对象这一事实&#xff0c;可以被赋值给变量、作为参数传递给其他函数或者作为其他…

【易经】-- 风水基础

目录 一、基础概念 1、五行 2、十天干 3、十二地支 4、八卦 4.1 伏羲八卦次序图 4.2 八卦对应自然界的基本事物 4.3 八卦及所代表的意像 ​编辑 5、生辰八字 5.1 定义 5.2 换算方法 5.3 举例 5.4 八字排盘示例 5.5 算法实现 二、举例 1、计算某年的生肖和年的属…

【nginx实战】nginx正向代理、反向代理、由反向代理实现的负载均衡、故障转移详解

文章目录 一. 正向代理与反向代理的概念二. Nginx服务器的正向代理服务1. Nginx服务器正向代理服务的配置的3个指令1.1. resolver指令1.2. resolver_timeout指令1.3. proxy_pass指令 2. Nginx服务器正向代理服务的使用 三. Nginx服务器的反向代理服务1. 反向代理的基本指令1.1.…

高数总结(1

目录 1.总结&#xff1a;小结&#xff1a; 1.总结&#xff1a; 小结&#xff1a; 关注我给大家分享更多有趣的知识&#xff0c;以下是个人公众号&#xff0c;提供 ||代码兼职|| ||代码问题求解|| 由于本号流量还不足以发表推广&#xff0c;搜我的公众号即可&#xff1a;

基于51单片机的超声波物位测量系统[proteus仿真]

基于51单片机的超声波物位测量系统[proteus仿真] 超声波检测系统这个题目算是课程设计和毕业设计中常见的题目了&#xff0c;本期是一个103基于51单片机的超声波物位测量系统 需要的源文件和程序的小伙伴可以关注公众号【阿目分享嵌入式】&#xff0c;赞赏任意文章 2&#xf…

Redis 笔记二

概览 1.高并发秒杀问题及可能出现的bug 2.秒杀场景JVM级别锁和分布式锁 3.大厂分布式锁Redisson框架 4.从Redisson源码剖析lua解决锁原子性问题 5.从Redisson源码剖析经典锁续命问题 6.Redis主从架构锁失效如何解决 7.Redlock分布式锁高并发下可能存在的问题 8.双十一大促如何将…

【学习】FPN特征金字塔

论文&#xff1a;Feature Pyramid Networks for Object Detection &#xff08;CVPR 2016) 参考blog&#xff1a;https://blog.csdn.net/weixin_55073640/article/details/122627966 参考视频讲解&#xff1a;添加链接描述 卷积网络中&#xff0c;深层网络容易响应语义特征&am…

【C++】list容器功能模拟实现

介绍 上一次介绍了list队容器的迭代器模拟&#xff0c;这次模拟实现list的简单功能&#xff0c;尤其要注意构造函数、析构函数、以及赋值运算符重载的实现。 list容器需要接纳所有类型的数据&#xff0c;因此&#xff0c;结构设置与迭代器设置同理&#xff0c;需要引入结点&…

Dirichlet Process 3

本节来介绍如何构造G&#xff0c;这里使用Stick-breaking construction算法 如下图H是关于的分布 对于G&#xff0c;这里面有2个变量&#xff0c;一个是&#xff0c;即采样的位置&#xff0c;一个是&#xff0c;即的权重 每次采样一次称为一个item 第一次采样 ,, 第二次采样…

c++的命名空间

命名空间 一.c的关键字二.命名空间2.1 命名空间定义2.1 命名空间的使用2.1.1加命名空间名称及作用域限定符2.1.2使用using将命名空间中某个成员引入 三.标准命名空间std 一.c的关键字 c中一共有63个关键字 关键字11111asmdoifreturntrycontinueautodoubleinlineshorttypedeff…

vue echarts地图

下载地图文件&#xff1a; DataV.GeoAtlas地理小工具系列 范围选择器右侧行政区划范围中输入需要选择的省份或地市&#xff0c;选择自己想要的数据格式&#xff0c;这里选择了geojson格式&#xff0c;点右侧的蓝色按钮复制到浏览器地址栏中&#xff0c;打开的geojson文件内容…

LeetCode 670 最大交换数

周一&#xff0c;非常冷&#xff0c;大风呼呼的&#xff0c;上班路都走不动。 好消息&#xff0c;马上要过年了。大风吹&#xff0c;天气好。 过年过年&#xff0c;回家过年~ 学生时代的迷茫是不应该存在的&#xff0c;最好的时光应该尽情享受&#xff0c;而不应该自己给加层…

三年的功能测试,让我女朋友跑了,太难受了...

简单概括一下 先说一下自己的情况&#xff0c;普通本科&#xff0c;18年通过校招进入深圳某软件公司&#xff0c;干了3年多的功能测试&#xff0c;21年的那会&#xff0c;因为大环境不好&#xff0c;我整个人心惊胆战的&#xff0c;怕自己卷铺盖走人了&#xff0c;我感觉自己不…

测试数据: 在线MP4和图片url地址

收集整理一些开发中用到的测试数据 目录 MP4图片ICON MP4 https://media.w3.org/2010/05/sintel/trailer.mp4 图片 https://img-blog.csdnimg.cn/fcc22710385e4edabccf2451d5f64a99.jpeg ICON https://img-blog.csdnimg.cn/direct/fb1e1f109889467a85eec6af0984611c.png 以…