图解NLP模型发展:从RNN到Transformer

news2025/2/26 19:32:22

图解NLP模型发展:从RNN到Transformer

自然语言处理 (NLP) 是深度学习中一个颇具挑战的问题,与图像识别和计算机视觉问题不同,自然语言本身没有良好的向量或矩阵结构,且原始单词的含义也不像像素值那么确定和容易表示。一般我们需要用词嵌入技术将单词转换为向量,然后再输入计算机进行计算。

词嵌入可用于多种任务,例如情感分类、文本生成、名称实体识别或机器翻译等。它以一种巧妙的处理方式,让模型在某些任务上的性能与人类能力相当。

那么,接下来的问题是:如何处理词嵌入? 如何为此类数据建立模型?这是本文接下来重点介绍的内容。

在这里插入图片描述

文章目录

    • 循环神经网络(RNN)
      • 普通RNN
      • 长短期记忆网络(LSTM)
      • 门控循环单元(GRU)
    • RNN架构
    • 注意力
      • 带注意力的seq2seq
      • 自注意力
      • 多头注意力
    • Transformer
      • 第一步. 将位置编码加入词嵌入
      • 第二步. 编码器:多头注意力和前馈
      • 第三步. 解码器:(掩码)多头注意力和前馈
      • 第四步. 分类器
    • 总结

循环神经网络(RNN)

人类的阅读习惯不会从头开始思考每个出现单词的含义,而是透过前面单词的信息来理解当前单词的含义。基于这种行为,循环神经网络 (RNN) 应运而生。

本节我们将重点关注 RNN 单元及其改进。 稍后,我们会将RNN单元组合在一起看整体架构。

普通RNN

Vanilla RNN 由若干重复单元组成,每个单元按顺序接收输入嵌入 x t x_t xt,并通过隐藏状态 h t − 1 h_{t-1} ht1 记忆过去的序列。隐藏状态更新为 h t h_t ht 并发送到下一个单元,或者输出预测结果。下图展示了 RNN 单元的内部工作原理。
在这里插入图片描述 h t = tanh ⁡ ( W ⋅ [ h t − 1 , x t ] + b ) h_t = \tanh(W \sdot [h_{t-1}, x_t]+b) ht=tanh(W[ht1,xt]+b)

普通RNN单元

优点

  • 以一种自然好理解的方式处理顺序和先前输入

缺点

  • 每一步的操作都依赖前一步的输出,因此很难并行化 RNN 操作。
  • 处理长序列可能出现梯度爆炸或消失。

长短期记忆网络(LSTM)

解决梯度爆炸或消失问题的一种方法是使用门控 RNN,门控 RNN可以有选择地保留信息并能够学习长期依赖性。门控 RNN 有两种流行变体:长短期记忆 (LSTM) 和门控循环单元 (GRU)。

在这里插入图片描述

LSTM单元

f t = σ ( W f ⋅ [ h t − 1 , x t ] + b f ) i t = σ ( W i ⋅ [ h t − 1 , x t ] + b i ) C ~ t = tanh ⁡ ( W c ⋅ [ h t − 1 , x t ] + b c ) o t = σ ( W o ⋅ [ h t − 1 , x t ] + b o ) C t = f t ∘ C t − 1 + i t ∘ C ~ t h t = o t ∘ tanh ⁡ ( C t ) \begin{align} f_t&=\sigma(W_f \sdot [h_{t-1}, x_t]+b_f)\notag\\ i_t&=\sigma(W_i \sdot [h_{t-1}, x_t]+b_i)\notag\\ \tilde{C}_t &= \tanh(W_c \sdot [h_{t-1}, x_t]+b_c)\notag\\ o_t&=\sigma(W_o \sdot [h_{t-1}, x_t]+b_o)\notag\\ C_t&=f_t \circ C_{t-1}+i_t \circ \tilde{C}_t\notag\\ h_t &= o_t \circ \tanh(C_t)\notag \end{align} ftitC~totCtht=σ(Wf[ht1,xt]+bf)=σ(Wi[ht1,xt]+bi)=tanh(Wc[ht1,xt]+bc)=σ(Wo[ht1,xt]+bo)=ftCt1+itC~t=ottanh(Ct)

