当前位置: 首页 > news >正文

从RNN讲起(RNN、LSTM、GRU、BiGRU)——序列数据处理网络

文章目录

  • RNN(Recurrent Neural Network,循环神经网络)
    • 1. 什么是RNN?
    • 2. 经典RNN的结构
    • 3. RNN的主要特点
    • 4. RNN存在问题——长期依赖(Long-TermDependencies)问题
  • LSTM(Long Short-Term Memory,长短期记忆网络)
    • 1. 什么是LSTM?
    • 2. LSTM的网络结构
      • 2.1 与RNN的不同之处
      • 2.2 LSTM核心
      • 2.3 遗忘门(Forget Gate)
      • 2.4 输入门(Input Gate)
      • 2.5 细胞状态
      • 2.6 输出门(Output Gate)
    • 3. LSTM网络结构总结
    • 4. 梯度消失与爆炸问题
  • GRU(Gate Recurrent Unit,门控循环单元)
    • 1. 什么是GRU?
    • 2. GRU的网络结构
      • 2.1 重置门(Reset Gate)
      • 2.2 更新门(Update Gate)
      • 2.3 候选记忆状态(candidate memory)
      • 2.4 最终记忆状态(hidden state)
    • 3. GRU网络结构总结
    • 4. GRU为何能够缓解梯度消失?
  • BiGRU(双向GRU)
  • 参考文献

RNN(Recurrent Neural Network,循环神经网络)

1. 什么是RNN?

循环神经网络是一类用于处理序列数据的神经网络,它一般以序列数据作为输入,通过网络内部的结构设计有效地捕捉序列之间的关系,以序列的形式输出。与传统的前馈神经网络不同,RNN具有"记忆"能力,通过在网络中引入循环连接,使得其可以利用先前的输入信息来影响当前的输出。这使得RNN非常适合处理具有时间依赖性或顺序性的任务


2. 经典RNN的结构

在介绍RNN之前,需要先了解最基本的单层网络,结构如图所示: 在这里插入图片描述

其含义是:输入 x x x,经过变换 W x + b Wx+b Wx+b 和激活函数 f f f,得到输出 y y y
常用激活函数主要有:在这里插入图片描述

在实际应用中,我们会遇到很多序列型的数据:在这里插入图片描述

以自言语言处理问题为例,简单来说,这可以看成是一句话, x 1 x_1 x1可以看做是第一个单词, x 2 x_2 x2可以看做是第二个单词,以此类推。


为了建模这种序列问题,RNN引入了 隐藏状态(hidden state) h h h 的概念。隐状态 h h h可以对序列类型的数据提取特征,然后再转换为输出。

h 1 h_1 h1 的计算为例:在这里插入图片描述
其中:圆圈或方框表示的是向量一个箭头就表示对该向量做一次变换 (例如上图中表示对 h 0 h_0 h0 x 1 x_1 x1 各做了一次变换)。

具体来说, h 1 h_1 h1 是基于上一个隐藏层的状态 h 0 h_0 h0 和当前的输入 x 1 x_1 x1 计算得到来的。泛化到任意时刻就是 h t = f ( W h t − 1 + U x t + b t ) h_t = f(Wh_{t-1}+Ux_t+b_t) ht=f(Wht1+Uxt+bt),这里激活函数 f f f 一般是tanh、sigmoid、ReLU等非线性激活函数。在实践中, h t h_t ht 一般只包含前面若干步而不是所有步的隐藏状态。

h 2 h_2 h2 的计算与 h 1 h_1 h1 相似:在这里插入图片描述

计算时,每一步使用的参数U、W、b都是一样的,也就是说每个步骤的参数是共享的,这是RNN的重要特点。 而在LSTM中权重是不共享的。
那为什么RNN的权值是共享的呢?是因为RNN的权值是在同一个向量中,只是不同的时刻而已。【进一步解释权重共享,指的是 x i x_i xi 在不同的时刻 i i i 乘的一直都是 U h i h_i hi 在不同的时刻 i i i 乘的一直都是 W。在 LSTM 中因为多出了门的概念,每个门对应的 W是不同的(即不同的门权重不共享),但是相同的门之间的 W 是共享的。】


依次计算剩下的(使用相同的参数U、W和b):在这里插入图片描述

到此,我们得到了所有的隐藏状态 h 1 h_1 h1 h 2 h_2 h2 h 3 h_3 h3 h 4 h_4 h4

RNN的输出通过隐藏状态进行计算:在这里插入图片描述

