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

05 循环神经网络

目录

1. 基本概念

2. 简单循环网络

2.1  简单循环网络

2.2 长程依赖问题

3. 循环神经网络的模式与参数学习

3.1 循环神经网络的模式

3.2 参数学习

4. 基于门控的循环神经网络

4.1 长短期记忆网络

4.2 LSTM网络的变体网络

4.3 门控循环单元网络

5. 深层循环神经网络

5.1 堆叠循环神经网络

5.2 双向循环神经网络


1. 基本概念

       在前馈神经网络中,信息的传递是单向的,这种限制虽然使得网络变得更容易学习,但在一定程度上也减弱了神经网络模型的能力。前馈神经网络可以看作一个复杂的函数,每次输入都是独立的,即网络的输出只依赖于当前的输入。但是在很多现实任务中,网络的输出不仅和当前时刻的输入相关,也和其过去一段时间的输出相关。比如一个有限状态自动机,其下一个时刻的状态(输出)不仅仅和当前输入相关,也和当前状态(上一个时刻的输出)相关。此外,前馈网络难以处理时序数据,比如视频、语音、文本等。时序数据的长度一般是不固定的,而前馈神经网络要求输入和输出的维数都是固定的,不能任意改变。因此,当处理这一类和时序数据相关的问题时,就需要一种能力更强的模型。

       循环神经网络(Recurrent Neural Network,RNN)是一类具有短期记忆能力的神经网络。在循环神经网络中,神经元不但可以接受其他神经元的信息,也可以接受自身的信息,形成具有环路的网络结构。和前馈神经网络相比,循环神经网络更加符合生物神经网络的结构。循环神经网络已经被广泛应用在语音识别、语言模型以及自然语言生成等任务上。循环神经网络的参数学习可以通过随时间反向传播算法来学习。随时间反向传播算法即按照时间的逆序将错误信息一步步地往前传递。

当输入序列比较长时,会存在梯度爆炸和消失问题,也称为长程依赖问题。为了解决这个问题,人们对循环神经网络进行了很多的改进,其中最有效的改进方式引入门控机制(Gating Mechanism)。

       为了处理这些时序数据并利用其历史信息, 我们需要让网络具有短期记忆能力。一般来讲,我们可以通过以下三种方法来给网络增加短期记忆能力: 

(1)延时神经网络

       一种简单的利用历史信息的方法是建立一个额外的延时单元,用来存储网络的历史信息(可以包括输入、输出、隐状态等)。比较有代表性的模型是延时神经网络(Time Delay Neural Network,TDNN)。

       延时神经网络是在前馈网络中的非输出层都添加一个延时器,记录神经元的最近几次活性值。在第 t 个时刻,第 l 层神经元的活性值依赖于第 l-1 层神经元的最近 K 个时刻的活性值,即:

       其中 h_t^{(l)} 表示第 l 层神经元在时刻 t 的活性值。通过延时器,前馈网络就具有了短期记忆的能力。

延时神经网络在时间维度上共享权值,以降低参数数量.因此对于序列输入来讲,延时神经网络就相当于卷积神经网络。

(2)有外部输入的非线性自回归模型

       自回归模型(AutoRegressive Model,AR)是统计学上常用的一类时间序列模型,用一个变量 \textbf{\textit{y}}_t 的历史信息来预测自己:

其中 K 为超参数,w_0,……,w_k 为可学习参数,\epsilon _t\sim N(0,\sigma ^2) 为第 t 个时刻的噪声,方差 \sigma ^2 和时间无关。 

       有外部输入的非线性自回归模型(Nonlinear AutoRegressive with Exogenous Inputs Model,NARX)是自回归模型的扩展,在每个时刻 t 都有一个外部输入\textbf{\textit{x}}_t,产生一个输出 \textbf{\textit{y}}_t,NARX通过一个延时记录最近 K_x 次的外部输入和最近 K_y 次的输出,第 t 个时刻的输出 \textbf{\textit{y}}_t 为:

其中 f(\cdot ) 表示非线性函数,可以是一个前馈网络,K_x 和 K_y为超参数。

(3)循环神经网络

       循环神经网络(Recurrent Neural Network,RNN)通过使用带自反馈的神经元,能够处理任意长度的时序数据。给定一个输入序列 \textbf{\textit{x}}_{1:T}=(\textbf{\textit{x}}_1,\textbf{\textit{x}}_2,\cdots ,\textbf{\textit{x}}_t,\cdots ,\textbf{\textit{x}}_T),循环神经网络通过下面公式更新带反馈边的隐藏层的活性值 \textbf{\textit{h}}_t

\textbf{\textit{h}}_t=f(\textbf{\textit{h}}_{t-1},\textbf{\textit{x}}_t)

其中 \textbf{\textit{h}}_0=0, f(\cdot ) 表示非线性函数,可以是一个前馈网络。从数学上讲,上面公式可以看成一个动力系统。因此,隐藏层的活性值在很多文献上也称为状态(State)或隐状态(Iidden State)。

动力系统(Dynamical System)的概念,指系统状态按照一定的规律随时间变化的系统。具体地讲,动力系统是使用一个函数来描述一个给定空间(如某个物理系统的状态空间)中所有点随时间的变化情况。生活中很多现象(比如钟摆晃动、台球轨迹等)都可以动力系统来描述。

       下图给出了循环神经网络的示例,其中“延时器”为一个虚拟单元,记录神经元的最近一次的活性值:

       由于循环神经网络具有短期记忆能力,相当于存储装置,因此其计算能力十分强大。理论上,循环神经网络可以近似任意的非线性动力系统。前馈神经网络可以模拟任何连续函数,而循环神经网络可以模拟任何程序。

2. 简单循环网络