为了避免长期依赖问题,LSTM 配备了一个类似于高速公路的单元状态 C t C_t Ct,因此信息可以很容易地流过而不会发生变化。

为了有选择地保留信息,LSTM 也有三个门:

  • 遗忘门 → \rarr 查看 h t − 1 h_{t-1} ht1 x t x_t xt,并输出一个由 0 到 1 之间的数字组成的向量 f t f_t ft,它告诉我们要从单元状态 C t − 1 C_{t-1} Ct1 中丢弃哪些信息。
  • 输入门 → \rarr 相似遗忘门,但这次输出的 i t i_t it 用于根据虚拟单元状态 c ˊ t \acute{c}_t cˊt 来决定我们要将哪些新信息存储在单元状态中。
  • 输出门 → \rarr 相似遗忘门,但是输出 o t o_t ot用于过滤更新后的单元状态 C t C_t Ct 得到新的隐藏状态 h t h_t ht

门控循环单元(GRU)

LSTM 非常复杂。GRU 提供与 LSTM 相似的性能,但复杂性更低(权重更少)。它合并了单元状态和隐藏状态。 还将遗忘门和输入门组合成一个“更新门”。

在这里插入图片描述

GRU单元

r t = σ ( W r ⋅ [ h t − 1 , x t ] + b r ) z t = σ ( W z ⋅ [ h t − 1 , x t ] + b z ) h ~ t = tanh ⁡ ( W h ⋅ [ r t ∘ h t − 1 , x t ] + b h ) h t = ( 1 − z t ) ∘ h t − 1 + z t ∘ h ~ t \begin{align} r_t&=\sigma(W_r \sdot [h_{t-1}, x_t]+b_r)\notag\\ z_t&=\sigma(W_z \sdot [h_{t-1}, x_t]+b_z)\notag\\ \tilde{h}_t &= \tanh(W_h \sdot [r_t \circ h_{t-1}, x_t]+b_h)\notag\\ h_t &= (1-z_t) \circ h_{t-1} + z_t \circ \tilde{h}_t\notag \end{align} rtzth~tht=σ(Wr[ht1,xt]+br)=σ(Wz[ht1,xt]+bz)=tanh(Wh[rtht1,xt]+bh)=(1zt)ht1+zth~t

GRU中有两个门:

  • 重置门 → \rarr 查看 h t − 1 h_{t-1} ht1 x t x_t xt,并输出一个由 0 到 1 之间的数字组成的向量 r t r_t rt,它决定需要忽略多少过去的信息 h t − 1 h_{t-1} ht1
  • 更新门 → \rarr 确定我们要在新的隐藏状态 h t h_t ht中保存的信息或基于 r t r_t rt丢弃的信息。

RNN架构

当我们了解了 RNN 单元的工作原理后,就可以按一定顺序将它们连接起来。 这里,预测的输出概率 y t y_t yt 可以表示为:
y t = g ( W h t + b ) y_t = g(Wh_t+b) yt=g(Wht+b)
其中 W W W是权重, b b b是偏差, g g g是激活函数。具体选择哪个激活函数以及RNN单元如何连接取决于具体任务。

在这里插入图片描述

不同任务下的RNN结构

其中,上图最后一个结构(机器翻译)就是我们所谓的seq2seq模型。其中输入序列 x 1 , x 2 , … , x t x_1,x_2,\dots,x_t x1,x2,,xt 被翻译成输出序列 y 1 , y 2 , … , y m y_1,y_2,\dots,y_m y1,y2,,ym。前 t t t 个 RNN 单元组成编码器,后 m m m 个 RNN 单元组成解码器。

另外,RNN 单元也可以如下图一样翻转或堆叠。 此类架构通常仅由两层或三层组成。这样做可以以增加计算量为代价提高模型性能。

在这里插入图片描述

RNN 变体,此类架构通常仅由两层或三层组成

注意力

seq2seq 只能使用编码器最末端的输出,输入给解码器解释。解码器只能看到来自最后一个编码器 RNN 单元的输入序列。但是,输入序列的不同部分在输出序列的每个生成步骤中可能更有用。 这就是注意力的概念。

优点

  • 无论输入标记的位置如何,都会考虑适当的编码表示。