正如前面提到的,一个箭头就表示对向量做一次类似于 f ( W x + b ) f(Wx+b) f(Wx+b) 的变换,这里箭头表示对 h 1 h_1 h1 进行一次变换,得到输出 y 1 y_1 y1
剩下的输出可以类似得到(使用相同的参数 V 和 c):在这里插入图片描述

到此为止,得到了所有的输出,这就是经典的RNN结构,输入和输出序列是等长的。


通过上面的描述,我们知道RNN是包含循环的网络,在这个循环的结构中,每个神经网络的模块,读取到某个输入 x t x_t xt,并输出一个值 y t y_t yt,然后不断循环,使得信息可以从当前步传递到下一步。RNN可以被看做是同一神经网络的多次复制,每个神经网络模块会把消息传递给下一个,将这个循环展开:

在这里插入图片描述

链式的特征揭示了RNN本质上是与序列相关的,它们是对这类数据的最自然的神经网络架构。


3. RNN的主要特点

循环连接:RNN的核心在于它的循环连接,即网络的输出会作为下一个时间步的输入,这使得网络能够保持对之前信息的记忆。

参数共享:在RNN中,无论序列的长度如何,使用的权重和参数是共享的。

记忆能力:RNN能够记住序列中的信息,这使得它在处理时间序列数据、自然语言处理等领域表现出色。


4. RNN存在问题——长期依赖(Long-TermDependencies)问题

有时候,我们仅仅需要知道先前的信息来执行当前的任务。例如,我们有一个语言模型用来基于先前的词来预测下一个词。如果我们试着预测这句话中 “the clouds are in the sky” 最后的这个词 “sky”,我们并不再需要其他的信息,因为很显然下一个词应该是sky。在这样的场景中,相关的信息和预测的词位置之间的间隔是非常小的,RNN可以学会使用先前的信息
在这里插入图片描述

但是同样会有一些更加复杂的场景。比如我们试着去预测 “I grew up in France…I speak fluent French” 最后的词 “French”。当前的信息建议下一个词可能是一种语言的名字,但是如果我们需要弄清楚是什么语言,我们是需要先前提到的离当前位置很远的 “French” 的上下文。这说明相关信息和当前预测位置之间的间隔就肯定变得相当的大。不幸的是,在这个间隔不断增大时,RNN会丧失学习到连接如此远的信息的能力。
在这里插入图片描述

换句话说, RNN 会受到短时记忆的影响。如果一条序列足够长,那它们将很难将信息从较早的时间步传送到后面的时间步。

因此,如果你正在尝试处理一段文本进行预测,RNN 可能从一开始就会遗漏重要信息。在反向传播期间(反向传播本质是通过不断缩小误差去更新权值,从而不断去修正拟合的函数),RNN 会面临梯度消失的问题。

因为梯度是用于更新神经网络的权重值(新的权值 = 旧权值 - 学习率*梯度),梯度会随着时间的推移不断下降减少,而当梯度值变得非常小时,就不会继续学习。

在这里插入图片描述

换言之,在递归神经网络中,获得小梯度更新的层会停止学习—— 那些通常是较早的层。 由于这些层不学习,RNN会忘记它在较长序列中以前看到的内容,因此RNN只具有短时记忆

而梯度爆炸则是因为计算的难度越来越复杂导致。

然而,幸运的是,有个RNN的变体——LSTM,可以在一定程度上解决梯度消失和梯度爆炸这两个问题!



LSTM(Long Short-Term Memory,长短期记忆网络)

1. 什么是LSTM?

长短期记忆网络(LSTM, Long Short-Term Memory)是一种特殊的循环神经网络RNN,设计用来解决传统RNN在处理长序列数据时遇到的梯度消失和梯度爆炸问题。

LSTM 网络的核心是三个门的机制:遗忘门(forget gate)输入门(input gate)输出门(output gate)。这些门通过自适应的方式控制信息的流动,从而实现对长期依赖信息的捕捉。

2. LSTM的网络结构

2.1 与RNN的不同之处

所有的RNN都具有一种重复神经网络模块的链式的形式。在标准的RNN中,这个重复的模块只有一个非常简单的结构,例如一个tanh层。

激活函数tanh的作用在于帮助调节流经网络的值,使得数值始终限制在-1到1之间。在这里插入图片描述

在这里插入图片描述

LSTM也同样是这种结构,但是重复的模块有一个不同的结构。具体来说,RNN重复单一的神经网络层,LSTM中的重复模块则包含四个交互的层,三个Sigmoid和一个tanh层,并以一种非常特殊的方式进行交互。