2.1  简单循环网络

       简单循环网络(Simple Recurrent Network,SRN)是一个非常简单的循环神经网络,只有一个隐藏层。在一个两层的前馈神经网络中,连接存在于相邻的层与层之间,隐藏层的节点之间是无连接的。而简单循环网络增加了从隐藏层到隐藏层的反馈连接。

       令向量 \textbf{\textit{x}}_t 表示在时刻 t 时网络的输入,\textbf{\textit{h}}_t 表示隐藏层状态(即隐藏层神经元活性值),则 \textbf{\textit{h}}_t 不仅和当前时刻的输入 \textbf{\textit{x}}_t 有关,也和上一时刻的隐藏层状态 \textbf{\textit{h}}_{t-1} 相关。简单循环网络在时刻 t 的更新公式为:

\textbf{\textit{h}}_t=f(\textbf{\textit{U}}\textbf{\textit{h}}_{t-1}+\textbf{\textit{W}}\textbf{\textit{x}}_t+\textbf{\textit{b}})

式中: \textbf{\textit{U}} 为状态-状态权重矩阵,用于连接上一时间步的隐藏状态到当前时间步的隐藏状态;\textbf{\textit{W}} 为状态-输入权重矩阵,用于连接当前时间步的输入到隐藏状态;\textbf{\textit{b}} 为偏置向量;f(\cdot ) 表示非线性激活函数,通常为Logistic函数或Tanh函数。

 2.2 长程依赖问题

(1) 长程依赖问题

       循环神经网络在学习过程中的主要问题是由于梯度消失或爆炸问题,很难建模长时间间隔(Long Range)的状态之间的依赖关系。

       梯度消失:是指随着网络层数的增加,反向传播过程中梯度值逐渐减小到几乎为零的现象。这意味着靠近输入层的权重几乎不会得到有效的更新,从而导致这些层的学习速度非常慢或者根本不学习。

       梯度爆炸:是指在反向传播过程中,梯度值变得异常大,导致权重更新幅度过大,模型参数可能发散,使得训练过程变得不稳定。

       虽然简单循环网络理论上可以建立长时间间隔的状态之间的依赖关系,但是由于梯度爆炸或消失问题,实际上只能学习到短期的依赖关系。这样,如果时刻 t 的输出 y_t 依赖于时刻 k 的输入 \textbf{\textit{x}}_k ,当间隔 t-k 比较大时,简单神经网络很难建模这种长距离的依赖关系,称为长程依赖问题(Long-Term Dependencies Problem)。

(2) 解决方案

       为了避免梯度爆炸或消失问题,一种最直接的方式就是选取合适的参数,同时使用非饱和的激活函数,但这种方式需要足够的人工调参经验,限制了模型的广泛应用。比较有效的方式是通过改进模型或优化方法来缓解循环网络的梯度爆炸和梯度消失问题。
梯度爆炸问题:循环网络的梯度爆炸问题比较容易解决,一般通过权重衰减梯度截断来避免:

  • 权重衰减是通过给参数增加 L1L2 范数的正则化项来限制参数的取值范围;
  • 梯度截断是设置一定阈值,当梯度的模大于一定阈值时,就将它截断成为一个较小的数。

梯度消失问题:梯度消失是循环网络的主要问题。除了使用一些优化技巧外,更有效的方式就是改变模型,比如:

\textbf{\textit{h}}_t=\textbf{\textit{h}}_{t-1}+g(\textbf{\textit{x}}_t,\textbf{\textit{h}}_{t-1};\theta )

这样,\textbf{\textit{h}}_t 和 \textbf{\textit{h}}_{t-1} 之间既有线性关系,也有非线性关系,且缓解了梯度消失问题。但这种改进依然存在两个问题:梯度爆炸问题和记忆容量问题。

  • 记忆容量(Memory Capacity)问题:随着 \textbf{\textit{h}}_t 不断累积存储新的输入信息,会发生饱和现象,也就是说,隐藏状态 \textbf{\textit{h}}_t 可以存储的信息是有限的,随着记忆单元存储的内容越来越多,其丢失的信息也越来越多。

       为了解决这两个问题,可以通过引入门控机制来进一步改进模型(第5节)。

3. 循环神经网络的模式与参数学习

3.1 循环神经网络的模式

       根据应用到不同类型的机器学习任务,循环神经网络可以分为以下几种模式:序列到类别模式、同步的序列到序列模式、异步的序列到序列模式。

(1)序列到类别模式

       序列到类别模式主要用于序列数据的分类问题:输入为序列,输出为类别。比如在文本分类中,输入数据为单词的序列,输出为该文本的类别。
       假设一个样本 \textbf{\textit{x}}_{1:T}=(\textbf{\textit{x}}_1,\textbf{\textit{x}}_2,\cdots ,\textbf{\textit{x}}_t,\cdots ,\textbf{\textit{x}}_T) 为一个长度为 T 的序列,输出为一个类别 y\epsilon \left \{ 1,\cdots ,C \right \}。我们可以将样本 \textbf{\textit{x}} 按不同时刻输入到循环神经网络中,并得到不同时刻的隐藏状态 \textbf{\textit{h}}_1,\cdots ,\textbf{\textit{h}}_T。我们可以将 \textbf{\textit{h}}_T 看作整个序列的最终表示(或特征),并输入给分类器 g(\cdot ) 进行分类,即:

\hat{y}=g(\textbf{\textit{h}}_T)

其中 g(\cdot ) 可以是简单的线性分类器(比如Logistic回归)或复杂的分类器(比如多层前馈神经网络)。
       除了将最后时刻的状态作为整个序列的表示之外,我们还可以对整个序列的所有状态进行平均,并用这个平均状态来作为整个序列的表示,即:

\hat{y}=g(\frac{1}{T}\sum_{t=1}^{T}\textbf{\textit{h}}_t)

(2)同步的序列到序列模式

       同步的序列到序列模式主要用于序列标注(Sequence Labeling)任务,即每一时刻都有输入和输出,输入序列和输出序列的长度相同。比如在词性标注(Part-of-Speech Tagging)中,每一个单词都需要标注其对应的词性标签。

       在同步的序列到序列模式中,输入为一个长度为 T 的序列\textbf{\textit{x}}_{1:T}=(\textbf{\textit{x}}_1,\textbf{\textit{x}}_2,\cdots ,\textbf{\textit{x}}_t,\cdots ,\textbf{\textit{x}}_T),输出为序列y_{1:T}=(y_1,y_2,\cdots ,y_t,\cdots ,y_T)。样本 \textbf{\textit{x}} 按不同时刻输入到循环神经网络中,并得到不同时刻的隐状态 \textbf{\textit{h}}_1,\cdots ,\textbf{\textit{h}}_T 。每个时刻的隐状态 t 代表了当前时刻和历史的信息,并输入给分类器 g(\cdot ) 得到当前时刻的标签 \hat{y}_t,即:

\hat{y}_t=g(\textbf{\textit{h}}_t),\: \forall \; t\epsilon \left [ 1,T \right ]

(3)异步的序列到序列模式

       异步的序列到序列模式也称为编码器-解码器(Encoder-Decoder)模型,即输入序列和输出序列不需要有严格的对应关系,也不需要保持相同的长度。比如在机器翻译中,输入为源语言的单词序列,输出为目标语言的单词序列。

       在异步的序列到序列模式中,输入为长度为 T 的序列 \textbf{\textit{x}}_{1:T}=(\textbf{\textit{x}}_1,\textbf{\textit{x}}_2,\cdots ,\textbf{\textit{x}}_t,\cdots ,\textbf{\textit{x}}_T) ,输出为长度为 M 的序列 y_{1:M}=(y_1,y_2,\cdots ,y_M)。异步的序列到序列模式一般通过先编码后解码的方式来实现。先将样本 \textbf{\textit{x}} 按不同时刻输入到一个循环神经网络(编码器)中,并得到其编码 \textbf{\textit{h}}_T ,然后再使用另一个循环神经网络(解码器),得到输出序列 \hat{y}_{1:M} 。为了建立输出序列之间的依赖关系,在解码器中通常使用非线性的自回归模型。令 f_1(\cdot ) 和 f_2(\cdot ) 分别为用作编码器和解码器的循环神经网络,则编码器-解码器模型可以写为:

其中,g(\cdot ) 为分类器,\hat{\textbf{\textit{y}}}_t 为预测输出 \hat{y}_t 的向量表示。

       在解码器中通常采用自回归模型,每个时刻的输入为上一时刻的预测结果 \hat{y}_{t-1} 。

3.2 参数学习

       循环神经网络的参数可以通过梯度下降方法来进行学习。

       循环神经网络中存在一个递归调用的函数 f(\cdot ),因此,其计算参数梯度的方式和前馈神经网络不太相同。在循环神经网络中主要有两种计算梯度的方式:随时间反向传播(BPTT)算法实时循环学习(RTRL)算法。

(1)随时间反向传播算法

       随时间反向传播(BackPropagation Through Time,BPTT)算法的主要思想是通过类似前馈神经网络的误差反向传播算法来计算梯度。

       BPTT算法将循环神经网络看作一个展开的多层前馈网络,其中“每一层”对应循环网络中的“每个时刻”。这样,循环神经网络就可以按照前馈网络中的反向传播算法计算参数梯度。在“展开”的前馈网络中,所有层的参数是共享的,因此参数的真实梯度是所有“展开层”的参数梯度之和。

       关于BPTT算法的原理,可参看下文这篇文章:

随时间反向传播(BackPropagation Through Time,BPTT)icon-default.png?t=N7T8https://www.cnblogs.com/shixiangwan/p/9289862.html

(2)实时循环学习算法

       实时循环学习(Real-Time Recurrent Learning, RTRL)算法是一种用于训练循环神经网络的方法,尤其是在训练长序列数据时。与反向传播的BPTT算法不同的是,RTRL算法是通过前向传播的方式来计算梯度。

       RTRL算法的主要特点是它能够在处理序列数据的同时在线地计算梯度。这意味着当网络处理每个时间步的数据时,它可以立即更新权重,而不需要等待整个序列被处理完毕。这种方法在理论上可以更好地适应动态环境,因为它可以在处理序列的过程中逐步优化模型。

优点

  • 能够实现真正的在线学习,适应实时数据流。
  • 梯度计算与网络响应同时进行,提供灵活的计算框架。

缺点

  • 计算复杂度高,特别是在处理长序列时。
  • 内存消耗大,需要存储雅可比矩阵。

       RTRL算法原理:

       上面,\bigodot 表示Hadamard乘积(同或运算),即对应位置元素相乘。

(3)两种算法比较

       RTFL算法和BPTT算法都是基于梯度下降的算法,分别通过前向模式反向模式应用链式法则来计算梯度。

       在循环神经网络中,一般网络输出维度远低于输入维度,因此BPTT算法的计算量会更小,但是BPTT算法需要保存所有时刻的中间梯度,空间复杂度较高。RTFL算法不需要梯度回传,因此非常适合用于需要在线学习或无限序列的任务中。

4. 基于门控的循环神经网络

       为了改善循环神经网络的长程依赖问题,一种非常好的解决方案是引入门控机制来控制信息的累积速度,包括有选择地加入新的信息,并有选择地遗忘之前累积的信息。这一类网络可以称为基于门控的循环神经网络(Gated RNN)

       本文主要介绍两种基于门控的循环神经网络:长短期记忆网络和门控循环单元网络。