缺点

  • 另一个计算步骤涉及学习权重。

带注意力的seq2seq

每个解码器token会查看每个编码器token,并通过其隐藏状态来决定哪些token需要更多关注。

在这里插入图片描述

带注意力的seq2seq工作流程

H = [ h 1 , h 2 , … , h t ] T Attention ( s i , H ) = softmax ( s i H T d h ) ⋅ H \begin{align} H&=[h_1, h_2, \dots, h_t]^T\notag\\ \text{Attention}(s_i, H)&=\text{softmax}(\frac{s_iH^T}{\sqrt{d_h}})\sdot H\notag \end{align} HAttention(si,H)=[h1,h2,,ht]T=softmax(dh siHT)H

在 seq2seq 中合并注意力分为三个步骤:

  1. 标量注意力分数是根据一对解码器和编码器隐藏状态 ( s i , h j ) (s_i, h_j) (si,hj) 计算的,它表示编码器token j j j 与解码器token i i i 的“相关性”。
  2. 所有注意力分数都通过 softmax 传递以产生注意力权重,这些注意力权重形成解码器和编码器token对相关性的概率分布。
  3. 计算具有注意力权重的编码器隐藏状态的加权和,并将其送入到下一个解码器单元。

在上面的案例中,分数函数为
score ( s i , h j ) = s i T h j d h \text{score}(s_i, h_j) = \frac{s_i^Th_j}{\sqrt{d_h}} score(si,hj)=dh siThj
其中 d h d_h dh h j h_j hj(和 s i s_i si)的维度。

自注意力

接下来我们完全抛弃 seq2seq,只关注注意力。 一种流行的注意力机制是自注意力。自注意力不去寻找解码器token与编码器token的相关性,而是寻找一组token中的每个token与同一组中所有其他token的相关性。

在这里插入图片描述

自注意力工作流程

X = [ x 1 , x 2 , … , x t ] T Q = [ q 1 , q 2 , … , q t ] T = X W Q K = [ k 1 , k 2 , … , k t ] T = X W K V = [ v 1 , v 2 , … , v t ] T = X W V Attension ( Q , K , V ) = softmax ( Q K T d k ) ⋅ V \begin{align} X=[x_1, x_2, \dots, x_t]^T\notag\\ Q=[q_1, q_2, \dots, q_t]^T &= XW_Q\notag\\ K=[k_1, k_2, \dots, k_t]^T &= XW_K\notag\\ V=[v_1, v_2, \dots, v_t]^T &= XW_V\notag\\ \text{Attension}(Q, K, V) &= \text{softmax}(\frac{QK^T}{\sqrt{d_k}})\sdot V\notag \end{align} X=[x1,x2,,xt]TQ=[q1,q2,,qt]TK=[k1,k2,,kt]TV=[v1,v2,,vt]TAttension(Q,K,V)=XWQ=XWK=XWV=softmax(dk QKT)V

自注意力使用注意力函数创建基于输入token对之间相似性的加权表示,它提供了输入序列的丰富表示,这些表示关注其元素之间的关系。

自注意力与普通注意力之间存在三个主要区别:

  1. 由于自注意力中没有解码器token,取而代之的是“查询”向量 q i q_i qi,它与输入嵌入 x i x_i xi 线性相关。
  2. 注意分数是根据 ( q i , k j ) (q_i, k_j) (qi,kj)对计算得到的,其中 k j k_j kj 是与 q i q_i qi 具有相同维度的“关键”向量,并且也与 x j x_j xj 线性相关。
  3. 与普通注意力中的 k j k_j kj 再次乘以注意力权重不同,自注意力将新的“值”向量 v j v_j vj 与注意力权重相乘。 请注意, v j v_j vj 可能具有与 k j k_j kj 不同的维度,并且也与 x j x_j xj 线性相关。

多头注意力

注意力可以并行运行多次,以产生所谓的多头注意力。 然后将独立的注意力输出连接起来并线性转换为预期维度。

多头注意力允许以不同方式关注输入序列的各个部分(例如,长期依赖与短期依赖),因此它可以提高单一注意力的性能。

在这里插入图片描述

带n个注意力机制的多头注意力工作流程