图中,每一条黑线传输着一整个向量,从一个节点的输出到其他节点的输入。粉色的圈代表pointwise的操作,诸如向量的和,而黄色的矩阵就是学习到的神经网络层。合在一起的线表示向量的连接,分开的线表示内容被复制,然后分发到不同的位置。
在这里插入图片描述

在这里插入图片描述

上图中,σ表示Sigmoid 激活函数,与tanh不同,sigmoid把值压缩到0到1之间。在这里插入图片描述

这样的设置有助于更新或忘记信息:

  • 因为任何数乘以 0 都得 0,这部分信息就会剔除掉;
  • 同样的,任何数乘以 1 都得到它本身,这部分信息就会完美地保存下来

相当于要么是1则记住,要么是0则忘掉,所以还是这个原则:因记忆能力有限,记住重要的,忘记无关紧要的。

2.2 LSTM核心

记忆细胞(Memory Cell) 是LSTM网络的核心,负责在整个序列处理过程中保持和更新长期依赖信息。记忆单元的结构相对简单,主要由一个或多个神经元组成,其状态通过时间步传递,仅通过线性方式更新。

在这里插入图片描述
LSTM有通过精心设计的称作为“门”的结构来去除或者增加信息到记忆细胞状态的能力。门是一种让信息选择式通过的方法。他们包含一个sigmoid神经网络层和一个pointwise乘法的非线性操作。

0代表“不许任何量通过”,1就指“允许任意量通过”!从而使得网络就能了解哪些数据是需要遗忘,哪些数据是需要保存。在这里插入图片描述


2.3 遗忘门(Forget Gate)

LSTM第一步是决定我们会从细胞状态中丢弃什么信息,这个决定通过一个称为 “遗忘门” 的结构完成。

遗忘门会读取上一个输出 h t − 1 h_{t-1} ht1 和当前输入 x t x_t xt,做一个sigmoid的非线性映射,然后输出一个向量 f t f_t ft(该向量每一个维度的值都在0到1之间,1表示完全保留,0表示完全舍弃,相当于记住了重要的,忘记了无关紧要的),最后与细胞状态 C t − 1 C_{t-1} Ct1 相乘。

在这里插入图片描述

  • W f W_f Wf 权值是不共享的: f t = σ ( W f h h t − 1 + W f x x t + b f ) f_t = \sigma(W_{fh}h_{t-1}+W_{fx}x_t+b_f) ft=σ(Wfhht1+Wfxxt+bf)

2.4 输入门(Input Gate)

这一步是确定什么样的新信息被存放在细胞状态中。包含两个部分:

  • sigmoid层决定哪些值将要更新
  • tanh层创建一个新的候选值向量 C ~ t \tilde C_t C~t,该向量被加入状态中。

在这里插入图片描述

  • i t = σ ( W i h h t − 1 + W i x x t + b i ) i_t = \sigma(W_{ih}h_{t-1}+W_{ix}x_t+b_i) it=σ(Wihht1+Wixxt+bi)
  • C ~ t = t a n h ( W C h h t − 1 + W C x x t + b C ) \tilde C_t=tanh(W_{Ch}h_{t-1}+W_{Cx}x_t+b_C) C~t=tanh(WChht1+WCxxt+bC)

2.5 细胞状态

更新旧细胞状态, C t − 1 C_{t-1} Ct1 更新为 C t C_t Ct

我们把旧状态与 f t f_t ft 相乘,丢弃掉我们确定需要丢弃的信息,接着加上 i t ∗ C ~ t i_t * \tilde C_t itC~t,这就是新的候选值。

在这里插入图片描述

2.6 输出门(Output Gate)

最终,输出门负责决定记忆单元状态的哪一部分将被输出到隐藏状态。包含两个操作:

  • sigmoid层确定细胞状态的哪个部分将输出
  • tanh层处理细胞状态(得到一个-1到1之间的值),并将其与sigmoid门的输出相乘

在这里插入图片描述

  • o t = σ ( W o h h t − 1 + W o x x t + b o ) o_t=\sigma(W_{oh}h_{t-1}+W_{ox}x_t+b_o) ot=σ(Wohht1+Woxxt+bo)

3. LSTM网络结构总结