4.1 长短期记忆网络

       长短期记忆网络(Long Short-Term Memory Network,LSTM)是循环神经网络的一个变体,可以有效地解决简单循环神经网络的梯度爆炸或消失问题。

       第2.2节讲到,为了解决梯度消失问题,神经元可以采用以下策略:

\textbf{\textit{h}}_t=\textbf{\textit{h}}_{t-1}+g(\textbf{\textit{x}}_t,\textbf{\textit{h}}_{t-1};\theta )

       LSTM网络是在上面公式的基础上,主要在以下两个方面进行了改进:

(1)新的内部状态

       LSTM网络引入一个新的内部状态(internal state)\textbf{\textit{c}}_t 专门进行线性的循环信息传递,同时(非线性地)输出信息给隐藏层的外部状态 \textbf{\textit{h}}_t。内部状态 \textbf{\textit{c}}_t 通过下面公式计算:

其中,遗忘门\textbf{\textit{f}}_t\: \epsilon \: [0,1]、输入门\textbf{\textit{i}}_t\: \epsilon \: [0,1]、输出门\textbf{\textit{o}}_t\: \epsilon \: [0,1]为三个门(gate)来控制信息传递的路径;\bigodot 为向量元素乘积;\textbf{\textit{c}}_{t-1} 为上一时刻的记忆单元;\tilde{\textbf{\textit{c}}}_t 是通过非线性函数得到的候选状态:

       在每个时刻 t ,LSTM网络的内部状态 \textbf{\textit{c}}_t 记录了到当前时刻为止的历史信息。

(2)门控机制

       在数字电路中,门(gate)为一个二值变量 {0,1},0代表关闭状态,不许任何信息通过;1代表开放状态,允许所有信息通过。LSTM网络引入门控机制(Gating Mechanism)来控制信息传递的路径。三个门的作用为:

  • 遗忘门:控制上一个时刻的内部状态 \textbf{\textit{c}}_{t-1} 需要遗忘多少信息;
  • 输入门:控制当前时刻的候选状态 \tilde{\textbf{\textit{c}}}_t 有多少信息需要保存;
  • 输出门:控制当前时刻的内部状态 \textbf{\textit{c}}_t 有多少信息需要输出给外部状态 \textbf{\textit{h}}_t 。

       当 \textbf{\textit{f}}_t=0,\textbf{\textit{i}}_t=1 时,记忆单元将历史信息清空,并将候选状态向量 \tilde{\textbf{\textit{c}}}_t 写入。但此时记忆单元 \textbf{\textit{c}}_t 依然和上一时刻的历史信息相关。当 \textbf{\textit{f}}_t=1,\textbf{\textit{i}}_t=0 时,记忆单元将复制上一时刻的内容,不写入新的信息。

       LSTM网络中的“门”是一种“软”门,取值在(0,1)之间,表示以一定的比例允许信息通过。三个门的计算方式为:

其中 \sigma (\cdot ) 为Logistic函数,其输出区间为(0,1),\textbf{\textit{x}}_t 为当前时刻的输入,\textbf{\textit{h}}_{t-1} 为上一时刻的外部状态。

   下图给出了LSTM网络的循环单元结构,其计算过程为:

  • 1)首先利用上一时刻的外部状态 \textbf{\textit{h}}_{t-1} 和当前时刻的输入 \textbf{\textit{x}}_t ,计算出三个门,以及候选状态 \tilde{\textbf{\textit{c}}}_t ;
  • 2)结合遗忘门 \textbf{\textit{f}}_t 和输入门 \textbf{\textit{i}}_t 来更新记忆单元 \textbf{\textit{c}}_t
  • 3)结合输出门 \textbf{\textit{o}}_t,将内部状态的信息传递给外部状态 \textbf{\textit{h}}_t 。

       通过 LSTM 循环单元,整个网络可以建立较长距离的时序依赖关系。

       循环神经网络中的隐状态 \textbf{\textit{h}} 存储了历史信息,可以看作一种记忆(Memory)。在简单循环网络中,隐状态每个时刻都会被重写,因此可以看作一种短期记忆(Short-Term Memory)。在神经网络中,长期记忆(Long-Term Memory)可以看作网络参数,隐含了从训练数据中学到的经验,其更新周期要远远慢于短期记忆。而在LSTM网络中,记忆单元 \textbf{\textit{c}} 可以在某个时刻捕捉到某个关键信息,并有能力将此关键信息保存一定的时间间隔。记亿单元 \textbf{\textit{c}} 中保存信息的生命周期要长于短期记忆,但又远远短于长期记忆,因此称为长短期记忆(LongShort-Term Memory)。

4.2 LSTM网络的变体网络

4.3 门控循环单元网络

        门控循环单元(Gated Recurrent Unit,GRU)网络是一种比LSTM网络更加简单的循环神经网络。
        GRU网络引入门控机制来控制信息更新的方式。和LSTM不同,GRU不引入额外的记亿单元,GRU网络是引入一个更新门(Update Gate)来控制当前状态需要从历史状态中保留多少信息,以及需要从候选状态中接受多少新信息,即:

\textbf{\textit{h}}_t=\textbf{\textit{z}}_t\bigodot \textbf{\textit{h}}_{t-1}+(1-\textbf{\textit{z}}_t)\bigodot g(\textbf{\textit{x}}_t,\textbf{\textit{h}}_{t-1};\theta )

其中,\textbf{\textit{z}}_t\: \epsilon \: [0,1] 为更新门:

\textbf{\textit{z}}_t=\sigma (\textbf{\textit{U}}_z\textbf{\textit{h}}_{t-1}+\textbf{\textit{W}}_z\textbf{\textit{x}}_t+\textbf{\textit{b}}_z)

        在LSTM网络中,输入门和遗忘门是互补关系,具有一定的冗余性,而GRU网络直接使用一个门来控制输入和遗忘之间的平衡。下图为GRU网络的循环单元结构:

5. 深层循环神经网络

       增加循环神经网络的深度可以增强循环神经网络的能力,这里的增加深度主要是增加同一时刻网络输入到输出之间的路径 \textbf{\textit{x}}_ty_t,比如增加隐状态到输出 \textbf{\textit{h}}_t →  y_t,以及输入到隐状态 \textbf{\textit{x}}_t\textbf{\textit{h}}_t 之间的路径的深度。

5.1 堆叠循环神经网络

       一种常见的增加循环神经网络深度的做法是将多个循环网络堆叠起来,称为堆叠循环神经网络(Stacked Recurrent Neural Network,SRNN)。一个堆叠的简单循环网络(Stacked SRN)也称为循环多层感知器(Recurrent Multi-Layer Perceptron,RMLP)。
       下图给出了按时间展开的堆叠循环神经网络:

       第 l 层网络的输入是第 l-1 层网络的输出。定义 \textbf{\textit{h}}^{(l)}_t 为在时刻 t 时第 l 层的隐状态:

\textbf{\textit{h}}^{(l)}_t=f (\textbf{\textit{U}}^{(l)}\textbf{\textit{h}}^{(l)}_{t-1}+\textbf{\textit{W}}^{(l)}\textbf{\textit{h}}^{(l-1)}_t+\textbf{\textit{b}}^{(l)})

其中,\textbf{\textit{h}}^{(l)}\textbf{\textit{W}}^{(l)} 和 \textbf{\textit{b}}^{(l)} 为权重矩阵和偏置向量,\textbf{\textit{h}}^{(0)}=\textbf{\textit{x}}_t 。

5.2 双向循环神经网络

       在有些任务中,一个时刻的输出不但和过去时刻的信息有关,也和后续时刻的信息有关。比如给定一个句子,其中一个词的词性由它的上下文决定,即包含左右两边的信息。因此,在这些任务中,我们可以增加一个按照时间的逆序来传递信息的网络层,来增强网络的能力。

       双向循环神经网络(Bidirectional Recurrent Neural Network,Bi-RNN)由两层循环神经网络组成,它们的输入相同,只是信息传递的方向不同。

       假设第1层按时间顺序,第2层按时间逆序,在时刻 t 时的隐状态定义为\textbf{\textit{h}}^{(1)}_t\textbf{\textit{h}}^{(2)}_t,则:

其中,\bigoplus 为向量拼接操作。

       下图为按时间展开的双向循环神经网络:

相关文章:

05 循环神经网络

目录 1. 基本概念 2. 简单循环网络 2.1 简单循环网络 2.2 长程依赖问题 3. 循环神经网络的模式与参数学习 3.1 循环神经网络的模式 3.2 参数学习 4. 基于门控的循环神经网络 4.1 长短期记忆网络 4.2 LSTM网络的变体网络 4.3 门控循环单元网络 5. 深层循环神经网络…...

C#初级——条件判断语句、循环语句和运算符

条件判断语句 简单的条件判断语句&#xff0c;if()里面进行条件判断&#xff0c;如果条件判断正确就执行语句块1&#xff0c;如果不符合就执行语句块2。 if (条件判断) { 语句块1 } else { 语句块2 } int age 18;if (age < 18){Console.WriteLine("未…...

Laravel路由模型绑定:简化依赖注入的艺术

Laravel路由模型绑定&#xff1a;简化依赖注入的艺术 引言 在现代Web应用开发中&#xff0c;Laravel框架以其优雅和简洁的代码而闻名。Laravel的路由模型绑定&#xff08;Route Model Binding&#xff09;是框架提供的一项强大功能&#xff0c;它允许开发者在路由处理中自动注…...

【vue前端项目实战案例】之Vue仿饿了么App

本文将介绍一款仿“饿了么”商家页面的App。该案例是基于 Vue2.0 Vue Router webpack ES6 等技术栈实现的一款外卖类App&#xff0c;适合初学者进行学习。 项目源码下载链接在文章末尾 1 项目概述 该项目是一款仿“饿了么”商家页面的外卖类App&#xff0c;主要有以下功能…...

冷热分离——Java全栈知识(36)

之前在面试的时候有老师问&#xff1a; 我看你使用了水平分表&#xff0c;但是如果有些 1%的数据占了访问量的 90%&#xff0c;而剩下 99%的数据只占了访问量的 10%。这种情况怎么处理。 1 、冷热分离 1.1、什么是冷热分离 冷热分离指的是在处理数据时将数据库分为冷库和热库…...

了解Selenium中的WebElement

Selenium中到处都使用WebElement来执行各种操作。什么是WebElement&#xff1f;这篇文章将详细讨论WebElement。 Selenium中的WebElement是一个表示网站HTML元素的Java接口。HTML元素包含一个开始标记和一个结束标记&#xff0c;内容位于这两个标记之间。 HTML元素的重命名 …...

OpenCV facedetect 人脸检测官方示例项目配置

运行程序。该程序会自动打开摄像头&#xff0c;识别并定位摄像头前的人脸以及眼睛部位。 输入q或者Q&#xff0c;退出程序。 或进行文本中所包含的图片路径 或 单个图片进行检测&#xff0c;自行修改代码即可 配置环境项目&#xff0c;debug 解决error C4996: ‘fopen’: This…...

自定义Laravel Artisan风格:打造个性化命令行体验