X = [ x 1 , x 2 , … , x t ] T Q = X W Q K = X W K V = X W V head i = Attension ( Q W Q ( i ) , K W k ( i ) , V W V ( i ) ) MultiHead ( Q , K , V ) = Concat ( head 1 , … , head n ) W 0 \begin{align} X&=[x_1, x_2, \dots, x_t]^T\notag\\ Q&=XW_Q\notag\\ K&=XW_K\notag\\ V&=XW_V\notag\\ \text{head}_i&=\text{Attension}(QW_Q^{(i)},KW_k^{(i)},VW_V^{(i)})\notag\\ \text{MultiHead}(Q,K,V) &= \text{Concat}(\text{head}_1, \dots,\text{head}_n)W_0\notag \end{align} XQKVheadiMultiHead(Q,K,V)=[x1,x2,,xt]T=XWQ=XWK=XWV=Attension(QWQ(i),KWk(i),VWV(i))=Concat(head1,,headn)W0

上图中的自注意力可以换成任何类型的注意力或其他实现,只要其变量的维度匹配即可。

Transformer

给定输入嵌入 X X X 和输出嵌入 Y Y Y,一般来说,Transformer有 N N N 个编码器堆叠而成,连接到 N N N 个解码器也堆叠在一起。 没有递归或卷积,每个编码器和解码器只需要注意力(attention is all you need)。

在这里插入图片描述

带n个编码器和解码器的 Transformer 工作流程

p i , 2 j = sin ⁡ ( 1 / 1000 0 2 j / d x ) p i , 2 j + 1 = cos ⁡ ( 1 / 1000 0 2 j / d x ) X = [ x 1 , x 2 , … , x t ] T + [ P i j ] Y = [ <bos> , x 1 , … , y m ] T + [ P i j ] For  r = 1 , 2 , … , N X : = LayerNorm ( X + MultiHead ( X W Q , X W K , X W V ) ) X : = LayerNorm ( X + max ⁡ { 0 , X W 1 ( r ) + b 1 ( r ) } W 2 ( r ) + b 2 ( r ) ) For  r = 1 , 2 , … , N Y : = LayerNorm ( Y + MaskMultiHead ( Y W Q , Y W K , Y W V ) ) Y : = LayerNorm ( Y + MultiHead ( Y W Q , X W K , X W V ) ) Y : = LayerNorm ( Y + max ⁡ { 0 , Y W 3 ( r ) + b 3 ( r ) } W 4 ( r ) + b 4 ( r ) ) proba = softmax ( Y W 0 ) \begin{align} p_{i, 2j}&=\sin(1/10000^{2j/d_x})\notag\\ p_{i, 2j+1}&=\cos(1/10000^{2j/d_x})\notag\\ X&=[x_1, x_2, \dots, x_t]^T+[P_{ij}]\notag\\ Y&=[\text{<bos>},x_1, \dots, y_m]^T+[P_{ij}]\notag\\ \notag\\ \text{For }r &= 1,2,\dots,N\notag\\ \quad X&:=\text{LayerNorm}(X+\text{MultiHead}(XW_Q, XW_K,XW_V))\notag\\ \quad X&:=\text{LayerNorm}(X+\max\{0,XW_1^{(r)}+b_1^{(r)}\}W_2^{(r)}+b_2^{(r)})\notag\\ \notag\\ \text{For }r &= 1,2,\dots,N\notag\\ \quad Y&:=\text{LayerNorm}(Y+\text{MaskMultiHead}(YW_Q, YW_K,YW_V))\notag\\ \quad Y&:=\text{LayerNorm}(Y+\text{MultiHead}(YW_Q, XW_K,XW_V))\notag\\ \quad Y&:=\text{LayerNorm}(Y+\max\{0,YW_3^{(r)}+b_3^{(r)}\}W_4^{(r)}+b_4^{(r)})\notag\\ \notag\\ \text{proba} &= \text{softmax}(YW_0)\notag \end{align} pi,2jpi,2j+1XYFor rXXFor rYYYproba=sin(1/100002j/dx)=cos(1/100002j/dx)=[x1,x2,,xt]T+[Pij]=[<bos>,x1,,ym]T+[Pij]=1,2,,N:=LayerNorm(X+MultiHead(XWQ,XWK,XWV)):=LayerNorm(X+max{0,XW1(r)+b1(r)}W2(r)+b2(r))=1,2,,N:=LayerNorm(Y+MaskMultiHead(YWQ,YWK,YWV)):=LayerNorm(Y+MultiHead(YWQ,XWK,XWV)):=LayerNorm(Y+max{0,YW3(r)+b3(r)}W4(r)+b4(r))=softmax(YW0)