在这里插入图片描述

  • 遗忘门:决定从单元状态中丢弃哪些信息 f t = σ ( W f ⋅ [ h t − 1 , x t ] + b f ) f_t=\sigma\left(W_f\cdot[h_{t-1},x_t] + b_f\right) ft=σ(Wf[ht1,xt]+bf)
  • 输入门:两部分组成:sigmoid层决定哪些值将被更新,tanh层创建一个新的候选值向量 i t = σ ( W i ⋅ [ h t − 1 , x t ] + b i ) C ~ t = tanh ⁡ ( W C ⋅ [ h t − 1 , x t ] + b C ) \begin{aligned}i_{t}&=\sigma\left(W_i\cdot[h_{t-1},x_t] + b_i\right)\\\tilde{C}_{t}&=\tanh(W_C\cdot[h_{t-1},x_t] + b_C)\end{aligned} itC~t=σ(Wi[ht1,xt]+bi)=tanh(WC[ht1,xt]+bC)
  • 细胞状态:更新结合了遗忘门和输入门的信息 C t = f t ∗ C t − 1 + i t ∗ C ~ t C_t=f_t*C_{t-1}+i_t*\tilde{C}_t Ct=ftCt1+itC~t
  • 输出门:决定输出哪些信息,同时输出的值通过tanh函数进行缩放 o t = σ ( W o [ h t − 1 , x t ] + b o ) h t = o t ∗ tanh ⁡ ( C t ) \begin{aligned}&o_{t}=\sigma\left(W_o [ h_{t-1},x_t] + b_o\right)\\&h_{t}=o_t*\tanh\left(C_t\right)\end{aligned} ot=σ(Wo[ht1,xt]+bo)ht=ottanh(Ct)

4. 梯度消失与爆炸问题

在标准的RNN中,梯度消失或爆炸问题是一个常见的问题,这会导致网络难以学习长期依赖关系。LSTM通过引入门控机制来解决这个问题。

梯度消失意味着随着时间的推移,梯度值逐渐减小,导致网络权重更新非常缓慢。梯度爆炸则是指梯度值随着时间的推移而变得非常大,导致权重更新过于剧烈,从而影响学习过程。

LSTM通过以下方式缓解这些问题:

  • 遗忘门允许网络有选择性地保留或遗忘信息,这有助于防止无关信息的积累。
  • 输入门允许网络更新单元状态,但仅当新输入与单元状态相关时。

通过这种方式,LSTM可以维持梯度在一个合理的范围内,避免消失或爆炸。

此外,现代的优化算法,如Adam或RMSprop,也可以有效缓解这些问题,它们通过调整学习率来适应每个参数的更新需求。



GRU(Gate Recurrent Unit,门控循环单元)

1. 什么是GRU?

GRU(Gate Recurrent Unit)门控循环单元,是循环神经网络(RNN)的变体,与LSTM类似,通过门控单元解决RNN中不能长期记忆和反向传播中的梯度等问题。

简单来说,GRU简化了LSTM的结构,将遗忘门和输入门合并为一个单一的 “更新门”,并且合并了细胞状态和隐藏状态。

GRU的核心思想是减少模型参数,同时保持对长短期依赖的记忆能力。


2. GRU的网络结构

在这里插入图片描述

更新门 z t z_t zt 和重置门 r t r_t rt 都是对 h t − 1 h_{t-1} ht1 x t x_t xt 做的sigmoid非线性映射,区别在哪?

更新门控制信息的流动,而重置门则决定了之前的记忆有多少应该被保留。

2.1 重置门(Reset Gate)

重置门记为 r t r_t rt,这个门决定了之前的记忆有多少应该被保留(或者理解为控制以往状态的影响程度)。也就是说,重置门控制着前一状态的信息 h t − 1 h_{t-1} ht1 传入候选状态 h t h_t ht 的比例,重置门 r t r_t rt 的值越小,则与 h t − 1 h_{t-1} ht1 的乘积越小, h t − 1 h_{t-1} ht1 的信息添加到 h t h_t ht 的越少。

计算时会结合前一时间步的隐藏状态 h t − 1 h_{t-1} ht1 和当前输入 x t x_t xt,输出是一个0到1之间的值。值越接近1表示越多地保留之前的状态,越接近0表示遗忘更多旧状态。对应的数学表达如下:
r t = σ ( W r ⋅ [ h t − 1 , x t ] ) r_t=\sigma (W_r\cdot[h_{t-1},x_t]) rt=σ(Wr[ht1,xt])

2.2 更新门(Update Gate)

更新门记为 z t z_t zt,这个门决定了上一时间步的记忆状态有多少需要传递到当前步,以及当前的输入信息有多少需要加到这个新的记忆状态中。也就是说,更新门用于控制前一状态的信息 h t − 1 h_{t-1} ht1 有多少保留到新状态 h t h_t ht 中,当 1 − z t 1-z_t 1zt越大,保留的信息越多。

同样,它也是基于 h t − 1 h_{t-1} ht1 x t x_t xt计算得到的。
z t = σ ( W z ⋅ [ h t − 1 , x t ] ) z_t=\sigma (W_z\cdot[h_{t-1},x_t]) zt=σ(Wz[ht1,xt])