自定义Laravel Artisan风格&#xff1a;打造个性化命令行体验 引言 Laravel的Artisan命令行工具是开发过程中不可或缺的一部分&#xff0c;它提供了一个强大的接口来执行各种开发、维护、测试等任务。除了执行命令&#xff0c;Artisan还允许开发者自定义命令行输出的风格&…...

CTF之网站被黑

简单看一下网页和源码没发现什么明显漏洞 那就扫描一下目录 发现了/shell.php文件&#xff0c;访问一下&#xff0c;发现是一个后台管理登录页面 别无他法只能爆破喽&#xff0c;爆破后发现密码是hack flag{25891d9e9d377f006eda3ca7d4c34c4d}...

Electron学习笔记(一)基础环境

目录 前言 基础环境准备 安装 Node.js 配置项目文件 通过代理服务安装 通过国内仓库安装 一些常见问题&#xff1a; 前言 一个新手学习Electron的笔记&#xff0c;记录为主&#xff0c;仅供参考。 其他文章见专栏目录。 基础环境准备 开发之前先将基础环境搭建好。 …...

【C语言】栈的实现(数据结构)

前言&#xff1a; 还是举一个生活中的例子&#xff0c;大家都玩过积木&#xff0c;当我们把积木叠起来的时候&#xff0c;如果要拿到最底部的积木&#xff0c;我们必须从顶端一个一个打出&#xff0c;最后才能拿到底部的积木&#xff0c;也就是后进先出&#xff08;先进后出&a…...

前端三大主流框架对比

在现代前端开发中&#xff0c;React、Vue和Angular是三大流行的框架/库。它们各自有独特的优缺点&#xff0c;适用于不同的开发需求和项目规模。下面是对这三者的详细比较&#xff1a; 一、 React 简介&#xff1a; 由Facebook开发和维护&#xff0c;是一个用于构建用户界面…...

AOP~面向切面编程介绍

AOP基础 概述 AOP&#xff1a;Aspect Oriented Programming&#xff08;面向切面编程、面向方面编程&#xff09;&#xff0c;面向特定方法的编程。 动态代理是面向切面编程最主流的实现。 SpringAOP是Spring框架的高级技术&#xff0c;旨在管理bean对象的过程中&#xff0c…...

Android SurfaceFlinger——GraphicBuffer的提交(三十三)

在 SurfaceFlinger 中,我们 dequeueBuffer 和 queueBuffer 是 Surface 控制接口中非常重要的两个函数,分别用于从 Surface 的 BufferQueue 中取出缓冲区和向 BufferQueue 提交(队列)缓冲区。这两个函数在生产者和消费者模型中扮演着核心角色,确保了图像数据的高效和有序传…...

创维汽车滁州永通体验中心开业仪式暨超充车型区域上市会圆满成功

2024年7月20日&#xff0c;创维汽车滁州永通体验中心盛大开业&#xff0c;当日&#xff0c;创维汽车市场部经理周世鹏、安徽大区总监王大明等领导参加本次开业盛典&#xff0c;共同见证创维汽车滁州永通体验中心成功落地。 2021年&#xff0c;新能源乘用车高速发展&#xff0c;…...

【PHP】系统的登录和注册

一、为什么要学习系统的登录和注册 系统的登录和注册可能存在多种漏洞&#xff0c;这些漏洞可能被恶意攻击者利用&#xff0c;从而对用户的安全和隐私构成威胁。通过学习系统的登录和注册理解整个登录和注册的逻辑方便后续更好站在开发的角度思考问题发现漏洞。以下是一些常见…...

2024.7.29 刷题总结

2024.7.29 **每日一题** 682.棒球比赛&#xff0c;这道题是一道简单的模拟题&#xff0c;用栈模拟题中的四个操作就可以了&#xff0c;操作一是将x加到列表末尾&#xff0c;操作二是将列表的后两项之和加到列表末尾&#xff0c;操作三是把列表最后一项的两倍加到列表末尾&#…...

WebSocket程序设计

协议说明 WebSocket 是一种在单个TCP连接上进行全双工通信的协议。WebSocket 使得客户端和服务器之间的数据交换变得更加简单&#xff0c;允许服务端主动向客户端推送数据。Websocket主要用在B/S架构的应用程序中&#xff0c;在 WebSocket API 中&#xff0c;浏览器和服务器只…...

ES(ElasticSearch)倒排索引

目录 正排与倒排索引 1.正排索引 作用&#xff1a; 优点&#xff1a; 缺点&#xff1a; 2.倒排索引 原理&#xff1a; 倒排索引的构建流程&#xff1a; 倒排索引的搜索流程&#xff1a; 优点&#xff1a; 缺点&#xff1a; 3. 应用场景 倒排索引中有几个非常重要的概念…...

Android Studio Build窗口出现中文乱码问题

刚安装成功的android studio软件打开工程&#xff0c;编译时下方build窗口中中文是乱码。 解决&#xff1a; 可点击studio状态栏的Help—>Edit Custom VM Options &#xff0c;在打开的studio64.exe.vmoptions文件后面添加&#xff1a;(要注意不能有空格&#xff0c;否则st…...

java生成随机数