优点

  • 更好地表示输入token,其中token表示基于使用自注意力的特定相邻token。
  • (并行)使用所有输入token,不受顺序处理(RNN)的内存限制。

缺点

  • 计算量大。
  • 需要大量数据(可以使用预训练模型缓解)。

接下来,让我们深入理解Transformer的工作原理!

第一步. 将位置编码加入词嵌入

在这里插入图片描述
p i , 2 j = sin ⁡ ( 1 / 1000 0 2 j / d x ) p i , 2 j + 1 = cos ⁡ ( 1 / 1000 0 2 j / d x ) X = [ x 1 , x 2 , … , x t ] T + [ P i j ] Y = [ <bos> , x 1 , … , y m ] T + [ P i j ] \begin{align} p_{i, 2j}&=\sin(1/10000^{2j/d_x})\notag\\ p_{i, 2j+1}&=\cos(1/10000^{2j/d_x})\notag\\ X&=[x_1, x_2, \dots, x_t]^T+[P_{ij}]\notag\\ Y&=[\text{<bos>},x_1, \dots, y_m]^T+[P_{ij}]\notag \end{align} pi,2jpi,2j+1XY=sin(1/100002j/dx)=cos(1/100002j/dx)=[x1,x2,,xt]T+[Pij]=[<bos>,x1,,ym]T+[Pij]

由于Transformer不包含递归和卷积,为了让模型可以利用序列的顺序,我们必须注入token在序列中相对或绝对位置的信息。