2.3 候选记忆状态(candidate memory)

新的候选记忆 h ~ t \tilde h_t h~t 是基于当前输入 x t x_t xt、上一时间步的隐藏状态 h t − 1 h_{t-1} ht1 以及重置门的输出 r t r_t rt 三者得到的。其中重置门决定了如何重置旧的记忆状态,以便更好地整合新信息。
h ~ t = t a n h ( W ⋅ [ r t ∗ h t − 1 , x t ] ) \tilde h_t = tanh(W\cdot[r_t*h_{t-1},x_t]) h~t=tanh(W[rtht1,xt])

2.4 最终记忆状态(hidden state)

更新后的隐藏状态 h t h_t ht 为最终记忆状态,通过结合更新门的输出 z t z_t zt、候选记忆状态 h ~ t \tilde h_t h~t 以及上一时间步的记忆状态 h t − 1 h_{t-1} ht1 计算得出的。其中更新门决定了新旧记忆的混合比例。
h t = ( 1 − z t ) ∗ h t − 1 + z t ∗ h ~ t h_t=(1-z_t)*h_{t-1}+z_t*\tilde h_t ht=(1zt)ht1+zth~t

3. GRU网络结构总结

在这里插入图片描述

  • 重置门:控制前一个状态在当前时间步骤的计算中保留多少历史信息,帮助模型决定忽略多少之前的信息。
    • r t = σ ( W r ⋅ [ h t − 1 , x t ] ) r_t=\sigma (W_r\cdot[h_{t-1},x_t]) rt=σ(Wr[ht1,xt])
    • 输出接近于0:表示较多地忽略前一个隐状态的信息
    • 输出接近于1:表示较多地保留前一个隐状态的信息
  • 更新门:控制当前时间步的候选隐状态对最终隐状态更新的贡献程度,有助于模型决定在每一步保留多少之前时刻的信息。
    • z t = σ ( W z ⋅ [ h t − 1 , x t ] ) z_t=\sigma (W_z\cdot[h_{t-1},x_t]) zt=σ(Wz[ht1,xt])
    • 输出接近于0:表示较少地更新当前时间步的隐状态
    • 输出接近于1:表示较多地更新当前时间步的隐状态
  • 候选隐藏状态: h ~ t = t a n h ( W ⋅ [ r t ∗ h t − 1 , x t ] ) \tilde h_t = tanh(W\cdot[r_t*h_{t-1},x_t]) h~t=tanh(W[rtht1,xt])
  • 最终隐藏状态: h t = ( 1 − z t ) ∗ h t − 1 + z t ∗ h ~ t h_t=(1-z_t)*h_{t-1}+z_t*\tilde h_t ht=(1zt)ht1+zth~t

GRU通过这种方式,实现了对信息的动态过滤和更新,同时减少了模型的复杂性。由于其结构的简化,GRU在某些任务上能够更快地训练,并且在某些情况下能够与LSTM相媲美或甚至更优。

4. GRU为何能够缓解梯度消失?

在传统的RNN中,由于长时间依赖问题,反向传播过程中梯度可能会因连续乘以小于1的数而变得非常小,导致早期时间步的权重几乎不更新,这就是梯度消失问题。

而GRU通过其独特的门控机制,特别是更新门和重置门的设计,能够更加灵活地控制信息流,可以更好地捕获时间步距离很长的序列上的依赖关系。

  • 重置门有助于捕获序列中的短期依赖关系。
    • 重置门帮助模型决定忽略多少之前的信息。重置门可以用来减少那些不太相关信息的影响,从而保护模型不会把注意力放在不相关的长期依赖上。当选择忽略一些不相关的信息时,梯度将不会在这部分信息上进行传递,这有助于集中于更相关的信息,并有助于梯度完整地在其他相关部分传递。
  • 更新门有助于捕获序列中的长期依赖关系。
    • 更新门有助于模型决定在每一步中应该保留多少之前时刻的信息。它可以让模型在需要的时候保持激活状态,这样有助于后续的梯度传递而不会随时间迅速减小。如果更新门接近1,那么梯度可以在很多时间步内传递而不衰减,使得长期依赖的信息得到保留。
  • 重置门打开时,门控循环单元包含基本循环神经网络;更新门打开时,门控循环单元可以跳过子序列。

因为有了这样的机制,GRU能够在每次更新中将梯度既不是完全传递也不是完全阻断,而是能够在相关的部分进行传递。这样在优化过程中,即使对于较长的序列,也能够更加稳定地保留梯度,防止了梯度极端消失,这对于学习长期依赖至关重要。因此,GRU往往在处理长序列数据时比传统RNN更加有效。