代码 startValue 开始值 endValue 结束值 per生成的位数也就是精度 /*** 随机数的生成* param startValue* param endValue* return*/private BigDecimal randomBigDecimal(String startValue, String endValue,int per) {BigDecimal min new BigDecimal(startValue);BigDeci…...

动态定制深度学习:Mojo模型与自定义训练算法的无缝切换

动态定制深度学习&#xff1a;Mojo模型与自定义训练算法的无缝切换 引言 在机器学习领域&#xff0c;算法的选择对模型的性能有着决定性的影响。随着研究的深入和技术的发展&#xff0c;开发者可能需要根据不同的数据特性和业务需求&#xff0c;动态地切换或自定义训练算法。…...

昇思25天学习打卡营第19天|DCGAN生成漫画头像

DCGAN生成漫画头像总结 实验概述 本实验旨在利用深度卷积生成对抗网络&#xff08;DCGAN&#xff09;生成动漫头像&#xff0c;通过设置网络、优化器以及损失函数&#xff0c;使用MindSpore进行实现。 实验目的 学习和掌握DCGAN的基本原理和应用。熟悉使用MindSpore进行图像…...

排序题目:按照频率将数组升序排序

文章目录 题目标题和出处难度题目描述要求示例数据范围 解法思路和算法代码复杂度分析 题目 标题和出处 标题&#xff1a;按照频率将数组升序排序 出处&#xff1a;1636. 按照频率将数组升序排序 难度 3 级 题目描述 要求 给定一个整数数组 nums \texttt{nums} nums&a…...

实分析与测度论问题的分类

实分析主要研究实数、实数序列、实数极限以及实值函数的分析&#xff0c;而度量空间则是一个具有距离函数的集合&#xff0c;其分类可以从多个角度进行。 实分析 实分析主要关注实数、实数序列、实数极限以及实值函数的分析。它涉及到多个重要的概念和理论&#xff0c;包括但…...

动态代理更改Java方法的返回参数(可用于优化feign调用后R对象的统一处理)

动态代理更改Java方法的返回参数&#xff08;可用于优化feign调用后R对象的统一处理&#xff09; 需求原始解决方案优化后方案1.首先创建AfterInterface.java2.创建InvocationHandler处理代理方法3. 调用 实际运行场景拓展 需求 某些场景&#xff0c;调用别人的方法&#xff0…...

Redis缓存数据库进阶——Redis与分布式锁(6)

分布式锁简介 1. 什么是分布式锁 分布式锁是一种在分布式系统环境下&#xff0c;通过多个节点对共享资源进行访问控制的一种同步机制。它的主要目的是防止多个节点同时操作同一份数据&#xff0c;从而避免数据的不一致性。 线程锁&#xff1a; 也被称为互斥锁&#xff08;Mu…...

网络芯片(又称为PHY网络芯片)

Realtek RTL8152B是一种常见的主板集成网络芯片&#xff08;又称为PHY网络芯片&#xff09;。PHY芯片是指将网络控制芯片的运算部分交由处理器或南桥芯片处理&#xff0c;以简化线路设计&#xff0c;从而降低成本。 https://www.realtek.com/Download/List?cate_id585 Realt…...

01 Go Web基础_20240728 课程笔记

概述 如果您没有Golang的基础&#xff0c;应该学习如下前置课程。 基础不好的同学每节课的代码最好配合视频进行阅读和学习&#xff0c;如果基础比较扎实&#xff0c;则阅读本教程巩固一下相关知识点即可&#xff0c;遇到不会的知识点再看视频。 视频课程 最近发现越来越多…...

嵌入式学习Day12---C语言提升

目录 一、指针数组 1.1.什么是指针数组 2.2. 格式 2.3.存储 2.4.与字符型二维数组相比 2.5.什么时候使用指针数组 2.6.练习 二、数组指针 2.1.什么是数组指针 2.2.格式 2.3.一维数组 2.3.特点 2.4.什么时候使用 三、指针和数组的关系 3.1.一维数组和指针 …...

6.6 使用dashboard商城搜索导入模板

本节重点介绍 : 模板商城中搜索模板导入模板修改模板 大盘模板商城地址 免费的 地址 https://grafana.com/grafana/dashboards 搜索模板技巧 详情 导入dashboard 两种导入模式 url导入id导入json文件导入 导入 node_exporter模板 https://grafana.com/grafana/dashboa…...

一文讲透useMemo和useCallback

在React项目中是经常会使用到useMemo&#xff0c;useCallBack的&#xff0c;这是两个优化性能的方法&#xff0c;那么useMemo&#xff0c;useCallBack到底是什么呢&#xff1f;什么时候用呢&#xff1f; 下面将给打击分享相关知识&#xff0c;希望对大家有所帮助同时欢迎讨论指…...

【环境变量】安装了一个软件,如何配置环境变量?

配置环境变量为啥&#xff1f; 方便地在任何文件夹下调用某一指定目录下的文件。 配置步骤 以jdk17为例。 1.打开环境变量配置页面 2.新建一个变量&#xff0c;变量名为JAVA_HOME&#xff0c;内容为jdk的path路径 3.打开path变量&#xff0c;新建一个%JAVA_HOME%\bin&#x…...

重生之我当程序猿外包

第一章 个人介绍与收入历程 我出生于1999年&#xff0c;在大四下学期进入了一家互联网公司实习。当时的实习工资是3500元&#xff0c;公司还提供住宿。作为一名实习生&#xff0c;这个工资足够支付生活开销&#xff0c;每个月还能给父母转1000元&#xff0c;自己留2500元用来吃…...

我想给 git 分支换一个名字,应该怎么做?

Git中重命名分支的操作步骤如下: 确保你在要重命名的分支上。可以使用git branch或git status命令查看当前所在分支[1][2]. 使用以下命令重命名当前分支: git branch -m new-branch-name例如,将当前分支重命名为"feature-xyz": git branch -m feature-xyz-m参数是&q…...

echarts多stack的legend点选

echarts支持点击legend&#xff0c;实现显示和隐藏legend对应的数据&#xff0c;具体就是option里series里,name为legend值的数据。 如果配置了多个stack&#xff0c;那么可能你可能设置了多组legend&#xff0c;你点选的是多个legend组中的某组中的一个&#xff0c;那么如果不…...

搭建自己的金融数据源和量化分析平台(四):自动化更新上市公司所属一级、二级行业以及股票上市状态

前面做了更新沪深交易所的上市股票列表的读取和更新&#xff0c;但一旦股票退市则需要在数据库里将该股票状态更新为退市&#xff0c;同时附上退市日期&#xff0c;将股票名更改为XX退。 此外深交所下载的xls解析出来是没有上市公司所属的二级行业的&#xff0c;因此还需要建立…...

科创板重启IPO上会!募投审核新方向?思看科技等优化募投项目

撰稿 | 多客 来源 | 贝多财经 根据上交所项目审核动态最新公告&#xff0c;思看科技&#xff08;杭州&#xff09;股份有限公司&#xff08;简称“思看科技”&#xff09;将于8月2日上会&#xff0c;标志着时隔50天后科创板重新迎来首家上会企业&#xff0c;也标志着思看科技…...

深入解析损失函数:从基础概念到YOLOv8的应用

深入解析损失函数&#xff1a;从基础概念到YOLOv8的应用 在机器学习和深度学习中&#xff0c;损失函数是至关重要的组件&#xff0c;它们衡量模型的预测值与真实值之间的差距&#xff0c;从而指导模型的优化过程。本文将详细探讨损失函数的基本概念&#xff0c;及其在YOLOv8中…...

2.11.ResNet

ResNet 动机&#xff1a;我们总是想加更多层&#xff0c;但加更多层并不总是能改进精度 可以看出F1到F6模型越来越大&#xff0c;但F6距离最优解却总变远了&#xff0c;反而效果不好&#xff0c;通俗的来说就是学偏了&#xff0c;实际上我们希望是这样的&#xff1a; ​ 更大…...

GitLab添加TortoiseGIT生成SSH Key

文章目录 前言一、PuTTYgen二、GitLab 前言 GitLab是一个用于托管代码仓库和项目管理的Web平台&#xff0c;公司搭建自己的gitlab来管理代码&#xff0c;我们在clone代码的时候可以选择http协议&#xff0c;也可以选择ssh协议来拉取代码。 SSH (Secure Shell)是一种通过网络进…...

20240729 大模型评测

参考&#xff1a; MMBench&#xff1a;基于ChatGPT的全方位多模能力评测体系_哔哩哔哩_bilibili https://en.wikipedia.org/wiki/Levenshtein_distance cider: https://zhuanlan.zhihu.com/p/698643372 GitHub - open-compass/opencompass: OpenCompass is an LLM evalua…...

基于微信小程序的校园警务系统/校园安全管理系统/校园出入管理系统

摘要 伴随着社会以及科学技术的发展&#xff0c;小程序已经渗透在人们的身边&#xff0c;小程序慢慢的变成了人们的生活必不可少的一部分&#xff0c;紧接着网络飞速的发展&#xff0c;小程序这一名词已不陌生&#xff0c;越来越多的学校机构等都会定制一款属于自己个性化的小程…...

达梦数据库归档介绍

一、什么是归档 数据库归档是一种数据管理策略&#xff0c;它涉及将旧的、不经常访问的数据移动到一个单独的存储设备&#xff0c;以便在需要时可以检索&#xff0c;同时保持数据库的性能和效率。 归档的主要目标是为了释放数据库中的空间&#xff0c;以便更有效地利用高性能…...

OpenAI推出AI搜索引擎SearchGPT

OpenAI推出AI搜索引擎SearchGPT 据英国《卫报》和美国消费者新闻与商业频道等媒体报道&#xff0c;7月25日&#xff0c;OpenAI宣布正在测试一款名为SearchGPT的全新人工智能&#xff08;AI&#xff09;搜索工具。该工具能够实时访问互联网信息&#xff0c;旨在为用户提供更具时…...

elementplus菜单组件的那些事

在使用 elementplus 的菜单组件时&#xff0c;我发现有很多东西是官方没有提到但是需要注意的点 1. 菜单组件右侧会有一个边框 设置css .el-menu {border: 0 !important; } 2. 使用其他的 icon 文字内容一定要写在 这个 名字为 title 的插槽中 <el-menu-itemv-for"it…...

【VSCode实战】Golang无法跳转问题竟是如此简单

上一讲【VSCode实战】Go插件依赖无法安装 – 经云的清净小站 (skycreator.top)&#xff0c;开头说到了在VSCode中Golang无法跳转的问题&#xff0c;但文章的最后也没给出解决方案&#xff0c;只解决了安装Go插件的依赖问题。 解决了插件依赖问题&#xff0c;无法跳转的问题也离…...

three.js中加载ply格式的文件,并使用tween.js插件按照json姿态文件运动

先贴一下文件地址&#xff1a; aa.ply 文件&#xff1a; https://download.csdn.net/download/yinge0508/89595650?spm1001.2014.3001.5501 new.json https://download.csdn.net/download/yinge0508/89595641?spm1001.2014.3001.5501 代码: <template><div>&…...

性能对比:Memcached 与 Redis 的关键差异

性能对比&#xff1a;Memcached 与 Redis 的关键差异 在选择合适的缓存系统时&#xff0c;Memcached 和 Redis 是最常被提及的两种技术。它们都是内存存储系统&#xff0c;用于提高数据访问速度和应用性能。尽管它们在功能上有很多相似之处&#xff0c;但在性能、特性和应用场…...

app-routing.module.ts 简单介绍

Angular的路由是一种功能&#xff0c;它允许应用程序响应不同的URL路径或参数并根据这些路径加载不同的组件。app-routing.module.ts是Angular项目中负责设置应用程序路由的文件。 以下是一个简单的app-routing.module.ts文件示例&#xff0c;它配置了三个路由&#xff1a; i…...