Transformer实战——循环神经网络详解
Transformer实战——循环神经网络详解
- 0. 前言
- 1. 基本循环神经网络单元
- 1.1 循环神经网络工作原理
- 1.2 时间反向传播
- 1.3 梯度消失和梯度爆炸问题
- 2. RNN 单元变体
- 2.1 长短期记忆
- 2.2 门控循环单元
- 2.3 Peephole LSTM
- 3. RNN 变体
- 3.1 双向 RNN
- 3.2 状态 RNN
- 4. RNN 拓扑结构
- 小结
0. 前言
循环神经网络 (Recurrent Neural Network
, RNN
) 是一类特殊的神经网络结构,广泛应用于处理和分析序列数据,如文本、语音、时间序列等。与传统的神经网络不同,RNN
具有记忆功能,可以通过循环连接处理序列中各个元素之间的依赖关系。
1. 基本循环神经网络单元
1.1 循环神经网络工作原理
传统的多层感知器神经网络假设所有输入都彼此独立,但这种假设对许多类型的序列数据并不成立。例如,句子中的单词、乐曲中的音符、随时间变化的股票价格,甚至化合物中的分子,都是一个元素的出现取决于其前面元素的序列。
循环神经网络 (Recurrent Neural Network
, RNN
) 单元通过使用隐藏状态(或记忆)来包含这种依赖关系,该隐藏状态保存到目前为止所见内容的要点。任意时刻的隐藏状态值是前一时刻的隐藏状态值和当前时刻输入值的函数,即:
h t = ϕ ( h t − 1 , x t ) h_t=\phi(h_{t-1},x_t) ht=ϕ(ht−1,xt)
其中, h t h_t ht 和 h t − 1 h_{t-1} ht−1 分别是时刻 t t t 和 t − 1 t-1 t−1 的隐藏状态值,而 x t x_t xt 是时刻 t t t 处的输入值。需要注意的是,以上方程是循环的,也就是说, h t − 1 h_{t-1} ht−1 可以用 h t − 2 h_{t-2} ht−2 和 x t − 1 x_{t-1} xt−1 表示,依此类推,直至序列的开始,这就是 RNN
编码和整合任意长度序列的信息的方式。
我们还可以 RNN
单元以图形方式表示,如下图所示。在时刻 t t t,单元有一个输入 x t x_t xt 和输出 o t o_t ot。输出的一部分 o t o_t ot (由隐藏状态 h t h_t ht 表示)会反馈到单元中,以便在后续时刻 t + 1 t+1 t+1 中使用。
与传统神经网络一样,学习到的参数存储为权重矩阵,RNN
的参数由三个权重矩阵 u u u、 v v v 和 w w w 定义,分别对应输入、输出和隐藏状态的权重:
上图还展示了 RNN
单元的展开视图,展开只意味着我们将网络绘制为完整序列的形式,假设网络只有三个时刻,适用于处理具有三个元素的序列。需要注意的是,权重矩阵 u u u、 v v v 和 w w w 在每个时刻之间是共享的。这是因为我们在每个时刻应用相同的操作到不同的输入上,在所有时刻共享这些权重极大的减少了 RNN
需要学习的参数数量。
我们还可以通过方程式将 RNN
描述为计算图。时刻 t t t 处的 RNN
的内部状态由隐藏向量 h t h_t ht 的值给出,该隐藏向量是权重矩阵 w w w 和时刻 t − 1 t-1 t−1 处的隐藏状态 h t − 1 h_{t-1} ht−1 的乘积,再加上权重矩阵 u u u 与时刻 t t t 处的输入 x t x_t xt 的乘积,然后通过 tanh
激活函数传递。选择 tanh
而不是 sigmoid
等其他激活函数,是因为在实践中 tanh
更有效,并有助于解决梯度消失问题。
为了方便,在描述不同类型的 RNN
结构的方程中,我们省略了显式的偏置项,将其合并到矩阵中。例如,以下 n
维空间中的直线方程,其中 w 1 w_1 w1 到 w n w_n wn 指的是直线在每个维度上的系数,偏置 b b b 指的是每个维度上的 y y y 截距:
y = w 1 x 1 + w 2 x 2 + ⋯ + w n x n + b y=w_1x_1+w_2x_2+\cdots+w_nx_n+b y=w1x1+w2x2+⋯+wnxn+b
我们可以将方程重写为矩阵形式如下:
y = w x + b y=wx+b y=wx+b
其中, w w w 是形状为 ( m , n ) (m, n) (m,n) 的矩阵, b b b 是形状为 ( m , 1 ) (m, 1) (m,1) 的向量, m m m 是数据集中的样本数, n n n 是每个样本对应的特征数。等效地,我们可以通过将 b b b 向量视为 w w w 的单位特征列,将其折叠到矩阵 w w w 中来消除向量 b b b:
y = w 1 x 1 + w 2 x 2 + ⋯ + w n x n + w 0 ( 1 ) = w ′ x y=w_1x_1+w_2x_2+\cdots+w_nx_n+w_0(1)=w'x y=w1x1+w2x2+⋯+wnxn+w0(1)=w′x
其中, w ′ w' w′ 是形状为 ( m , n + 1 ) (m, n+1) (m,n+1) 的矩阵,最后一列包含 b b b 的值,这样得到的形式更为紧凑,也更容易理解和记忆。
在时刻 t t t 处的输出向量 o t o_t ot 是权重矩阵 v v v 和隐藏状态 h t h_t ht 的乘积经过 softmax
激活得到的,得到的输出向量为输出概率:
h t = t a n h ( w h t − 1 + u x t ) o t = s o f t m a x ( v h t ) h_t= tanh(wh_{t-1} +ux_t)\\ o_t=softmax(vh_t) ht=tanh(wht−1+uxt)ot=softmax(vht)
Keras
提供了 SimpleRNN
循环层(包含基本 RNN
单元的所有逻辑),以及高级变体如长短期记忆 (Long Short Term Memory
, LSTM
) 和门控循环单元 (Gated Recurrent Unit
, GRU
)。严格来说,使用这些层构建模型并不需要理解它们的工作原理,然而,了解它们的结构和方程在需要构建专门的 RNN
单元以解决特定问题时很有帮助。
我们已经了解了数据如何通过 RNN
单元前向传播,即如何组合其输入和隐藏状态以产生输出和下一个隐藏状态,接下来,我们介绍梯度的反向传播过程,这一过程称为时间反向传播 (Backpropagation Through Time
, BPTT
)。
1.2 时间反向传播
与传统的神经网络一样,训练 RNN
也涉及到梯度的反向传播。不同之处在于,由于权重在所有时刻是共享的,每个输出的梯度不仅取决于当前时刻,还取决于之前的时刻,这一过程称为时间反向传播 (Backpropagation Through Time
, BPTT
)。由于在 RNN
中权重 u u u、 v v v 和 w w w 在不同时刻间共享,因此需要对各个时刻的梯度进行求和,这是传统反向传播和 BPTT
之间的关键区别。
例如,在如下具有五个时刻的 RNN
中。在前向传播期间,网络生成时刻 t t t 处的预测 o ^ t \hat o_t o^t,将其与标签 o t o_t ot 进行比较以计算损失 L t L_t Lt。在反向传播过程中(用虚线表示),计算每个时刻的损失对权重 u u u、 v v v 和 w w w 的梯度,并用梯度的总和更新参数:
损失函数对 w w w 的梯度如下方程所示,这个权重是导致梯度消失和梯度爆炸问题的原因。梯度消失和梯度爆炸问题表现为损失的梯度接近零或无穷大,使得网络难以训练。为了理解为什么会发生这种情况,考虑我们之前介绍的 SimpleRNN
的方程,隐藏状态 h t h_t ht 依赖于 h t − 1 h_{t-1} ht−1,而 h t − 1 h_{t-1} ht−1 又依赖于 h t − 2 h_{t-2} ht−2,依此类推:
∂ L ∂ w = ∑ t ∂ L t ∂ w \frac{\partial L}{\partial w}=\sum_t\frac{\partial L_t}{\partial w} ∂w∂L=t∑∂w∂Lt
观察时刻 t = 3 t=3 t=3 时的梯度情况,根据链式法则,损失函数相对于 w w w 的梯度可以分解为三个子梯度的乘积。隐藏状态 h 2 h_2 h2 相对于 w w w 的梯度可以进一步分解为每个隐藏状态相对于前一个隐藏状态的梯度之和。最后,每个隐藏状态相对于前一个隐藏状态的梯度可以进一步分解为当前隐藏状态相对于前一个隐藏状态的梯度的乘积:
∂ L 3 ∂ w = ∂ L 3 ∂ o ^ 3 ∂ o ^ 3 ∂ h 3 ∂ h 3 ∂ w = ∑ t = 0 3 ∂ L 3 ∂ o ^ 3 ∂ o ^ 3 ∂ h 3 ∂ h 3 ∂ h t ∂ h t ∂ w = ∑ t = 0 3 ∂ L 3 ∂ o ^ 3 ∂ o ^ 3 ∂ h 3 ( ∏ j = t + 1 3 ∂ h j ∂ h j − 1 ) ∂ h t ∂ w \frac{\partial L_3}{\partial w}=\frac{\partial L_3}{\partial \hat o_3}\frac{\partial \hat o_3}{\partial h_3}\frac{\partial h_3}{\partial w}=\sum_{t=0}^3\frac{\partial L_3}{\partial \hat o_3}\frac{\partial \hat o_3}{\partial h_3}\frac{\partial h_3}{\partial h_t}\frac{\partial h_t}{\partial w}=\sum_{t=0}^3\frac{\partial L_3}{\partial \hat o_3}\frac{\partial \hat o_3}{\partial h_3}(\prod _{j=t+1}^3\frac{\partial h_j}{\partial h_{j-1}})\frac{\partial h_t}{\partial w} ∂w∂L3=∂o^3∂L3∂h3∂o^3∂w∂h3=t=0∑3∂o^3∂L3∂h3∂o^3∂ht∂h3∂w∂ht=t=0∑3∂o^3∂L3∂h3∂o^3(j=t+1∏3∂hj−1∂hj)∂w∂ht
类似的计算同样可以用于计算损失 L 0 L_0 L0 到 L 4 L_4 L4 相对于 w w w 的梯度,并将它们累加到W的梯度更新中。
1.3 梯度消失和梯度爆炸问题
BPTT
对梯度消失和梯度爆炸问题特别敏感,原因在于表示损失相对于 w w w 的梯度的最终公式中的乘积部分。假设隐藏状态相对于前一隐藏状态的各个梯度都小于 1
。那么随着跨多个时刻进行反向传播,梯度的乘积变得越来越小,最终导致梯度消失的问题。同样地,如果梯度大于 1
,乘积会越来越大,最终导致梯度爆炸的问题。
在以上两种情况中,梯度爆炸更容易被检测到,因为梯度会变得非常大并转化为 NaN
,导致训练过程崩溃。可以通过预定义阈值裁剪梯度来控制梯度爆炸,TensorFlow
可以通过在优化器构建期间使用 clipvalue
或 clipnorm
参数裁剪梯度,或者通过 tf.clip_by_value
显式裁剪梯度。
梯度消失会导致来自较远时刻的梯度对学习过程没有贡献,因此 RNN
最终无法学习到任何长期依赖关系。尽管有多种方法可以降低梯度消失问题的影响,如正确初始化 w w w 矩阵、使用更强大的正则化、使用 ReLU
代替 tanh
激活函数以及使用无监督方法预训练 RNN
层,但最佳的解决方案是使用 LSTM
或 GRU
架构,这些架构旨在更有效地处理梯度消失问题并学习长期依赖关系。
2. RNN 单元变体
2.1 长短期记忆
长短期记忆 (Long Short Term Memory
, LSTM
) 是 SimpleRNN
单元的一种变体,能够学习数据中的长期依赖关系。LSTM
在多种问题上具有优异表现,是最广泛使用的 RNN
变体。
SimpleRNN
通过 tanh
层将前一个时刻的隐藏状态和当前输入结合起来实现循环。LSTM
也以类似的方式实现循环,但不同于单一的 tanh
,LSTM
中有四个流程以特定的方式相互作用。下图展示了在时刻 t t t 时应用于隐藏状态的变换过程:
整体来看似乎很复杂,逐个组件分解便于理解。图顶部的横线代表单元的内部状态(也称记忆) c c c。底部的横线代表隐藏状态 h h h,而 i i i、 f f f 和 o o o 门则是 LSTM
处理梯度消失问题的机制。在训练期间,LSTM
学习这些门的参数。
理解 LSTM
单元内部各个门工作机制的另一种方式是利用数学方程,这些方程描述了如何从前一时时刻的隐藏状态 h t − 1 h_{t-1} ht−1 计算时刻 t t t 的隐藏状态 h t h_t ht 的值。总的来说,基于方程的描述往往更清晰、更简洁。表示 LSTM
的方程组如下:
i = σ ( w i h t − 1 + u i x t + v i ) f = σ ( w f h t − 1 + u f x t + v f ) o = σ ( w o h t − 1 + u o x t + v o ) g = tanh w g h t − 1 + u g x t c t = ( f ∗ c t − 1 ) + ( g ∗ i ) h t = tanh ( c t ) ∗ o i=\sigma(w_ih_{t-1}+u_ix_t+v_i)\\ f=\sigma(w_fh_{t-1}+u_fx_t+v_f)\\ o=\sigma(w_oh_{t-1}+u_ox_t+v_o)\\ g=\text{tanh}w_gh_{t-1}+u_gx_t\\ c_t=(f\ast c_{t-1})+(g\ast i)\\ h_t=\text{tanh}(c_t)\ast o i=σ(wiht−1+uixt+vi)f=σ(wfht−1+ufxt+vf)o=σ(woht−1+uoxt+vo)g=tanhwght−1+ugxtct=(f∗ct−1)+(g∗i)ht=tanh(ct)∗o
其中, i i i、 f f f 和 o o o 分别表示输入门 (input gate
)、遗忘门 (forget gate
) 和输出门 (output gate
)。它们使用相同的方程计算,但使用不同的参数矩阵 ( w i w_i wi、 u i u_i ui、 w f w_f wf、 u f u_f uf 和 w o w_o wo、 u o u_o uo)。sigmoid
函数将这些门的输出限制在 0
到 1
之间,因此生成的输出向量可以与另一个向量逐元素相乘,以定义第二个向量能通过第一个向量的程度。
遗忘门定义了之前隐藏状态 h t − 1 h_t-1 ht−1 通过的量,输入门定义了新计算的当前输入 x t x_t xt 的状态通过的量,而输出门定义了将内部状态暴露给下一层的量。内部隐藏状态 g g g 是基于当前输入 x t x_t xt 和前一个隐藏状态 h t − 1 h_{t-1} ht−1 计算的。需要注意的是, g g g 的方程与 SimpleRNN
的方程相同,但在 LSTM
中会通过输入门 i i i 的输出进行调节。
给定 i i i、 f f f、 o o o 和 g g g,可以计算时间刻 t t t 的单元状态 c t c_t ct,方法是将时刻 t − 1 t-1 t−1 处的单元状态 c t − 1 c_{t-1} ct−1 乘以遗忘门 f f f 的值,再加上状态 g g g 乘以输入门 i i i 的值。这本质上是将前一个单元状态与新输入结合起来的方法,将遗忘门设为 0
可以忽略旧状态,将输入门设为 0
可以忽略新计算出的状态。最后,时刻 t t t 处的隐藏状态 h t h_t ht 计算为时刻 t t t 处的单元状态 c t c_t ct 乘以输出门 o o o。
需要注意的是,LSTM
可以直接替代 SimpleRNN
单元,区别在于 LSTM
对梯度消失问题具有更强的抵抗能力。我们可以在网络中直接使用 LSTM
替换 RNN
单元,通常情况下,网络的训练结果会更好,相应的训练时间可能会更长。TensorFlow
还提供了 ConvLSTM2D
实现,其中矩阵乘法被卷积算子取代。
2.2 门控循环单元
门控循环单元 (Gated Recurrent Unit
, GRU
) 是 LSTM
的一种变体。它保留了 LSTM
对梯度消失问题的抵抗力,但其内部结构更简单,更新其隐藏状态所需的计算更少,因此训练速度更快。
与 LSTM
单元中的输入门 i i i、遗忘门 f f f 和输出门 o o o 不同,GRU
单元具有两个门:更新门 (update gate
) z z z 和重置门 (reset gate
) r r r。更新门定义了保留多少先前状态,而重置门定义了如何将新输入与先前状态结合。与 LSTM
不同,没有像 LSTM
那样与隐藏状态不同的持久性单元状态。
GRU
单元定义了如何基于前一个时刻的隐藏状态 h t − 1 h_{t-1} ht−1 计算时刻 t t t 的隐藏状态 h t h_t ht:
z = σ ( w z h h − 1 + u z x t ) r = σ ( w r h h − 1 + u r x t ) c = tanh ( w c ( h t − 1 ∗ r ) + u c x t ) h t = ( z ∗ c ) + ( ( 1 − z ) ∗ h t − 1 ) z=\sigma(w_zh_{h-1}+u_zx_t)\\ r=\sigma(w_rh_{h-1}+u_rx_t)\\ c=\text{tanh}(w_c(h_{t-1}\ast r)+u_cx_t)\\ h_t=(z\ast c)+((1-z)\ast h_{t-1})\\ z=σ(wzhh−1+uzxt)r=σ(wrhh−1+urxt)c=tanh(wc(ht−1∗r)+ucxt)ht=(z∗c)+((1−z)∗ht−1)
更新门 z z z 和重置门 r r r 的输出都是使用前一个隐藏状态 h t − 1 h_{t-1} ht−1 和当前输入 x t x_t xt 的组合计算得到的,Sigmoid
函数将这些函数的输出值调节到 0
和 1
之间。单元状态 c c c 是重置门 r r r 和输入 x t x_t xt 的函数输出,时刻 t t t 处的隐藏状态 h t h_t ht 是单元状态 c c c 和前一个隐藏状态 h t − 1 h_{t-1} ht−1 的函数输出。参数 w z w_z wz、 u z u_z uz、 w r w_r wr、 u r u_r ur、 w c w_c wc、 u c u_c uc 在训练过程中进行学习。
与 LSTM
类似,TensorFlow
也提供了 GRU
的实现,可以直接替换 RNN
单元。
2.3 Peephole LSTM
Peephole LSTM
是 LSTM
的一个变体。它在输入、遗忘和输出门上添加了窥视孔 (peephole
),使它们可以看到先前的单元状态 c t − 1 c_{t-1} ct−1。在 Peephole LSTM
中,使用以下方程从上一个时刻的隐藏状态 h t − 1 h_{t-1} ht−1 计算时刻 t t t 处的隐藏状态 h t h_t ht:
i = σ ( w i h t − 1 + u i x t + v i c t − 1 ) f = σ ( w f h t − 1 + u f x t + v f c t − 1 ) o = σ ( w o h t − 1 + u o x t + v o c t − 1 ) g = tanh w g h t − 1 + u g x t c t = ( f ∗ c t − 1 ) + ( g ∗ i ) h t = tanh ( c t ) ∗ o i=\sigma(w_ih_{t-1}+u_ix_t+v_ic_{t-1})\\ f=\sigma(w_fh_{t-1}+u_fx_t+v_fc_{t-1})\\ o=\sigma(w_oh_{t-1}+u_ox_t+v_oc_{t-1})\\ g=\text{tanh}w_gh_{t-1}+u_gx_t\\ c_t=(f\ast c_{t-1})+(g\ast i)\\ h_t=\text{tanh}(c_t)\ast o i=σ(wiht−1+uixt+vict−1)f=σ(wfht−1+ufxt+vfct−1)o=σ(woht−1+uoxt+voct−1)g=tanhwght−1+ugxtct=(f∗ct−1)+(g∗i)ht=tanh(ct)∗o
需要注意的是,与 LSTM
的方程唯一的区别在于,计算输入门 i i i、遗忘门 f f f 和输出门 o o o 输出时增加了 c t − 1 c_{t-1} ct−1 项。
在以上部分中,我们介绍了多个 RNN
单元变体,这些变体用于解决基本 RNN
单元的不足以提成性能。接下来,我们将介绍 RNN
网络的架构变体,这些变体旨在满足特定的任务需求。
3. RNN 变体
在本节中,我们将探讨一些基本 RNN
架构的变体,这些变体在特定任务场景中可以提供性能改进。需要注意的是,这些策略可以应用于不同类型的 RNN
单元,以及不同的 RNN
拓扑结构。
3.1 双向 RNN
我们已经知道,在任意给定的时刻 t t t,RNN
的输出依赖于所有先前时刻的输出。然而,输出也可能依赖于未来的输出,因为我们试图预测的词或短语可能依赖于整个句子的上下文,而不仅仅是之前的词。
双向 RNN
(Bidirectional RNN
, BiRNN
) 可以解决此问题,它本质上是两个堆叠在一起的 RNN
,一个从左到右读取输入,另一个从右到左读取输入。
每个时刻的输出基于这两个 RNN
的隐藏状态,双向 RNN
允许网络对序列的开头和结尾都给予同等重视,通常能带来性能的提升:
TensorFlow
通过双向封装层提供对双向 RNN
的支持,要使 RNN
层(如 SimpleRNN
或 LSTM
等)变为双向,只需将该层包装在此封装层中。由于在 BiLSTM
中左右 LSTM
中每对单元的输出是连接在一起的,它需要返回每个单元的输出。因此,将 return_sequences
设置为 True
(默认值为 False
,意味着只从 LSTM
的最后一个单元返回输出):
self.lstm = tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(10, return_sequences=True, input_shape=(5, 10)))
3.2 状态 RNN
状态 RNN
(Stateful RNN
) 可以在训练期间跨批次保持状态。也就是说,为一批训练数据计算的隐藏状态将将会用作下一批训练数据的初始隐藏状态。这需要显式设置,因为默认情况下,TensorFlow
中的 RNN
是无状态的,并在每个批次后重置状态。将 RNN
设置为有状态意味着它可以在其训练序列中建立状态,甚至在进行预测时保持该状态。
使用状态 RNN
的优势包括网络尺寸较小且训练时间较短,缺点是我们需要负责使用反映数据周期性的批次大小来训练网络,并在每个 epoch
后重置状态。此外,在训练网络时不能打乱数据,因为数据呈现的顺序与状态网络相关。
要使用状态 RNN
层,将变量 stateful
设置为 True
。例如在生成文本任务中,使用由连续文本片段组成的数据进行训练,因此使用状态 RNN
意味着从前一个文本块生成的隐藏状态会被用于当前文本块。
4. RNN 拓扑结构
RNN
采用序列输入和输出,这意味着 RNN
单元可以以不同的方式排列,构建适合解决不同类型问题的网络。下图展示了 5
种不同的输入、隐藏层和输出配置。
一对一 (one-to-one
) 类型可以实现为一个简单的具有一个输入和一个输出的全连接网络。
一对多 (one-to-many
) 类型有一个输入并输出一个序列。这种网络可以用作从图像生成文本标签,其中训练数据集包含图像不同方面的简短文本描述,网络使用图像输入和表示图像标签的文本序列进行训练。
多对一 (many-to-one
) 类型则相反,以张量序列作为输入,输出单个张量。这种网络可以用作情感分析,它以文本块(如电影评论)作为输入,并输出文本情感类型。
多对多 (many-to-many
) 类型有两种形式。第一种更常见,称为 seq2seq
模型。在这种模型中,读取一个序列并生成代表输入序列的上下文向量,该向量用于生成输出序列。这种拓扑结构在机器翻译领域以及可以重构为机器翻译问题的问题中取得了巨大成功。第二种 many-to-many
类型具有与每个输入单元相对应的输出单元。这种类型的网络适用于输入和输出之间存在 1:1
对应关系的用例,如时间序列。这个模型与 seq2seq
模型的主要区别在于,在解码过程开始之前,输入不必完全被编码。
小结
循环神经网络 (Recurrent neural networks
, RNN
) ,RNN
是在文本输入中广泛使用的神经网络。RNN
非常灵活,已被用于解决诸如语音识别、语言建模、机器翻译、情感分析和图像字幕等问题。RNN
利用输入的序列特性,序列输入可以是文本、语音、时间序列以及任何其他元素的出现取决于其前面元素的序列。
在本节中,我们介绍了 RNN
及其变体,并学习如何使用 TensorFlow
进行实现。首先介绍了基本 RNN
单元的内部结构,以及它如何处理输入中的序列依赖关系。我们还将了解基本 RNN
单元的一些限制,并介绍两种基本 RNN
单元变体——长短期记忆 (Long Short Term Memory
, LSTM
) 和门控循环单元 (Gated Recurrent Unit
, GRU
),以及它们是如何克服基本 RNN
单元的限制的。然后,我们介绍了 RNN
层,RNN
层将 RNN
单元应用于每一时刻。RNN
可以被视为一个 RNN
单元图,每个单元对序列的连续元素执行相同的操作。我们还将进行一些简单的改进来提高性能,例如使 RNN
具有双向性或状态保留性。最后,介绍了一些标准的 RNN
拓扑结构。
相关文章:
Transformer实战——循环神经网络详解
Transformer实战——循环神经网络详解 0. 前言1. 基本循环神经网络单元1.1 循环神经网络工作原理1.2 时间反向传播1.3 梯度消失和梯度爆炸问题 2. RNN 单元变体2.1 长短期记忆2.2 门控循环单元2.3 Peephole LSTM 3. RNN 变体3.1 双向 RNN3.2 状态 RNN 4. RNN 拓扑结构小结 0. 前…...
基于Qt的app开发第九天
写在前面 笔者的课设截止时间已经越来越近了,还有不少地方的功能没有完成,所以重构一事还是放到做完整个项目、学完设计模式再考虑。目前就是继续往屎山堆屎。 需求分析 笔者的学长要做多线程,传数据的时候涉及到互斥锁之类的内容࿰…...
Baklib内容中台驱动资源管理创新
内容中台驱动智能整合 现代企业数字化进程中,内容中台通过结构化数据治理与智能算法协同,有效解决跨系统内容孤岛问题。以Baklib为例,其核心功能通过多语言支持与API接口集成能力,实现营销素材、产品文档等异构资源的统一索引与动…...
项目记录:「五秒反应挑战」小游戏的开发全过程
我正在参加CodeBuddy「首席试玩官」内容创作大赛,本文所使用的 CodeBuddy 免费下载链接:腾讯云代码助手 CodeBuddy - AI 时代的智能编程伙伴 灵感来源与目标设定 最近我突然有个小想法:想做一个简洁但富有科技感的小型游戏,最好能…...
Git本地使用小Tips
要将本地仓库 d:\test 的更新推送到另一个本地仓库 e:\test,可以使用 Git 的远程仓库功能。以下是具体步骤: 在 e:\test 中添加 d:\test 作为远程仓库 在 e:\test 目录中打开 Git Bash 或命令行,执行以下命令: git remo…...
【AWS入门】AWS身份验证和访问管理(IAM)
【AWS入门】AWS身份验证和访问管理(IAM) [AWS Essentials] AWS Identity and Access Management (IAM) By JacksonML 众所周知,AWS亚马逊云科技位列全球云计算服务第一位,并且持续为广大客户提供安全、稳定的各类云产品和服务。…...
【NLP】36. 从指令微调到人类偏好:构建更有用的大语言模型
从指令微调到人类偏好:构建更有用的大语言模型 大语言模型(LLMs)已经成为现代自然语言处理系统的核心,但单纯依赖传统语言建模目标,往往难以满足实际应用的“人类意图”。从 Instruction Tuning(指令微调&…...
蓝桥杯1447 砝码称重
问题描述 你有一架天平和 N 个砝码,这 N 个砝码重量依次是 W1,W2,⋅⋅⋅,WN。 请你计算一共可以称出多少种不同的重量? 注意砝码可以放在天平两边。 输入格式 输入的第一行包含一个整数 N。 第二行包含 N 个整数:W1,W2,W3,⋅⋅⋅,WN…...
每日c/c++题 备战蓝桥杯(洛谷P4715 【深基16.例1】淘汰赛 题解)
洛谷P4715 【深基16.例1】淘汰赛 题解 题目大意 有 (2^n) 名选手进行淘汰赛,每场比赛两人对决,能力值高者胜出;若能力值相同,则编号较小者胜出。最终决出冠军,要求输出亚军的编号。 解题思路 关键观察:…...
基于深度学习的电力负荷预测研究
一、深度学习模型框架 在当今数字化时代,基于深度学习的电力负荷预测研究正成为保障电力系统稳定、高效运行的关键领域。其模型构建是一个复杂而精妙的过程,涉及多学科知识与前沿技术的融合应用。首先,要明确电力负荷预测的目标,…...
没有 Mac,我如何用 Appuploader 完成 iOS App 上架
没有 Mac,我如何用 Appuploader 完成 iOS App 上架|一个跨平台开发者的实战笔记 在做移动开发这些年里,唯一让我频繁想砸电脑的时刻,大概就是每次要把 iOS App 上传到 App Store。 作为一个主要在 Windows 和 Linux 开发的程序员…...
卓力达手撕垫片:精密制造的创新解决方案与多领域应用
目录 引言 一、手撕垫片的技术特性与核心功能 二、手撕垫片的多领域应用 三、南通卓力达手撕垫片的核心优势 四、未来技术展望 结语 引言 手撕垫片作为一种创新型精密金属部件,凭借其“可分层剥离、快速安装”的特性,在工业制造、电子通信、航空航天等…...
[[春秋云境] Privilege仿真场景
文章目录 靶标介绍:知识点卷影拷贝(VSS) 外网任意文件读取Jenkins管理员后台rdp远程登录Gitlab apiToken 内网搭建代理 Oracle RCESeRestorePrivilege提权mimikatzspn卷影拷贝提取SAM 参考文章 靶标介绍: 在这个靶场中,您将扮演一名资深黑客…...
【工具推荐】--Git详解
本文讲诉,git命令环境的安装和git命令的介绍 Git 是一个非常流行的分布式版本控制系统,它帮助开发者管理和跟踪项目中的代码变化。通俗地说,可以认为 Git 就像是一个代码的时间机器,它记录了项目从开始到结束的每一次代码变动。 …...
在linux里上传本地项目到github中
首先先安装git,安装完git后,输入如下操作指令: 输入自己的用户名和邮箱(为注册GITHUB账号时的用户名和邮箱): git config --global user.name "111"git config --global user.email "121…...
【基础】Windows开发设置入门8:Windows 子系统 (WSL)操作入门
前言 大家熟悉的docker、Python,但对于Windows上有一套开配合开发的相对底层的环境设置,包括powershell、winget、WSL、还有开发驱动器什么的,我准备系统学一下,不然地基不牢,也盖不起冲天高楼~ 本节,介绍…...
服务器上的Nano 编辑器进行git合并
使用git pull拉取后,出现如下部分: GNU nano 2.9.3 /data/zhouy24Files/embody/DSLab-embodied-intelligence/.git/MERGE_MSG Merge branch …...
【idea 报错:java: 非法字符: ‘\ufeff‘】
执行main方法报错:: ‘\ufeff’?package cn.com 截图如下:任何一个mian都不能执行,都报这个 写出来希望大家都能快速解决这种少见的问题,还不好弄。 我是参考这篇文章就好了:idea 报错:java: 非法字符: …...
BM25(Best Matching 25)介绍与使用
BM25(Best Matching 25)是一种基于概率检索框架的改进算法,主要用于信息检索中的相关性评分。它通过引入词频饱和函数、文档长度归一化等机制,克服了传统TF-IDF算法的局限性。 一、BM25的核心原理 1. 改进TF-IDF的三大维度 词频…...
.NET 函数:检测 SQL 注入风险
以下是一个用 C# 编写的 .NET 函数,用于检测用户输入是否存在潜在的 SQL 注入风险: using System; using System.Text.RegularExpressions;public class SqlInjectionChecker {// 常见 SQL 注入关键词和模式private static readonly string[] SqlKeywor…...
远程数据采集智能网关支持下的雨洪资源分布式监测网络搭建实践
一、项目背景 随着城市化进程的加快以及气候变化的影响,雨洪水管理成为了城市基础设施建设中的重要课题。传统的雨洪水监测手段主要依赖人工巡查和固定站点监测,存在数据获取不及时、不全面,以及在恶劣天气条件下人员安全隐患等诸多问题。为…...
LinuxYUM下载笔记
在基于RPM的Linux发行版(如CentOS、RHEL、Fedora等)中,YUM(Yellowdog Updater Modified)是默认的包管理工具,用于简化软件的安装、更新和依赖管理。以下是YUM的使用指南: 一、检查YUM是否安装 …...
研读论文《Attention Is All You Need》(7)
原文 14 3.2 Attention An attention function can be described as mapping a query and a set of key-value pairs to an output, where the query, keys, values, and output are all vectors. The output is computed as a weighted sum of the values, where the weight…...
使用excel 工具做数据清洗
数据分析中有个很重要的预处理步骤,叫做「数据清洗」。 简单来说就是把数据中「脏脏的 」部分 —— 缺失的、重复的、错误的等等,给它清除掉,剩下「干净的」数据。 1、缺失数据 如果某处缺了一两个数据,最简单的方法就是 —— …...
LeetCode 217.存在重复元素
目录 题目: 题目描述: 题目链接: 思路: 思路一详解(排序): 思路二详解(Set): 思路三详解(Map): 代码: …...
Flask 与 Django 服务器部署
一、引言 在 Web 开发领域,Flask 和 Django 是 Python 生态中最受欢迎的两个 Web 框架。Flask 以其轻量级和灵活性著称,适合快速开发小型应用和 API;而 Django 则提供了全面的功能套件,包括 ORM、管理界面和认证系统,…...
Python:操作Excel按行写入
Python按行写入Excel数据,5种实用方法大揭秘! 在日常的数据处理和分析工作中,我们经常需要将数据写入到Excel文件中。Python作为一门强大的编程语言,提供了多种库和方法来实现将数据按行写入Excel文件的功能。本文将详细介绍5种常见的Python按行写入Excel数据的方法,并附上…...
架构演变 -单体到云原生
软件架构的演变是随着技术发展、业务需求和硬件条件的变化而不断迭代的过程。以下是从单体架构到现代云原生架构的典型演变路径及关键阶段特点: 一、单体架构(Monolithic Architecture) 时间阶段:2000 年代前 特点: …...
VSCode 安装教程
访问官网 Visual Studio Code 官网 打开下载的exe文件 选一个安装位置 创建桌面快捷方式 (D) 在桌面生成 VSCode 的快捷图标,方便快速启动程序。 将 “通过 Code 打开” 操作添加到 Windows 资源管理器文件上下文菜单 右键点击文件时,菜单中会新增 “通…...
开源表单设计器FcDesigner配置多语言教程
开源低代码表单设计器FcDesigner中提供了强大的多语言支持功能,允许开发者在表单中实现一键式语言切换。在现代业务应用中,多语言支持是一项基本需求,尤其在国际化产品中。 源码地址: Github | Gitee | 文档 | 在线演示 设计器中配置多语言…...
ONIE安装NOS操作说明
ONIE 安装 NOS 操作说明 1. ONIE 简介 ONIE(Open Network Install Environment)是开放网络设备的出厂预装环境,类似于服务器的PXE/BIOS,主要用于自动或手动安装网络操作系统(NOS,如SONiC、Cumulus、FBOSS等…...
fastadmin 数据导出,设置excel行高和限制图片大小
fastadmin默认导出图片全部都再一块,而且不在单元格里 话不多说,上代码 修改文件的路径: /public/assets/js/require-table.js exportOptions: {fileName: export_ Moment().format("YYYY-MM-DD"),preventInjection: false,mso…...
仿腾讯会议——音频服务器部分
1、中介者定义处理音频帧函数 2、 中介者实现处理音频帧函数 3、绑定函数映射 4、服务器定义音频处理函数 5、 服务器实现音频处理函数...
国产化替代对金融行业有哪些影响?如何应对?
在全球产业链重构与科技自主创新的时代背景下,国产化替代已从技术领域的局部探索,升级为金融行业应对复杂外部环境、夯实发展根基的战略选择。作为国家核心竞争力的重要组成部分,金融行业长期依赖国外技术设备的传统模式正面临安全性、可控性…...
包装类(1)
1.包装类的分类 1.针对八种基本数据类型相应的引用类型--包装类 2.有了类的特点,就可以调用类中的方法. 基本数据类型. 包装类 例: 手动装箱 int->Integer 手动执箱 Integer->int 注:jdk5后就可以自动装箱和拆箱 2.包装类和基本数据的转换 (1)jdk5前的…...
java中如何优雅处理多租户系统的查询?
多租户系统通常是指一个应用服务多个客户(租户),每个租户的数据需要隔离,确保数据安全和隐私。处理这样的系统需要考虑数据隔离、查询效率、代码的可维护性等方面。 首先,我应该明确多租户的实现方式。常见的多租户数据…...
Ubuntu服务器部署多语言项目(Node.js/Python)方式实践
Ubuntu服务器部署多语言项目(Node.js/Python)方式实践 服务器脚本运行方式命令行直接执行nohup后台执行进程 Screen概述安装基本操作命令启动 Screen退出当前会话(不终止进程)查看所有会话重连会话关闭会话 常用快捷键典型使用场景…...
【MySQL】基础操作
MySQL(二)基础操作 一、数据库操作 1.创建库 2.查看库 3.选中库 4.删除库 二、表操作 1.创建表 1.1[comment 注释]: 1.2,...: 2.查看表 2.1查看所有表 2.2查看表结构 3.删除表 三、记录操作 1.插入记录 1.1全列插入 1.2指定列插入 1.3…...
在 Java MyBatis 中遇到 “操作数类型冲突: varbinary 与 float 不兼容” 的解决方法
在 MyBatis 中遇到 “操作数类型冲突: varbinary 与 float 不兼容” 错误,通常是因为当字段值为 null 时,MyBatis 无法正确推断其 JDBC 类型,导致向数据库传递 null 值时类型不匹配。以下是原因分析和解决方案: 问题原因 未指定 j…...
课题推荐——扩展卡尔曼滤波(EKF)估计pmsm的位置误差
扩展卡尔曼滤波(EKF)是一种常用于非线性系统状态估计的方法,特别适用于永磁同步电机(PMSM)的位置和速度估计。EKF可以实时估计电机的转子位置误差(与实际转子位置的偏差),从而提高控…...
elasticsearch之记录es7.17升级8.17 springboot2.7.0 程序改造坑
es7.17升级8.x问题目录 一、硬件安装1-1. centos7 服务器上,删除elasticsearch7.17,安装es8.17 二、 程序改造2-1. Java API Client 8.17.52-2. 依赖引入2-3. 配置文件2-4. Java 配置类 三、根据 Elasticsearch 集群信息(版本 8.17.2…...
SpringBoot+ELK 搭建日志监控平台
ELK 简介 ELK(Elasticsearch, Logstash, Kibana)是一个目前主流的开源日志监控平台。由三个主要组件组成的: Elasticsearch: 是一个开源的分布式搜索和分析引擎,可以用于全文检索、结构化检索和分析,它构建…...
家庭数字生态构建实战:基于飞牛fnOS的智能家居数据中台搭建全流程解析
文章目录 前言1. VMware安装飞牛云(fnOS)1.1 打开VMware创建虚拟机1.3 初始化系统 2. 安装Cpolar工具3. 配置远程访问地址4. 远程访问飞牛云NAS5. 固定远程访问地址 前言 在数字生活时代,数据管理正成为每个家庭的刚需。今天要向大家重点推荐…...
博客系统功能测试
博客系统网址:http://8.137.19.140:9090/blog_list.html 主要测试内容 功能测试、界面测试、性能测试、易用性测试、安全测试、兼容性测试、弱网测试、安装卸载测试、压力测试… 测试方法及目的 利用selenium和python编写测试脚本,对博客系统进行的相关…...
抽奖相关功能测试思路
1. 抽奖系统功能测试用例设计(登录 每日3次 中奖40% 道具兑换码) ✅ 功能点分析 必须登录后才能抽奖每天最多抽奖3次抽奖有 40% 概率中奖中奖返回兑换码 ✅ 测试用例设计 编号 用例描述 前置条件 操作 预期结果 TC01 未登录时抽奖 未登录 …...
paddle ocr本地化部署进行文字识别
一、Paddle 简介 1. 基本概念 Paddle(全称 PaddlePaddle,飞桨)是百度开发的 开源深度学习平台,也是中国首个自主研发、功能丰富、技术领先的工业级深度学习平台。它覆盖了深度学习从数据准备、模型训练、模型部署到预测的全流程…...
在CentOS系统上部署GitLabRunner并配置CICD自动项目集成!
在CentOS系统上部署GitLabRunner并配置CICD自动项目集成 在CentOS系统上部署GitLab Runner并配置CI/CD自动项目集成GitLab CI/CD是一个强大的持续集成和持续部署工具,能够显著提高开发团队的效率。 本文将详细介绍如何在CentOS系统上部署GitLab Runner,…...
python学习day2(未写完,明天继续补充)
今天主要学习了变量的数据类型,以及如何使用格式化符号进行输出。 一、认识数据类型 在python里为了应对不同的业务需求,也把数据分为不同的类型。 代码如下: """ 1、按类型将不同的变量存储在不同的类型数据 2、验证这些…...
深度强化学习框架DI-engine
深度强化学习框架DI-engine 一、DI-engine概述:决策智能的通用引擎 DI-engine是由OpenDILab开源的决策智能引擎,基于PyTorch和JAX构建,旨在为强化学习(RL)、模仿学习(IL)、离线学习等场景提供…...
gitlab迁移
需求:需要将A服务器上的 gitlab 迁移到B服务器上,均使用docker 部署 一、备份数据 进入到A服务器的 gitlab 的容器中,运行gitlab-rake gitlab:backup:create 该命令会在 /var/opt/gitlab/backups/ 目录下创建一个xxx_gitlab_backup.tar 压缩…...