BiGRU(双向GRU)

BiGRU(双向门控循环单元)是一种改进的循环神经网络(RNN)结构,它由两个独立的GRU层组成,一个沿正向处理序列,另一个沿反向处理序列。这种双向结构使得BiGRU能够捕捉到序列中的长距离依赖关系,从而提高模型的性能。

在这里插入图片描述

首先,对于一个输入序列 X = x 1 , x 2 , … , x T X = x_1,x_2,\dots,x_T X=x1,x2,,xT,BiGRU模型的前向计算可以表示为:
h t → = G R U ( h t − 1 → , x t ) h t ← = G R U ( h t + 1 ← , x t ) \overrightarrow{h_t}=\mathrm{GRU}(\overrightarrow{h_{t-1}},x_t)\\\\\overleftarrow{h_t}=\mathrm{GRU}(\overleftarrow{h_{t+1}},x_t) ht =GRU(ht1 ,xt)ht =GRU(ht+1 ,xt)

其中, h t → \overrightarrow{h_t} ht h t ← \overleftarrow{h_t} ht 分别表示从左到右和从右到左的隐藏状态, G R U GRU GRU 表示GRU单元, x t x_t xt 表示输入序列中的第 t t t 个元素。

然后,将两个方向的隐藏状态拼接在一起,得到最终的隐藏状态 h t h_t ht
h t = [ h t → ; h t ← ] h_t=[\overrightarrow{h_t};\overleftarrow{h_t}] ht=[ht ;ht ]
其中, [ ⋅ ; ⋅ ] [\cdot;\cdot] [;] 表示向量的拼接操作。

最后,将隐藏状态 h t h_t ht 传递给一个全连接层,得到输出 y t y_t yt
y t = s o f t m a x ( W h t + b ) y_t=\mathrm{softmax}(Wh_t+b) yt=softmax(Wht+b)



参考文献

  1. 循环神经网络(Recurrent Neural Networks)
  2. 如何从RNN起步,一步一步通俗理解LSTM
  3. 【深度学习:Recurrent Neural Networks】循环神经网络(RNN)的简要概述
  4. 神经网络之lstm
  5. 循环神经网络 RNN、LSTM、GRU
  6. 人工智能(pytorch)搭建模型12-pytorch搭建BiGRU模型

相关文章:

从RNN讲起(RNN、LSTM、GRU、BiGRU)——序列数据处理网络