因此,我们必须通过“位置编码”的方式让模型明确地知道token的位置:
p i , 2 j = sin ⁡ ( 1 / 1000 0 2 j / d x ) p i , 2 j + 1 = cos ⁡ ( 1 / 1000 0 2 j / d x ) \begin{align} p_{i, 2j}&=\sin(1/10000^{2j/d_x})\notag\\ p_{i, 2j+1}&=\cos(1/10000^{2j/d_x})\notag \end{align} pi,2jpi,2j+1=sin(1/100002j/dx)=cos(1/100002j/dx)
其中 i i i 是token的位置(#0、#1 等), j j j 是编码的列号, d x dₓ dx 是编码的维度(与输入嵌入 X X X 的维度相同 )。

下图是对编码维度为 512 512 512 的前 2048 2048 2048 个token的位置编码矩阵 P P P 的可视化。

img

与 seq2seq 模型一样,输出嵌入 Y Y Y 向右移动,第一个token是“句子开始”标记<bos>。 接着将位置编码添加到 X X X Y Y Y,然后分别发送到第一个编码器和解码器。

第二步. 编码器:多头注意力和前馈

在这里插入图片描述
For  r = 1 , 2 , … , N X : = LayerNorm ( X + MultiHead ( X W Q , X W K , X W V ) ) X : = LayerNorm ( X + max ⁡ { 0 , X W 1 ( r ) + b 1 ( r ) } W 2 ( r ) + b 2 ( r ) ) \begin{align} \text{For }r &= 1,2,\dots,N\notag\\ \quad X&:=\text{LayerNorm}(X+\text{MultiHead}(XW_Q, XW_K,XW_V))\notag\\ \quad X&:=\text{LayerNorm}(X+\max\{0,XW_1^{(r)}+b_1^{(r)}\}W_2^{(r)}+b_2^{(r)})\notag \end{align} For rXX=1,2,,N:=LayerNorm(X+MultiHead(XWQ,XWK,XWV)):=LayerNorm(X+max{0,XW1(r)+b1(r)}W2(r)+b2(r))

编码器由两部分组成:

  1. 输入嵌入 X X X ——在添加位置编码 P P P 之后——被送入多头注意力。多头注意力采用了残差连接,这意味着我们将词嵌入(或前一个编码器的输出)加到注意力的输出上。 然后将结果归一化。
  2. 归一化后,信息传入一个前馈神经网络,该网络由两层组成,分别具有 ReLU 和线性激活函数。同样,我们在此部分采用了残差连接和归一化。

编码器内部计算结束后,输出可以发送到另一个编码器,最后一个编码器将特定部分发送给每个解码器。

在这里插入图片描述

Transformer 编码器和解码器

第三步. 解码器:(掩码)多头注意力和前馈

在这里插入图片描述
For  r = 1 , 2 , … , N Y : = LayerNorm ( Y + MaskMultiHead ( Y W Q , Y W K , Y W V ) ) Y : = LayerNorm ( Y + MultiHead ( Y W Q , X W K , X W V ) ) Y : = LayerNorm ( Y + max ⁡ { 0 , Y W 3 ( r ) + b 3 ( r ) } W 4 ( r ) + b 4 ( r ) ) \begin{align} \text{For }r &= 1,2,\dots,N\notag\\ \quad Y&:=\text{LayerNorm}(Y+\text{MaskMultiHead}(YW_Q, YW_K,YW_V))\notag\\ \quad Y&:=\text{LayerNorm}(Y+\text{MultiHead}(YW_Q, XW_K,XW_V))\notag\\ \quad Y&:=\text{LayerNorm}(Y+\max\{0,YW_3^{(r)}+b_3^{(r)}\}W_4^{(r)}+b_4^{(r)})\notag \end{align} For rYYY=1,2,,N:=LayerNorm(Y+MaskMultiHead(YWQ,YWK,YWV)):=LayerNorm(Y+MultiHead(YWQ,XWK,XWV)):=LayerNorm(Y+max{0,YW3(r)+b3(r)}W4(r)+b4(r))

解码器包含三部分:

  1. 输出嵌入 Y Y Y ——在右移并添加位置编码 P P P 之后——被输入到多头注意力中。 在注意力中,我们屏蔽掉(设置为 − ∞ -\infin )softmax 输入中对应于后续位置连接的所有值。
  2. 然后信息通过另一个多头注意力——没有掩码——作为查询向量传递。 键和值向量来自最后一个编码器的输出。 这允许解码器中的每个位置都关注输入序列中的所有位置。
  3. 跟编码器一样,结果会发送到具有激活函数的前馈神经网络。

解码器内部计算的结束后,输出可以发送到另一个解码器,最后一个解码器将输出发送给分类器。

第四步. 分类器

在这里插入图片描述
proba = softmax ( Y W 0 ) \text{proba} = \text{softmax}(YW_0) proba=softmax(YW0)
这是最后一步,非常简单。 我们使用习得的线性变换和 softmax 将解码器输出转换为预测的下一个token的概率。
∗ ∗ ∗ \ast\ast\ast
Transformer 在 NLP 中取得了巨大的成功。它的出现是机器学习领域的一个里程碑。许多预训练模型(例如 GPT-2、GPT-3、BERT、XLNet 和 RoBERTa)等都是从Transformer发展而来。最近大火的ChatGPT也是以Transformer为基础,在各种 NLP 相关任务(例如机器翻译、文档摘要、文档生成、命名实体识别)和语义理解中展现了超出预期的经验表现。

总结

尽管NLP 相关任务很难,但依然有许多方法可以解决它们。最直观的是 RNN,虽然它很难并行化,且在处理长序列时会出现梯度爆炸或梯度消失。但我们还有 LSTM 和 GRU!

如何组织排列 RNN 单元有很多种方式,其中一种称为 seq2seq。 在 seq2seq 中,解码器只能看到来自最后一个编码器 RNN 单元的输入序列。这激发了注意力机制的诞生,在输出序列的每个生成步骤中,可以关注输入序列的不同部分。

随着自注意力的发展,RNN 单元被完全抛弃。被称为多头注意力的自注意力与前馈神经网络形成了Transformer ,Transformer 作为一个重要的里程碑,影响并创建了许多先进的 NLP 模型,如 GPT-3、BERT 等。

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

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

相关文章

【随笔记】Win11、RTX3070、CUDA117的深度学习机器学习环境配置

文章目录一、创建深度学习 Conda 虚拟环境二、安装 Pytorch-Gpu三、安装 PyTorch Geometric四、安装 Sklearn五、Jupyter 配置5.1 将虚拟环境加入内核5.2 插件配置5.3 主题、字体、字号配置假设你已经安装了Anaconda3&#xff08;最新Anaconda3的安装配置及使用教程&#xff08…

里程碑,ChatGPT插件影响几何?

目录插件发布网络浏览器代码解释器平台生态微软魄力总结3月15日OpenAI推出了GPT-4&#xff0c;引起了全球轰动&#xff0c;仅仅过去一周多时间&#xff0c;OpenAI又宣布推出插件功能。如果说ChatGPT是AI的“iPhone时刻”&#xff0c;那么插件就是ChatGPT的“App Store”。超强的…

SpringBoot整合Flink(施耐德PLC物联网信息采集)

SpringBoot整合Flink&#xff08;施耐德PLC物联网信息采集&#xff09;Linux环境安装kafka前情&#xff1a;施耐德PLC设备&#xff08;TM200C16R&#xff09;设置好信息采集程序&#xff0c;连接局域网&#xff0c;SpringBoot订阅MQTT主题&#xff0c;消息转至kafka&#xff0c…

【chatgpt-01】部署学术神器chatgpt_academic

目录1 chatgpt_academic简介2 前置准备3 项目下载/配置4 安装依赖5 项目配置6 运行7 测试实验性功能1 chatgpt_academic简介 chatgpt_academic是一个科研工作专用ChatGPT拓展&#xff0c;特别优化学术Paper润色体验&#xff0c;支持自定义快捷按钮&#xff0c;支持markdown表格…

Jenkins部署与自动化构建

Jenkins笔记 文章目录Jenkins笔记[toc]一、安装Jenkinsdocker 安装 JenkinsJava启动war包直接安装二、配置mavenGit自动构建jar包三、自动化发布到测试服务器运行超时机制数据流重定向编写清理Shell脚本四、构建触发器1. 生成API token2. Jenkins项目配置触发器3. 远程Git仓库配…

Elasticsearch:配置选项

Elasticsearch 带有大量的设置和配置&#xff0c;甚至可能让专家工程师感到困惑。 尽管它使用约定优于配置范例并且大部分时间使用默认值&#xff0c;但在将应用程序投入生产之前自定义配置是必不可少的。 在这里&#xff0c;我们将介绍属于不同类别的一些属性&#xff0c;并讨…

【风光场景生成】基于改进ISODATA的负荷曲线聚类算法(Matlab代码实现)

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

《计算机网络-自顶向下》04. 网络层-数据平面

文章目录网络层数据平面和控制平面两者的概述数据平面控制平面控制平面&#xff1a;传统方法控制平面&#xff1a;SDN 方法网络服务模型路由器工作原理通用路由器体系结构输入端口的功能基于目标的转发交换结构内存交换方式总线交换方式纵横式交换方式输出端口的功能何时何处出…

YOLOV8改进:如何增加注意力模块?(以CBAM模块为例)

YOLOV8改进&#xff1a;如何增加注意力模块&#xff1f;&#xff08;以CBAM模块为例&#xff09;前言YOLOV8nn文件夹modules.pytask.pymodels文件夹总结前言 因为毕设用到了YOLO&#xff0c;鉴于最近V8刚出&#xff0c;因此考虑将注意力机制加入到v8中。 YOLOV8 代码地址&am…

ChatGPT能代替Oracle DBA吗?用Oracle OCP(1z0-083)的真题测试一下。

让我们来看看ChatGPT不能通过Oracle OCP的考试&#xff1f; 文章目录引言测试过程总结和分析关于博主&#xff0c;姚远&#xff1a;Oracle ACE&#xff08;Oracle和MySQL数据库方向&#xff09;。Oracle MAA 大师。华为云MVP。《MySQL 8.0运维与优化》的作者。拥有 Oracle 10g和…

被吐槽 GitHub仓 库太大,直接 600M 瘦身到 6M,这下舒服了

大家好&#xff0c;我是小富&#xff5e; 前言 忙里偷闲学习了点技术写了点demo代码&#xff0c;打算提交到我那 2000Star 的Github仓库上&#xff0c;居然发现有5个Issues&#xff0c;最近的一条日期已经是2022/8/1了&#xff0c;以前我还真没留意过这些&#xff0c;我这人懒…

Esp8266+阿里云+STM32点灯(三)

1、简介 1、固件库烧录&#xff1a;Esp8266阿里云STM32点灯&#xff08;一&#xff09; 2、ESP8266通过电脑与阿里云通讯&#xff1a;Esp8266阿里云STM32点灯&#xff08;二&#xff09; 前两部分已经完成ESP8266和阿里云简单通讯&#xff0c;这部分通过STM32单片机通过ESP8…

vue全局使用svg

1、安装依赖 npm install svg-sprite-loader2、配置选项 在vue.config.js的chainWebpack里配置下面代码 解释&#xff1a;config.module.rule是一个方法&#xff0c;用来获取某个对象的规则。.exclude.add&#xff08;文件a&#xff09;是往禁用组添加文件a&#xff0c;就是对文…

人民链Baas服务平台上线,中创助力人民数据共建数据服务应用场景

人民链2.0是数据要素大发展时代下的可信联盟链 作为区块链分布式存储领域行业先驱与让人民放心的国家级数据云平台&#xff0c;中创算力与人民数据的合作从未间断。为了推动人民链2.0高质量发展&#xff0c;中创算力与人民数据开展了多方面合作&#xff0c;助力人民数据共建数据…

计算机网络 - 网络通信 (TCP与UDP)

前言 本篇通过了解套接字&#xff0c;TCP与UDP协议的特点&#xff0c;使用UDP的api套接字与TCP的api套接字进行回显程序的网络通信&#xff0c;如有错误&#xff0c;请在评论区指正&#xff0c;让我们一起交流&#xff0c;共同进步&#xff01; 文章目录前言1. 认识网络通信需…

JVM、JVM中的垃圾回收、类加载、IoC和DI

一、JVM 1、概念 JVM&#xff1a;Java Virtual Machine 的简称&#xff0c;意为 Java虚拟机&#xff0c;可以运行Java代码&#xff0c;是整个Java实现跨平台的最核心的部分&#xff1b;所有的Java程序会首先被编译为.class的类文件&#xff0c;这种类文件可以在虚拟机上执行&…

2022-ISCC信息安全与对抗竞赛wp-misc(详解,有脚本( •̀ ω •́ )y)

前言 没想到不知不觉一年时间就这样过去了&#xff0c;又到了一年一度的ISCC信息对抗大赛&#xff0c;不知道去年打比赛的小伙伴今年还能不能再碰到&#xff0c;期待与君再相见( •̀ ω •́ )y 所以今天就把去年的题目再复现一遍供师傅们参考 嘻嘻 目录 misc &#xff08…

2023MathorCup数模B题思路数据代码论文【全网最全分享】

文章目录赛题思路赛题详情参赛建议&#xff08;个人见解&#xff09;选择队友及任务分配问题&#xff08;重要程度&#xff1a;5星&#xff09;2023MathorCup数模B题思路数据论文代码【最新】赛题思路 (赛题出来以后第一时间在CSDN分享) 最新进度在文章最下方卡片&#xff0c;…

STM-32:I2C外设总线—硬件I2C读写MPU6050

目录一、I2C外设简介二、I2C框图三、I2C基本结构四、主机发送五、主机接收六、I2C的中断请求七、软件/硬件波形对比八、应用实例&#xff1a;硬件I2C读写MPU60508.1接线图8.2程序代码一、I2C外设简介 STM32内部集成了硬件I2C收发电路&#xff0c;可以由硬件自动执行时钟生成、…

Blender安装最新版本

目录1. Blender下载1.1 Blender硬件要求1.2 下载Blender1.3 或者下载LTS版本2. 安装向导2.1 在Windows上安装2.1.1安装msi文件(这里演示案例)2.1.2 点击“Next”2.1.3 勾选&#xff0c;点击“Next”2.1.4 点击“Next”2.1.5 点击“Install”2.1.6 安装进度2.1.7 点击“Finish”…