文章目录 RNN(Recurrent Neural Network,循环神经网络)1. 什么是RNN?2. 经典RNN的结构3. RNN的主要特点4. RNN存在问题——长期依赖(Long-TermDependencies)问题 LSTM(Long Short-Term Memory&a…...

python:假的身份信息生成模块faker

前言 发现一个有趣的python模块(faker),他支持生成多个国家语言下的假身份信息,包含人名、地址、邮箱、公司名、电话号码、甚至是个人简历! 你可以拿它做一些自动化测试,或一些跟假数据有关的填充工作。 代…...

spring task的使用场景

spring task 简介 spring task 是spring自带的任务调度框架按照约定的时间执行某个方法的工具,类似于闹钟 应用场景 cron表达式 周和日两者必定有一个是问号 简单案例...

美畅物联丨剖析 GB/T 28181 与 GB 35114:视频汇聚领域的关键协议

我们在使用畅联云平台进行视频汇聚时,经常会用的GB/T 28181协议,前面我们写了关于GB/T 28181的相关介绍,​ 详见《畅联云平台|关于GB28181你了解多少?》。 ​最近也有朋友向我们咨询GB 35114协议与GB/T 28181有什么不同…...

uni-app 开发的应用快速构建成鸿蒙原生应用

uni-app 是一个使用 Vue.js 开发所有前端应用的框架,它支持编译到 iOS、Android、小程序等多个平台。对于 HarmonyOS(鸿蒙系统),uni-app 提供了特定的支持,允许开发者构建鸿蒙原生应用。 一、uni-app 对 HarmonyOS 的支…...

代码随想录算法训练营| 669. 修剪二叉搜索树 、 108.将有序数组转换为二叉搜索树 、 538.把二叉搜索树转换为累加树

669. 修剪二叉搜索树 题目 参考文章 思路:这题其实就是删除不符合上下边界的节点。注意:这里删除不符合上下边界节点时,这个不符合上下边界的节点的左或右子树可能存在符合上下边界的节点,所i有每次比较完之后,要继…...

Django模型实现外键自关联

Django模型实现外键自关联 1、场景 省市区、评论 2、模型models.py from django.db import models 资讯评论:资讯,用户,是否取消,时间class CommentInfomation(models.Model):info = models...

Android ViewModel

一问:ViewModel如何保证应用配置变化后能够自动继续存在,其原理是什么,ViewModel的生命周期和谁绑定的? ViewModel 的确能够在应用配置发生变化(例如屏幕旋转)后继续存在,这得益于 Android 系统的 ViewMod…...

优先算法1--双指针

“一念既出,万山无阻。”加油陌生人! 目录 1.双指针--移动零 2.双指针-复写零 ok,首先在学习之前,为了方便大家后面的学习,我们这里需要补充一个知识点,我这里所谓的指针,不是之前学习的带有…...

利用弹性盒子完成移动端布局(第二次实验作业)

需要实现的效果如下&#xff1a; 下面是首先是这个项目的框架&#xff1a; 然后是html页面的代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"wid…...

C# 字符串(string)三个不同的处理方法:IsNullOrEmpty、IsInterned 、IsNullOrWhiteSpace

在C#中&#xff0c;string.IsNullOrEmpty、string.IsInterned 和 string.IsNullOrWhiteSpace 是三个不同的字符串处理方法&#xff0c;它们各自有不同的用途&#xff1a; 1.string.IsNullOrEmpty&#xff1a; 这个方法用来检查字符串是否为null或者空字符串&#xff08;"…...

读书笔记 - 虚拟化技术 - 0 QEMU/KVM概述与历史

《QEMU/KVM源码解析与应用》 - 王强 概述 虚拟化简介 虚拟化思想 David Wheeler&#xff1a;计算机科学中任何问题都可以通过增加一个中间层来解决。 虚拟化思想存在与计算机科学的各个领域。 主要思想&#xff1a;通过分层将底层的复杂&#xff0c;难用的资源虚拟抽象为简…...

常见的负载均衡

1.常见的负载均衡服务 负载均衡服务是分布式系统中用于分配网络流量和请求的关键组件&#xff0c;它可以帮助提高应用程序的可用性、可扩展性和响应速度。以下是一些常用的负载均衡服务&#xff1a; Nginx&#xff1a;一个高性能的Web服务器和反向代理&#xff0c;广泛用于实现…...

利用sessionStorage收集用户访问信息,然后传递给后端

这里只是简单的收集用户的停留时间、页面加载时间、当前页面URL及来源页面&#xff0c;以做示例 <html><head><meta http-equiv"content-type" content"text/html; charsetUTF-8"/><title>测试sessionStorage存储用户访问信息<…...

什么是Qseven?模块电脑(核心板)规范标准简介二

1.概念 Qseven是一种通用的、小尺寸计算机模块标准&#xff0c;适用于需要低功耗、低成本和高性能的应用。 Qseven模块电脑&#xff08;核心板&#xff09;采用230Pin金手指连接器 2.Qseven的起源 Qseven最初是由Congatec、SECO、MSC三家欧洲公司于2008年发起&#xff0c;旨在…...

leetcode数组(三)-有序数组的平方

题目 . - 力扣&#xff08;LeetCode&#xff09; 给你一个按 非递减顺序 排序的整数数组 nums&#xff0c;返回 每个数字的平方 组成的新数组&#xff0c;要求也按 非递减顺序 排序。 例1 输入&#xff1a;nums [-4,-1,0,3,10] 输出&#xff1a;[0,1,9,16,100] 解释&#…...

HCIP-HarmonyOS Application Developer 习题(五)

1、以下哪种原子化布局能力属于自适应变化能力? A. 拉伸 B.占比 C. 隐藏 D.拆行 答案&#xff1a;A 分析&#xff1a;划分为“自适应变化能力”和“自适应布局能力”两类。 其中&#xff0c;自适应变化能力包含了缩放能力和拉伸能力&#xff0c;自适应布局能力包含了隐藏、折…...

【详细教程】如何使用YOLOv11进行图像与视频的目标检测

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…...

H7-TOOL的LUA小程序教程第14期:任意波形信号发生器,0-20mA输出和微型数控电源(2024-10-11,已更新)

LUA脚本的好处是用户可以根据自己注册的一批API&#xff08;当前TOOL已经提供了几百个函数供大家使用&#xff09;&#xff0c;实现各种小程序&#xff0c;不再限制Flash里面已经下载的程序&#xff0c;就跟手机安装APP差不多&#xff0c;所以在H7-TOOL里面被广泛使用&#xff…...

Redis面试篇3

1、Redis的数据类型&#xff0c;以及每种数据类型的使用场景&#xff1f; 常见的几种数据类型和使用场景如下&#xff1a; 字符串(String)&#xff1a;字符串类型是Redis最基本的数据结构&#xff0c;一个键最大能存储512MB。 使用场景&#xff1a;适用于计数器、分布式锁、缓…...

集成方案 | 借助 Microsoft Copilot for Sales 与 Docusign,加速销售流程!

加速协议信息提取&#xff0c;随时优化邮件内容~ 在当今信息爆炸的时代&#xff0c;销售人员掌握着丰富的数据资源。他们能够通过 CRM 平台、电子邮件、合同库以及其他多种记录系统&#xff0c;随时检索特定个人或组织的关键信息。这些数据对于销售沟通至关重要。然而&#x…...

k8s 1.28.2 集群部署 MinIO 分布式集群

文章目录 [toc]MinIO 介绍MinIO 生产硬件要求MinIO 存储要求MinIO 内存要求MinIO 网络要求MinIO 部署架构分布式 MinIO复制的 MinIO 部署 MinIO创建目录节点打标签创建 namespace创建 pv创建 MinIO配置 ingress问题记录通过代理服务器访问 MinIO 的 Object Browser 界面一直显示…...

HAL库常用的函数:

目录 HAL库&#xff1a; 1.GPIO常用函数&#xff1a; 1.HAL_GPIO_ReadPin( ) 2.HAL_GPIO_WritePin( ) 3.HAL_GPIO_TogglePin( ) 4.HAL_GPIO_EXTI_IRQHandler( ) 5.HAL_GPIO_EXTI_Callback( ) 2.UART常用函数&#xff1a; 1.HAL_U…...

如何捕捉行情爆发的前兆

在金融市场的激烈角逐中&#xff0c;每一次行情的爆发都是投资者获取丰厚回报的关键时刻。然而&#xff0c;如何识别并把握这些时刻&#xff0c;却是一门需要深厚金融专业知识和敏锐洞察力的艺术。今天&#xff0c;我们就来深入探讨行情爆发的初期信号&#xff0c;揭示那些能够…...

【万字长文】Word2Vec计算详解(一)CBOW模型

【万字长文】Word2Vec计算详解&#xff08;一&#xff09;CBOW模型 写在前面 本文用于记录本人学习NLP过程中&#xff0c;学习Word2Vec部分时的详细过程&#xff0c;本文与本人写的其他文章一样&#xff0c;旨在给出Word2Vec模型中的详细计算过程&#xff0c;包括每个模块的计…...

React Native源码学习

核心组件 基础组件&#xff1a;View、Text、Image、TextInput、ScrollView&#xff08;性能没有FlatList好&#xff0c;因为它会一次性把子元素渲染出来&#xff09;、StyleSheet交互组件&#xff1a;button列表视图&#xff1a;FlatList&#xff08;优先渲染屏幕上可见的元素&…...

【计网】从零开始认识https协议 --- 保证安全的网络通信

在每个死胡同的尽头&#xff0c; 都有另一个维度的天空&#xff0c; 在无路可走时迫使你腾空而起&#xff0c; 那就是奇迹。 --- 廖一梅 --- 从零开始认识https协议 1 什么是https协议2 https通信方案2.1 只使用对称加密2.2 只使用非对称加密2.3 双方都使用非对称加密2.4 …...

Ubuntu安装 MySQL【亲测有效】

在Ubuntu上安装MySQL数据库的步骤通常包括更新软件包列表、安装MySQL服务器、启动并配置MySQL服务等。以下是一个详细的安装指南&#xff1a; 一、更新软件包列表 首先&#xff0c;打开终端并输入以下命令来更新Ubuntu的软件包列表&#xff1a; sudo apt update二、安装MySQ…...

Unity 从零开始搭建一套简单易用的UGUI小框架 扩展与优化篇(完结)

一个通用的UGUI小框架就算是写完了&#xff0c;下面是一步步的思考与优化过程 Unity 从零开始搭建一套简单易用的UGUI小框架 基础分析篇-CSDN博客 Unity 从零开始搭建一套简单易用的UGUI小框架 功能撰写与优化篇-CSDN博客 从使用者的角度来整理一下可能会发出的疑问 0. Panel…...

MySQL多表操作--外键约束多表关系

外键约束介绍 Mysql外键约束&#xff08;foreign key&#xff09;是表的一个特殊字段&#xff0c;常与主键约束一起使用。外键约束是一种用于维护两个表之间数据一致性的方法。它确保引用表中的每个值都存在于主表中的某个列中。外键约束通常用于实现数据库的参照完整性。对于两…...