1. 时间序列(Time Series)

时间序列是一系列按时间顺序排列的、可比较的观察值 y t y_t yt,这些观察值是在等距的时间间隔内记录的。
y t y_t yt表示第 t t t个周期的观察值,其中 t = 1 , 2 , … , n t=1,2,…,n t=1,2,,n
在这里插入图片描述
例如:

  1. 股票价格(Stock prices):股票价格随时间变化,可以形成时间序列数据。
    在这里插入图片描述

  2. 温度读数(Temperature readings):温度数据通常在固定的时间间隔(如每小时)记录,形成时间序列。
    在这里插入图片描述

  3. 脑电图(Electroencephalography脑电图):脑电图是一种通过在头皮上放置电极来记录大脑电活动的技术。这些电极可以检测到大脑神经元产生的微小电流变化,从而生成脑电波的图形记录。在这里插入图片描述

1.1 时间序列模型(Time Series Models)

时间序列建模是指使用统计方法和数学模型来分析和预测按时间顺序排列的数据点。这种建模可以帮助我们理解数据随时间变化的模式和趋势。
时间序列中连续时间点的值通常存在相关性。这种相关性是时间序列分析和预测的基础。如果时间序列中的值是完全随机的,那么预测就变得不可能。
时间序列的统计特性(如均值、方差等)在时间上是稳定的。这是许多时间序列模型的基本假设之一。
宽平稳(Wide-Sense Stationary,WSS)是平稳性的一种较弱形式,它要求时间序列满足以下两个条件:

  1. 均值和自协方差不随时间变化。
  2. 方差对所有时间都是有限的。

在统计学和机器学习中,时间序列通常被描述为一系列随时间变化的向量(或标量)。
这些向量或标量表示在不同时间点 t t t上的观测值,例如 { x ( t 0 ) , x ( t 1 ) , ⋯   , x ( t i − 1 ) , x ( t i ) , x ( t i + 1 ) , ⋯   } \{x(t_0), x(t_1), \cdots, x(t_{i-1}), x(t_i), x(t_{i+1}), \cdots \} {x(t0),x(t1),,x(ti1),x(ti),x(ti+1),}

时间序列是某个过程 P 的输出,这个过程具有未知的动态特性(Unknown dynamics)。
在这里插入图片描述

我们的目标是通过分析观测到的时间序列数据来理解和预测这个过程的动态特性。

1.1.1 连续信号采样

连续信号 x ( t ) x(t) x(t)是指在时间上连续变化的信号。例如,声音波形、温度变化等都可以视为连续信号。
为了将这些连续信号用于时间序列分析,需要在离散的时间点对其进行采样,从而得到一系列离散的观测值。
均匀采样(Uniform Sampling)是指以固定的时间间隔 Δ t Δt Δt对连续信号进行采样。
通过均匀采样得到的离散时间序列表示为 { x [ t ] } \{x[t]\} {x[t]}
因此这个序列表示为: { x [ t ] } = { x ( 0 ) , x ( Δ t ) , x ( 2 Δ t ) , x ( 3 Δ t ) , ⋯ } \{x[t]\}=\{x(0),x(Δt),x(2Δt),x(3Δt),⋯\} {x[t]}={x(0),x(Δt),x(t),x(t),}

1.1.2 预测未来的问题

从时间点 t t t向前延伸,我们有一个时间序列 { x [ t ] , x [ t − 1 ] , ⋯ } \{x[t],x[t−1],⋯\} {x[t],x[t1],}。我们的目标是估计在未来某个时间点 t + s t+s t+s的值 x x x
预测公式表示为: x ^ [ t + s ] = f ( x [ t ] , x [ t − 1 ] , ⋯   ) \hat{x}[t+s] = f(x[t], x[t-1], \cdots) x^[t+s]=f(x[t],x[t1],)
s s s被称为预测范围(horizon of prediction)。
在开始时,我们预测未来一个时间点,即 s = 1 s=1 s=1
这是一个函数逼近问题(function approximation problem),我们需要找到一个合适的函数 f f f来逼近真实的未来值。
我们的解决步骤如下:

  1. 首先,我们需要假设一个生成模型,这个模型能够生成时间序列数据。
  2. 对于过去的每一个点 x [ t i ] x[t_i] x[ti],使用 t i t_i ti之前的数据作为输入, t i t_i ti之后的数据作为期望输出,来训练生成模型。
  3. 使用训练好的模型,根据 ( x [ t ] , x [ t − 1 ] , ⋯ ) (x[t],x[t−1],⋯) (x[t],x[t1],)来预测 x ^ [ t + s ] \hat{x}[t+s] x^[t+s]

时间序列预测是一种统计方法,用于根据历史数据预测未来的趋势和行为。它在许多领域都有广泛的应用。
例如:

  1. 金融领域:例如股票价格、汇率等。通过对历史金融数据的分析,可以预测未来的市场走势,从而做出投资决策。
  2. 物理观测:例如天气变化、河流流量等。通过对历史观测数据的分析,可以预测未来的天气情况或河流水位,从而进行相应的规划和管理。

时间序列预测的重要性如下:

  1. 预防不良事件:
    通过预测事件的发生,识别事件前的特定情况,并采取纠正措施,可以避免事件的发生。
    例如,在医疗领域,通过分析病人的历史健康数据,可以预测某些疾病的发生,从而提前采取预防措施。
  2. 减轻不可避免事件的影响:
    对于一些不可避免的不良事件,通过预测可以提前采取措施,减轻其影响。
    例如,在自然灾害领域,通过预测地震、洪水等灾害的发生,可以提前疏散人员,减少损失。
  3. 从预测中获利:
    在金融市场中,通过预测股票价格、汇率等,可以进行投资决策,从而获得收益。
    例如,通过对历史金融数据的分析,可以预测未来的市场走势,从而进行买卖操作,获得投资回报。

时间序列预测有以下难点:

  • 数据量有限(Limited quantity of data):
    可用的时间序列数据可能数量有限,这限制了模型训练的充分性和预测的准确性。
    时间序列数据可能太短,以至于无法有效地分割成训练集和测试集,这会影响模型的泛化能力。
  • 噪声(Noise):
    数据中可能存在错误数据点或噪声,这些会干扰模型的学习和预测。
  • 非平稳性(Non-stationarity):
    时间序列的统计特性(如均值、方差)可能随时间变化,这种非平稳性使得预测变得更加复杂。
  • 预测方法的选择(Forecasting method selection):
    存在多种预测方法,如统计方法和人工智能方法,选择合适的方法对于提高预测性能至关重要。

神经网络,尤其是前馈神经网络,已被广泛用于时间序列预测。这些网络通常使用滑动窗口方法处理输入序列。滑动窗口是一种技术,它在输入序列上移动,每次提取一个固定长度的子序列作为输入向量。
神经网络将时间序列 X 1 , … , X n X_1,…,X_n X1,,Xn视为多个从输入向量到输出值的映射。这意味着网络学习如何根据输入的一系列值(如过去的观测值)来预测下一个值。

1.1.2.1 使用人工神经网络(ANN)进行时间序列预测

我们用以下方式使用人工神经网络(ANN)进行时间序列预测:

  1. 输入窗口的数据点映射:
    将时间序列中相邻的一系列数据点(输入窗口 X t − s , X t − s + 1 , … , X t X_{t−s} ,X_{t−s+1},…,X_t Xts,Xts+1,,Xt)映射到区间 [ 0 , 1 ] [0,1] [0,1],并用作输入层的激活值。
    这个步骤是为了将原始数据标准化或归一化,使其适合神经网络处理。
  2. 输入窗口的大小与神经网络的输入单元数:
    输入窗口的大小 s s s对应于神经网络输入层的单元数。
    这意味着如果输入窗口包含 s s s个数据点,那么输入层将有 s s s个神经元。
  3. 前向传播和误差计算:
    在前向传播过程中,激活值通过隐藏层传播到输出单元。
    用于反向传播训练的误差是通过比较输出单元的值与时间序列在时间 t + 1 t+1 t+1的实际值来计算的。
    这个过程涉及到损失函数,它衡量了预测值与实际值之间的差异。
  4. 多层感知器网络的训练:
    使用反向传播学习算法训练多层感知器(MLP)网络通常需要多次呈现所有输入集的表示(称为一个epoch)。
    这意味着在训练过程中,整个训练数据集需要被多次遍历,以便网络能够学习到数据中的模式和关系。

下图展示了使用人工神经网络(ANN)进行时间序列预测的结构示意图。
在这里插入图片描述
我们这里稍微复习一下前面所学的前馈神经网络(Feed Forward Neural Network,FNN)。前馈神经网络是一种常见的神经网络结构,其中信息从输入层流向输出层,不形成闭环。
通过训练(例如使用反向传播算法),带有隐藏节点的前馈神经网络会发展出内部表示,这些表示对输入信号进行重新编码。
这种重新编码使得网络能够以一种方式处理输入信号,从而产生正确的输出。
在这里插入图片描述
输入层接收输入信号,隐藏层处理这些信号,输出层生成最终的输出。
对于隐藏层的每个神经元 j j j
y j ( t ) = f ( n e t j ) y_j(t) = f(net_j) yj(t)=f(netj)
n e t j ( t ) = ∑ i ( v j i x i ( t ) ) + θ j net_j(t) = \sum_i (v_{ji} x_i(t)) + θ_j netj(t)=i(vjixi(t))+θj
其中, y j ( t ) y_j(t) yj(t)是神经元 j j j在时间 t t t的输出, f f f是激活函数, n e t j net_j netj是神经元 j j j的净输入, v j i v_{ji} vji是从输入层到隐藏层的权重, x i ( t ) x_i(t) xi(t)是输入信号, θ j θ_j θj是神经元 j j j的偏置项。
对于输出层的每个神经元 k k k
y k ( t ) = g ( n e t k ) y_k(t) = g(net_k) yk(t)=g(netk)
n e t k ( t ) = ∑ j w k j y j ( t ) + θ k net_k(t) =\sum_j w_{kj} y_j(t) + θ_k netk(t)=jwkjyj(t)+θk
其中, y k ( t ) y_k(t) yk(t)是输出层神经元 k k k在时间 t t t的输出, g g g是激活函数, n e t k net_k netk是神经元 k k k的净输入, w k j w_{kj} wkj是从隐藏层到输出层的权重, y j ( t ) y_j(t) yj(t)是隐藏层神经元 j j j的输出, θ k θ_k θk是神经元 k k k的偏置项。

1.2 动态网络(dynamic networks)

有时,我们希望模型对一段时间前呈现的输入保持敏感。
这意味着我们的需求不能仅通过一个函数(无论它多么复杂)来满足,而是需要一个能够维护状态或记忆的模型,这些状态或记忆可以跨越多个输入呈现。
序列输入(sequential input):例如语言理解、机器人探索等。在这些应用中,理解当前输入通常需要考虑之前的输入信息。
序列输出(sequential output):例如语音生成、路线规划等。在这些应用中,生成当前输出通常需要考虑之前的输出信息。
输入和输出的组合:有些应用可能同时需要处理序列输入和序列输出,例如机器翻译,其中输入是一段文本序列,输出是另一段文本序列。

因此动态网络的好处如下:

  1. 记忆和状态维护:动态网络能够维护一个内部状态,这个状态可以随时间更新,从而允许网络“记住”过去的信息。
  2. 处理序列数据:动态网络特别适合处理序列数据,因为它们可以利用过去的信息来影响当前的决策或输出。
  3. 复杂模式识别:在处理复杂的序列模式时,动态网络可以更好地捕捉长期依赖关系,这是静态模型难以做到的。

1.2.1 序列学习(Sequence Learning)

多层感知器(MLP)和径向基函数(RBF)网络是静态网络(Static Networks)的例子。
静态网络学习从单个输入信号到单个输出响应的映射。
它们可以处理任意数量的输入输出对,但每个输入输出对都是独立的。

动态网络(Dynamic Networks)学习从单个输入信号到一系列响应信号的映射。
它们可以处理任意数量的输入序列对(输入信号和对应的输出序列)。
动态网络的输入信号通常是序列中的一个元素,然后网络生成序列的其余部分作为响应。
例如:

  1. 文本生成:假设我们有一个文本序列:“我今天很开心”。
    如果网络的输入是“我今”,网络的任务可能是生成序列的下一个单词“天”。
    网络通过学习语言模式和上下文关系来预测下一个合适的单词。
  2. 时间序列预测:假设我们有一个股票价格的时间序列。
    如果网络的输入是最近几天的股票价格,网络的任务可能是预测接下来几天的价格。
    网络通过分析历史价格数据和可能的趋势来预测未来的价格。

为了学习序列,网络需要包含某种形式的记忆(短期记忆)。
这是因为序列数据具有时间依赖性,网络需要记住过去的信息来预测未来的值。

1.2.1.1 记忆效应(Memory Effect)

记忆效应(Memory Effect)是指系统能够记住过去发生的事件,并利用这些信息来影响当前或未来的行为。具体来说是网络或模型能够利用过去的输入数据来影响当前的输出或预测。
序列学习中的记忆效应分为两种主要方式:隐式(Implicit)和显式(Explicit)。

  1. 隐式(Implicit):
    隐式记忆效应是通过将时间延迟的信号作为输入提供给静态网络,或者通过循环连接(recurrent connections)来实现的。
    在这种方法中,我们假设收集(输入信号,输出序列)示例的环境是静止的(stationary)。这意味着环境的统计特性不随时间变化,例如,时间序列数据的均值和方差在时间上保持恒定。
  2. 显式(Explicit):
    显式记忆效应是通过明确设计网络结构来实现的,例如使用时间反向传播方法(Temporal Backpropagation Method)。
    显式形式允许环境是非静止的(non-stationary),即网络能够跟踪信号结构的变化。这意味着网络可以适应环境的变化,例如,时间序列数据的统计特性可能随时间变化。
1.2.1.1.1 时间延迟网络(Time Delayed Networks)

时间延迟网络是一种特殊的神经网络结构,它通过引入时间延迟的输入来处理序列数据。
这种网络结构使得网络能够利用过去的输入信息来影响当前的输出。
信号可以被外部缓冲(buffered externally),并在额外的输入节点(input banks)上呈现。这样网络可以接收一系列时间延迟的输入信号,这些信号是在过去不同时间点上收集的。
时间延迟网络展示了一种隐式的序列学习方法,它将静态网络(如多层感知器MLP或径向基函数RBF)与记忆结构结合起来。
通过这种方式,网络能够在没有显式记忆单元的情况下,利用过去的输入信息来处理序列数据。
在这里插入图片描述
输入层接收一系列时间延迟的信号,如 x ( t − ω ) , x ( t − 2 ) , x ( t − 1 ) , x ( t ) x(t−ω),x(t−2),x(t−1),x(t) x(tω),x(t2),x(t1),x(t)
这些输入信号被连接到隐藏层(State/hidden),隐藏层通过权重 W W W将信息传递到输出层。
输出层生成最终的输出。

1.2.1.1.2 动态神经网络(Dynamical Neural Networks)

动态神经网络能够根据输入数据和内部状态动态地调整其行为,这使得它们非常适合处理具有时间依赖性的任务。我们重点介绍循环网络。
循环网络可以显式地处理按顺序呈现的输入,这在现实问题中几乎总是如此。
循环网络与前馈网络(Feed Forward Networks)在本质上是不同的。循环网络不仅处理输入数据,还处理网络的状态。这种状态可以看作是网络的内部记忆,它允许网络记住过去的输入信息,并利用这些信息来影响当前和未来的输出。
网络的回响(reverberate)和持续活动的能力可以作为工作记忆(working memory)。这意味着网络能够在一段时间内保持信息,即使在没有新的输入的情况下也能继续处理信息。
具有这种能力的网络被称为动态神经网络。

下图将前馈神经网络(Feed-Forward Neural Networks)和循环神经网络(Recurrent Neural Networks,RNN)进行了对比。
在这里插入图片描述
左侧(前馈神经网络):
连接方向:连接仅从左到右,没有连接循环(即没有反馈连接)。
激活传播:激活值从输入层通过隐藏层向前传播到输出层,没有反馈回路。
记忆能力:前馈网络没有记忆能力,因为它们不存储过去的信息。

右侧(循环神经网络):
连接循环:至少存在一个连接循环,即网络中存在反馈连接,使得信息可以在网络中循环流动。
激活回响:激活可以“回响”(reverberate),即使在没有新输入的情况下也能持续存在。这意味着网络可以维持内部状态。
记忆系统:循环网络具有记忆能力,可以存储和利用过去的信息。
动态系统:从数学角度来看,RNN实现了动态系统。这意味着它们的行为和输出可以随时间变化,并且对初始条件敏感。

我们再总结一下显式和隐式记忆效应。
显式记忆效应涉及到对神经网络结构的直接修改,以引入一种机制来明确地存储和利用过去的信息。
隐式记忆效应不涉及对网络结构的直接修改,而是通过控制输入或利用网络的学习能力来间接利用过去的信息。

2. Elman网络

Elman网络是一种循环神经网络,这意味着它具有循环连接,可以将网络的输出反馈到输入,从而允许信息在网络中循环流动。
Elman网络除了传统的三层:输入层、隐藏层和输出层。此外,它还有一个额外的层,称为上下文层(context layer)或记忆层,用于存储隐藏层的输出。
Elman网络具有强大的预测能力,这主要得益于其循环连接和上下文层。通过这些结构,网络可以利用过去的信息来预测未来的输出。

2.1 Elman网络的结构

Elman网络包含以下几个部分:

  1. 输入层(Input):
    输入层接收外部输入信号 x x x
  2. 隐藏层(State/Hidden):
    隐藏层处理输入信号,并生成内部状态 z z z
    隐藏层的输出不仅用于生成最终的输出,还被复制到上下文层(Context Layer)。
  3. 上下文层(Context Layer):
    上下文层存储隐藏层的输出,作为网络的短期记忆。
    上下文层的输出被反馈到隐藏层,形成循环连接。
  4. 输出层(Output):
    输出层生成最终的输出 y y y,基于隐藏层的当前状态和上下文层的状态。

W W W:从隐藏层到输出层的权重。
V V V:从输入层到隐藏层的权重。
U U U:从上下文层到隐藏层的权重,用于形成循环连接。
在这里插入图片描述
状态更新: z t = F v ( z t − 1 , x ) z^t = F_v(z^{t-1}, x) zt=Fv(zt1,x),其中:
z t z^t zt是时间 t t t时刻的状态。
z t − 1 z^{t-1} zt1是时间 t − 1 t−1 t1时刻的状态。
x x x是当前的输入。
F v F_v Fv是状态更新函数,通常是一个非线性激活函数。
输出生成: y = F w ( z ) y = F_w(z) y=Fw(z),其中:
y y y是网络的输出。
F w F_w Fw是输出生成函数,通常也是一个非线性激活函数。

在这里插入图片描述

隐藏层的净输入和输出:
n e t j ( t ) = ∑ i v j i x i ( t ) + ∑ h u j h y h ( t − 1 ) + θ j net_j(t) = \sum_i v_{ji} x_i(t) + \sum_h u_{jh} y_h(t-1) + \theta_j netj(t)=ivjixi(t)+hujhyh(t1)+θj
y j ( t ) = f ( n e t j ) y_j(t) = f(net_j) yj(t)=f(netj)
其中:
n e t j ( t ) net_j(t) netj(t)是隐藏层第 j j j个神经元在时间 t t t的净输入。
v j i v_{ji} vji是从输入层到隐藏层的权重。
u j h u_{jh} ujh是从上下文层(隐藏层的前一状态)到隐藏层的权重(延迟的反馈)。
θ j \theta_j θj是隐藏层第 j j j个神经元的偏置。
f f f是激活函数。

输出层的净输入和输出:
n e t k ( t ) = ∑ j w k j y j ( t ) + θ k net_k(t) = \sum_j w_{kj} y_j(t) + \theta_k netk(t)=jwkjyj(t)+θk
y k ( t ) = g ( n e t k ) y_k(t) = g(net_k) yk(t)=g(netk)
其中:
n e t k ( t ) net_k(t) netk(t)是输出层第 k k k个神经元在时间 t t t的净输入。
w k j w_{kj} wkj是从隐藏层到输出层的权重。
θ k \theta_k θk是输出层第 k k k个神经元的偏置。
g g g是激活函数。

Elman网络中使用的方程与前馈神经网络(Feed Forward Neural Networks)中的方程在形式上是相同的。这包括如何计算神经元的净输入(net input)以及如何根据净输入通过激活函数生成输出。
Elman网络与前馈网络的主要区别在于引入了另一组权重(通常表示为 U),这组权重负责将隐藏层(hidden nodes)的激活值反馈到隐藏层自身。这种连接方式允许网络在处理序列数据时能够维持一个内部状态,或称为“记忆”。

在这里插入图片描述
所以Elman网络的主要特点和区别确实在于隐藏层与上下文层之间的交互方式:
隐藏层(Hidden Layer):
隐藏层负责形成内部表示,处理输入层传来的数据,并生成内部状态。
隐藏层的输出不仅用于生成最终的输出,还被复制到上下文层。
上下文层(Context Layer):
上下文层存储隐藏层的输出,作为网络的短期记忆。
上下文层的值被用作隐藏层所有神经元的额外输入信号,用于下一个时间步。
在Elman网络中,从隐藏层到上下文层的权重被设置为1并固定,以确保上下文神经元的值能够被精确复制。

总结一下:
隐藏层的激活值(即隐藏层神经元的输出)在每个时间步被复制并存储在上下文层中。上下文层可以被看作是隐藏层状态的“快照”,它记录了前一时间步隐藏层的信息。
在下一个时间步,上下文层中的值被用作额外的输入,反馈到隐藏层。这意味着隐藏层在处理当前输入时,不仅考虑当前的输入数据,还会考虑前一时间步的隐藏层状态(即上下文层提供的值)。

2.2 Elman网络的学习算法

Elman网络采用反向传播算法(Backpropagation,BP)来调整网络的权重。
Elman网络使用的误差函数: E = ∑ k = 1 n [ y ( k ) − d ( k ) ] 2 E = \sum_{k=1}^{n} [y(k) - d(k)]^2 E=k=1n[y(k)d(k)]2,其中:
E E E是总误差。
y ( k ) y(k) y(k)是网络在第 k k k个时间步的实际输出。
d ( k ) d(k) d(k) 是第 k k k个时间步的期望输出(目标值)。
n n n是时间步的总数。

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

下面我们具体开始介绍循环神经网络。

3.1 历史

RNN在1980年代末被引入到机器学习和神经网络领域。RNN的设计允许它们处理序列数据,这是传统前馈神经网络所不具备的能力。
1991年,Sepp Hochreiter发现了RNN中的“梯度消失”(vanishing gradients)问题。这个问题指的是在训练RNN时,随着网络深度的增加,梯度在反向传播过程中逐渐变小,导致网络难以学习到序列中较远距离的依赖关系。
1997年,Jürgen Schmidhuber和Sepp Hochreiter发表了关于LSTM的论文。LSTM是一种特殊类型的RNN,它被设计来解决RNN中的长期依赖问题。
我们将在后面详细学习LSTM。

3.2 循环神经网络和前馈神经网络的对比

前馈神经网络(Feed Forward Networks)的特点:

  1. 固定大小的输入和输出:
    前馈网络接受固定大小的向量作为输入,并产生固定大小的向量作为输出。
  2. 固定数量的计算步骤:
    前馈网络通常有固定数量的计算步骤,这意味着它们处理输入数据的方式是静态的,不随时间变化。
  3. 独立性假设:
    在传统的前馈网络中,所有的输入(和输出)都假设彼此独立,没有考虑数据之间的时间依赖性。

循环神经网络(RNN)的特点:

  1. 处理序列数据:
    RNN允许我们处理向量序列,这意味着它们可以处理随时间变化的数据,如时间序列、文本、语音等。
  2. 利用序列信息:
    RNN背后的理念是利用序列信息,即在处理数据时考虑到数据点之间的顺序和依赖关系。
  3. 时间依赖性的重要性:
    对于许多任务来说,假设输入彼此独立是一个糟糕的想法。例如,如果你想预测句子中的下一个单词,你最好知道前面出现了哪些单词。

3.3 RNN的结构

RNN被称为循环网络,因为它们对序列中的每个元素执行相同的任务,并且输出依赖于先前的计算(即记忆)。
在这里插入图片描述

主要组件:
输入 x ( t ) x(t) x(t):在时间 t t t的输入向量。
输出 y ( t ) y(t) y(t):在时间 t t t的输出向量。
隐藏状态 s ( t ) s(t) s(t):网络的内部状态或记忆,它存储了网络对之前输入的处理结果。
延迟单元:用于保持激活值直到下一个时间步。

当前的隐藏状态 s ( t ) s(t) s(t)是基于前一时间步的隐藏状态 s ( t − 1 ) s(t−1) s(t1)和当前的输入 x ( t ) x(t) x(t)计算得到的。
当前的输出 o ( t ) o(t) o(t)是基于当前的隐藏状态 s ( t ) s(t) s(t)计算得到的。

RNN在时间步 t − 1 t−1 t1做出的决策会影响它在时间步 t t t做出的决策。
RNN有两个输入源:当前输入和最近的过去(即先前的隐藏状态),这两个输入源结合起来决定网络如何响应新的数据。

3.4 RNN的拓扑结构

RNN的拓扑结构分为两种,在此之前我们先说基础的前馈神经网络(Feed Forward NN)。
在这里插入图片描述

这是最基本的神经网络结构,其中信息仅从输入层流向输出层,没有循环连接。每个节点只接收来自前一层的输入,不接收来自后一层的反馈。

然后是RNN的拓扑结构,第一种是简单的循环神经网络(A Simple RNN)。
在这里插入图片描述

这种网络结构中,循环仅存在于隐藏层。隐藏层的输出会被反馈到同一隐藏层的下一时间步,但输出层不参与循环。

第二种是全连接循环神经网络(Fully Connected RNN)。
在这里插入图片描述

在这种结构中,每个节点都与所有其他节点相连,包括跨时间步的连接。这意味着不仅隐藏层之间有循环连接,输入层和输出层也参与到循环中。

因此RNN的循环我们可以这样分为两种:

  1. 部分循环(Partly Recurrent):
    部分循环网络是一种分层网络,具有明确的输入和输出层,其中循环仅限于隐藏层。这种结构允许网络在处理序列数据时考虑过去的信息,但输出层的计算不依赖于先前的输出。
  2. 完全循环(Fully Recurrent):
    在完全循环网络中,每个节点都从所有其他节点接收输入,这意味着网络中的每个部分都可以直接或间接地影响其他部分。这种结构提供了最灵活的循环机制,但同时也可能导致更复杂的训练过程。

3.5 RNN架构

RNN有多种架构类型:
一对一(One to One):
在这里插入图片描述

这种架构处理固定大小的输入并产生固定大小的输出。例如,图像分类任务,其中输入是一个图像,输出是一个类别标签。

一对多(One to Many):
在这里插入图片描述

在这种架构中,单个输入对应一个序列输出。例如,图像字幕生成任务,其中输入是一个图像,输出是一系列单词(即字幕)。

多对一(Many to One):
在这里插入图片描述

这种架构处理序列输入并产生单个输出。例如,情感分析任务,其中输入是一个句子,输出是该句子表达的是正面还是负面情感。

多对多(Many to Many):
在这里插入图片描述

这种架构处理序列输入并产生序列输出。例如,机器翻译任务,其中输入是一个语言的句子,输出是另一种语言的句子。

多对多(Many to Many)同步序列输入和输出:
在这里插入图片描述

在这种架构中,输入和输出都是序列,并且它们是同步的。例如,视频分类任务,其中输入是视频的帧序列,输出是每个帧的标签。

3.5.1 RNN的前向传播

我们现在介绍RNN的前向传播。
在这里插入图片描述

  1. 网络在时间 t t t的输入:
    a h ( t ) = U x ( t ) + W s ( t − 1 ) a_h(t) = Ux(t) + Ws(t - 1) ah(t)=Ux(t)+Ws(t1)
    a h ( t ) a_h(t) ah(t)是隐藏层在时间 t t t的净输入。
    U U U是从输入层到隐藏层的权重矩阵。
    x ( t ) x(t) x(t)是在时间 t t t的输入向量。
    W W W是从先前隐藏状态到当前隐藏状态的权重矩阵。
    s ( t − 1 ) s(t−1) s(t1)是在时间 t − 1 t−1 t1的隐藏状态。

  2. 隐藏单元在时间 t t t的激活:
    s ( t ) = f h ( a h ( t ) ) s(t) = f_h(a_h(t)) s(t)=fh(ah(t))
    s ( t ) s(t) s(t)是隐藏层在时间 t 的激活值(或状态)。
    f h f_h fh是隐藏层的激活函数,通常是一个非线性函数,如tanh或ReLU。

  3. 隐藏层到输出层在时间 t t t的净输入:
    a o ( t ) = V s ( t ) a_o(t) = Vs(t) ao(t)=Vs(t)
    a o ( t ) a_o(t) ao(t)是输出层在时间 t t t的净输入。
    V V V是从隐藏层到输出层的权重矩阵。

  4. 网络在时间 t t t的输出:
    o ( t ) = f o ( a o ( t ) ) o(t) = f_o(a_o(t)) o(t)=fo(ao(t))
    o ( t ) o(t) o(t)是网络在时间 t t t的输出向量。
    f o f_o fo是输出层的激活函数,它可以根据任务的不同而选择不同的函数,如softmax用于分类任务。

3.5.2 RNN的损失函数

我们再介绍损失函数的计算。

  1. 误差向量:
    [ e ( t ) ] k = [ d ( t ) ] k − [ o ( t ) ] k [e(t)]_k = [d(t)]_k - [o(t)]_k [e(t)]k=[d(t)]k[o(t)]k
    [ e ( t ) ] k [e(t)]_k [e(t)]k表示在时间 t t t时第 k k k个输出的误差。
    [ d ( t ) ] k [d(t)]_k [d(t)]k是在时间 t t t时第 k k k个输出的目标值(期望输出)。
    [ o ( t ) ] k [o(t)]_k [o(t)]k是在时间 t t t时第 k k k个输出的实际值(模型预测)。

  2. 每个时间步的损失:
    E ( t ) = 1 2 e ( t ) T e ( t ) E(t) = \frac{1}{2} e(t)^T e(t) E(t)=21e(t)Te(t)
    E ( t ) E(t) E(t)是在时间 t t t的损失,计算方式是误差向量 e ( t ) e(t) e(t)的平方和的一半。这种计算方式称为平方误差损失函数。

  3. 总损失:
    E t o t a l = ∑ t = t 0 t 1 E ( t ) E_{total} = \sum_{t=t_0}^{t_1} E(t) Etotal=t=t0t1E(t)
    E t o t a l E_{total} Etotal是从时间 t 0 t_0 t0到时间 t 1 t_1 t1的总损失,它是每个时间步损失 E ( t ) E(t) E(t)的总和。

3.5.3 RNN的反向传播

介绍RNN的反向传播之前,我们先看一个操作。我们可以通过“展开”(unfolding)时间来将RNN视为一系列前馈网络。
在这里插入图片描述

RNN通过在隐藏层引入循环连接来处理序列数据。
通过将RNN在时间上展开,我们可以将RNN视为一系列前馈网络的集合。每个时间步长可以看作是前馈网络中的一层。上图变展示了这一点,每个时间步的隐藏状态和输入都被单独表示。
例如,如果我们关注的序列是一个由5个单词组成的句子,那么RNN可以被展开成一个5层的神经网络,每一层对应序列中的一个单词。
这种展开方式意味着我们可以将前馈网络的学习理论应用于RNN。例如,可以使用反向传播算法来训练RNN,尽管这需要在时间上进行反向传播,通常称为时间反向传播(Backpropagation Through Time,简称BPTT)。
因此通过“展开”,错误(损失)可以传播超过两层以捕获更长的历史信息。这意味着网络不仅考虑最近的输入,还能利用更早的输入信息来影响当前的决策。
在展开的RNN中,循环权重会为任意数量的时间步复制。
图中展示了RNN在每个时间步都有输出。然而,这并不总是必要的,具体取决于任务的需求。
例如,在预测句子的情感时,我们可能只关心最终的输出(整个句子的情感),而不是每个单词之后的情感。
RNN的主要特征是其隐藏状态,它捕获了序列的一些信息。隐藏状态使得RNN能够处理序列数据,因为它能够记住过去的输入并将其用于当前和未来的决策。

3.5.3.1 时间反向传播(Back Propagation Through Time,BPTT)

BPTT是标准反向传播算法的扩展,它在展开的网络(unfolded network)上执行梯度下降。
在BPTT中,权重更新的梯度下降不仅来自当前时间步的误差,还来自序列中每个时间步的贡献。这允许网络在训练过程中同时学习处理整个序列数据。
与前馈网络不同,RNN中的错误(损失不仅需要通过网络传播(即从输出层向隐藏层传播),还需要通过时间传播(即从当前时间步向先前的时间步传播)。这是因为RNN的隐藏层状态依赖于先前的状态。
对于循环网络,损失函数不仅依赖于隐藏层的激活如何影响输出层,还依赖于隐藏层的激活如何影响下一时间步的隐藏层。这意味着隐藏层的状态不仅影响当前输出,还影响未来时间步的隐藏状态。

3.5.3.2 梯度消失(Vanishing Gradients)

RNN使用时间反向传播(Back Propagation Through Time,简称BPTT)训练时,难以学习时间序列中远距离步骤之间的长期依赖关系。这是因为梯度消失问题导致的。
在这里插入图片描述
图中显示了单层、双层、三层和四层Sigmoid函数的曲线。
随着层数的增加,曲线在输入值较大或较小的区域变得平坦,这意味着梯度接近于零,导致网络难以学习。
梯度消失意味着在网络的反向传播过程中,梯度值变得非常小,以至于在权重更新时几乎不起作用。这使得网络难以捕捉到序列中远距离依赖关系,因为这些依赖关系需要通过多个时间步的梯度来传播。

我们再仔细看下Sigmoid函数。
在这里插入图片描述
Sigmoid函数在两端的导数为0。
当神经元的激活值接近0或1时,我们说神经元饱和(saturated)。饱和的神经元梯度为零,这导致前一层的梯度也趋向于0。
从“远距离”时间步的梯度贡献变为零,这导致网络遗忘旧信息,最终无法学习到长距离依赖关系。

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

LSTM是为了解决循环神经网络(RNN)中的梯度消失问题而发明的。
LSTM通过其独特的结构设计,能够在反向传播过程中维持一个更恒定的误差流。
LSTM能够处理那些在时间上相隔较远但仍然相关联的大型序列。这使得LSTM非常适合处理如自然语言处理、语音识别和时间序列预测等任务,这些任务通常涉及到处理具有长期依赖性的序列数据。

3.5.3.3.1 LSTM的架构

在这里插入图片描述
LSTM和RNN类似,LSTM单元接收当前的输入 x t x_t xt和前一时间步的隐藏状态 s t − 1 s_{t−1} st1,然后产生当前时间步的输出 y t y_t yt和新的隐藏状态 s t + 1 s_{t+1} st+1

LSTM网络的隐藏层由多个记忆块(memory block)组成,每个记忆块包含一个或多个记忆单元(memory cells)和一对自适应的乘法门控单元(adaptive multiplicative gating units)。
记忆块(memory blocks)允许网络中的单元共享相同的门控机制,从而减少模型的参数数量。
在这里插入图片描述

下图展示了LSTM中单个LSTM单元(LSTM cell)的结构。
在这里插入图片描述

  1. 输入门(Input Gate):
    输入门控制新信息的写入。它决定哪些新的输入信息将被写入到细胞状态(cell state)中。
    输入门通过一个sigmoid激活函数来决定哪些值需要更新。
  2. 遗忘门(Forget Gate):
    遗忘门控制细胞状态中哪些信息需要被遗忘,即从细胞状态中移除。
    同样通过sigmoid激活函数来决定哪些信息应该被保留或丢弃。
  3. 细胞状态(Cell State):
    细胞状态是LSTM的“记忆”部分,它存储长期信息。
    细胞状态通过输入门和遗忘门的控制进行更新。
  4. 输出门(Output Gate):
    输出门决定细胞状态的哪些部分将被用作输出。
    通过sigmoid激活函数来决定输出的内容。
  5. 候选记忆内容(Candidate Memory Content):
    候选记忆内容是新信息的候选值,它将被加权后加入到细胞状态中。
    通常通过tanh激活函数生成,因为它可以将值限制在-1到1之间,有助于梯度的传播。
  6. 输出(Output):
    LSTM单元的最终输出是细胞状态经过输出门处理后的结果。

上图没有显式地展示遗忘门,候选记忆内容。

3.5.3.3.2 LSTM的前向传播

在这里插入图片描述
LSTM网络中的层(或门控机制)负责决定哪些输入信息应该被传递(或“前向”)到LSTM单元内部,这一步通过将先前时间步的输出 y ( t − 1 ) y(t−1) y(t1)与循环权重矩阵 R z R_z Rz相乘来完成。

细胞状态的净输入:
a z ( t ) = W z x ( t ) + R z y ( t − 1 ) a_z(t) = W_z x(t) + R_z y(t - 1) az(t)=Wzx(t)+Rzy(t1)
细胞状态的更新:
z ( t ) = g ( a z ( t ) ) z(t) = g(a_z(t)) z(t)=g(az(t))
a z ( t ) a_z(t) az(t)是时间 t t t的细胞状态的净输入。
W z W_z Wz是从输入 x ( t ) x(t) x(t)到细胞状态的权重矩阵。
R z R_z Rz是从先前的隐藏状态 y ( t − 1 ) y(t−1) y(t1)到当前细胞状态的权重矩阵。
g g g是激活函数,通常为tanh函数,用于更新细胞状态 z ( t ) z(t) z(t)
x ( t ) x(t) x(t)是时间 t t t的输入向量。
y ( t − 1 ) y(t−1) y(t1)是时间 t − 1 t−1 t1的隐藏状态(或输出)。

在这里插入图片描述

输入门控制哪些信息可以从当前输入写入到记忆单元(Memory Cells)中。这是通过使用一个称为“挤压函数”(squashing function)的激活函数σ来实现的,该函数的输出作为因子,随后会与挤压后的细胞输入 z ( t ) z(t) z(t)相乘。我们这里说的输入门的净输入计算和细胞状态的净输入计算相似。
输入门的净输入:
a i n ( t ) = W i n x ( t ) + R i n y ( t − 1 ) a_{in}(t) = W_{in}x(t) + R_{in}y(t - 1) ain(t)=Winx(t)+Riny(t1)
输入门的激活值:
i ( t ) = σ ( a i n ( t ) ) i(t) = \sigma(a_{in}(t)) i(t)=σ(ain(t))
a i n ( t ) a_{in}(t) ain(t)是时间 t t t输入门的净输入。
W i n W_{in} Win是从输入 x ( t ) x(t) x(t)到输入门的权重矩阵。
R i n R_{in} Rin是从先前时间步的隐藏状态 y ( t − 1 ) y(t−1) y(t1)到输入门的权重矩阵。
i ( t ) i(t) i(t)是时间 t t t输入门的激活值,通过sigmoid函数 σ σ σ计算得出。
x ( t ) x(t) x(t)是时间 t t t的输入向量。
y ( t − 1 ) y(t−1) y(t1)是时间 t − 1 t−1 t1的隐藏状态(或输出)。

在这里插入图片描述
每个记忆单元包含一个节点,该节点具有一个自连接的循环边,权重固定为1,这个节点叫做恒定误差载体(Constant Error Carousel,CEC)。
CEC通过维持一个恒定的误差流来解决梯度消失问题。在没有新的输入或误差信号到达单元的情况下,CEC使得局部误差反向传播保持恒定,既不增长也不衰减。
细胞状态更新公式:
c ( t ) = z ( t ) ⊙ i ( t ) + c ( t − 1 ) c(t) = z(t) \odot i(t) + c(t - 1) c(t)=z(t)i(t)+c(t1)
其中:
c ( t ) c(t) c(t)是时间 t t t的细胞状态。
z ( t ) z(t) z(t)是候选记忆内容,由tanh激活函数 g g g生成。
i ( t ) i(t) i(t)是输入门的激活值,由sigmoid激活函数 σ \sigma σ生成。
⊙ \odot 表示Hadamard乘积(Hadam product),这是一种元素级别的乘法,用于组合两个向量。
候选记忆内容是通过当前输入和先前的隐藏状态经过一系列操作(如加权、激活函数等)生成的。具体来说,它通常由输入门控制的候选记忆内容生成函数计算得出,这个函数可以是一个tanh函数(双曲正切函数),因为它能够将值限制在-1到1之间,有助于梯度的稳定传播。

在这里插入图片描述
输出门控制从记忆单元(memory cells)中读取信息的权限。它决定了哪些信息可以从细胞状态传递到隐藏状态,进而影响最终的输出。
输出门通过使用挤压函数(squashing function,通常是sigmoid函数)的结果 σ σ σ作为一个因子,这个因子随后会与细胞内容 h ( c ( t ) ) h(c(t)) h(c(t))相乘。
挤压函数 σ σ σ的输出范围是 (0,1),可以解释为:当输出为0时,表示读取访问被拒绝;当输出为1时,表示读取访问被允许。
输出门的净输入:
a o u t ( t ) = W o u t x ( t ) + R o u t y ( t − 1 ) a_{out}(t) = W_{out}x(t) + R_{out}y(t - 1) aout(t)=Woutx(t)+Routy(t1)
最终输出:
o ( t ) = σ ( a o u t ( t ) ) o(t) = \sigma(a_{out}(t)) o(t)=σ(aout(t))
a o u t ( t ) a_{out}(t) aout(t)是时间 t t t时输出门的净输入。
W o u t W_{out} Wout是从输入 x ( t ) x(t) x(t)到输出门的权重矩阵。
R o u t R_{out} Rout是从先前隐藏状态 y ( t − 1 ) y(t−1) y(t1)到输出门的权重矩阵。
x ( t ) x(t) x(t)是时间 t t t的输入向量。
y ( t − 1 ) y(t−1) y(t1)是时间 t − 1 t−1 t1的隐藏状态(或输出)。
σ σ σ是sigmoid激活函数,用于计算输出门的激活值。
o ( t ) o(t) o(t)是时间 t t t的网络输出。

在这里插入图片描述
存储在细胞状态 c ( t ) c(t) c(t)中的值通过函数 h h h进行挤压(squashing)。挤压函数通常是一个非线性激活函数,如tanh函数,用于将细胞状态转换为适合输出的形式。
输出门控制细胞状态中的信息是否被输出。这是通过输出门的激活值 o ( t ) o(t) o(t)来决定的,该值由sigmoid函数 σ σ σ计算得出。
最终输出 y ( t ) y(t) y(t)是细胞状态的挤压值 h ( c ( t ) ) h(c(t)) h(c(t))和输出门激活值 o ( t ) o(t) o(t)的Hadamard乘积(即元素级别的乘法)。
最终输出计算公式:
y ( t ) = h ( c ( t ) ) ⊙ o ( t ) y(t) = h(c(t)) \odot o(t) y(t)=h(c(t))o(t)
其中:
y ( t ) y(t) y(t)是时间 t t t的输出。
h ( c ( t ) ) h(c(t)) h(c(t)) 是细胞状态 c ( t ) c(t) c(t)经过挤压函数 h h h处理后的值。
o ( t ) o(t) o(t)是输出门的激活值,由sigmoid激活函数 σ \sigma σ计算得出。
⊙ \odot 表示Hadamard乘积(即元素级别的乘法)。

所以细胞状态更新基于当前状态和三个输入: a z a_z az a i n a_{in} ain a o u t a_{out} aout
候选记忆内容 z ( t ) z(t) z(t)的计算:
a z ( t ) = W z x ( t ) + R z ( y ( t − 1 ) ) a_z(t) = W_zx(t) + R_z(y(t - 1)) az(t)=Wzx(t)+Rz(y(t1))
z ( t ) = g ( a z ( t ) ) z(t) = g(a_z(t)) z(t)=g(az(t))
输入门 i ( t ) i(t) i(t)的激活值:
a i n ( t ) = W i n x ( t ) + R i n ( y ( t − 1 ) ) a_{in}(t) = W_{in}x(t) + R_{in}(y(t - 1)) ain(t)=Winx(t)+Rin(y(t1))
i ( t ) = σ ( a i n ( t ) ) i(t) = \sigma(a_{in}(t)) i(t)=σ(ain(t))
细胞状态 c ( t ) c(t) c(t)的更新:
c ( t ) = z ( t ) ⊙ i ( t ) + c ( t − 1 ) c(t) = z(t) \odot i(t) + c(t - 1) c(t)=z(t)i(t)+c(t1)
输出门 o ( t ) o(t) o(t)的激活值:
a o u t ( t ) = W o u t x ( t ) + R o u t ( y ( t − 1 ) ) a_{out}(t) = W_{out}x(t) + R_{out}(y(t - 1)) aout(t)=Woutx(t)+Rout(y(t1))
o ( t ) = σ ( a o u t ( t ) ) o(t) = \sigma(a_{out}(t)) o(t)=σ(aout(t))
最终输出 y ( t ) y(t) y(t)的计算:
y ( t ) = h ( c ( t ) ) ⊙ o ( t ) y(t) = h(c(t)) \odot o(t) y(t)=h(c(t))o(t)
其中:
g g g是生成候选记忆内容的激活函数,通常是tanh函数。
σ σ σ是sigmoid激活函数,用于计算输入门和输出门的激活值。
⊙ ⊙ 表示Hadamard乘积(元素级别的乘法)。
h h h是输出的激活函数,通常是tanh函数。

3.5.3.3.3 LSTM的反向传播
  • 错误传播到CEC:
    在LSTM中,到达细胞输出的错误信号被传播到恒定误差载体(CEC)。CEC是LSTM中的一种机制,它允许错误信号在网络中持续存在一段时间。
  • 错误在CEC中的持续存在:
    错误可以在CEC中长时间存在。这意味着即使在没有新的输入或错误信号到达细胞的情况下,CEC中的错误信号也不会消失。
  • 确保非衰减的错误:
    这种机制确保了错误信号在反向传播过程中不会衰减,从而维持了一个稳定的误差流。
  • 跨越时间间隔的桥接:
    这种稳定的误差流使得LSTM能够“桥接”输入事件和目标信号之间的时间间隔。这对于学习序列中远距离依赖关系非常重要,因为它允许网络捕捉到即使在时间上相隔较远的输入和输出之间的联系。
3.5.3.3.4 LSTM的优势

LSTM的优势如下:

  1. 非衰减的误差反向传播(Non-decaying error backpropagation):
    LSTM通过其独特的门控机制(包括输入门、遗忘门和输出门)解决了梯度消失问题。这意味着在反向传播过程中,误差信号可以在网络中保持较大的值,从而允许网络学习到序列中较远距离的依赖关系。
  2. 处理长时间滞后问题(For long time lag problems):
    LSTM能够有效地处理那些在时间上相隔较远但仍相互关联的问题,即长时间滞后问题。这是因为LSTM能够维持一个稳定的状态,这个状态可以跨越多个时间步长距离地保持信息。
  3. 处理噪声和连续值(Handle noise and continuous values):
    LSTM能够处理带有噪声的数据和连续值。由于其设计能够维持一个长期的状态,LSTM对于输入数据中的噪声和连续变化具有较强的鲁棒性。
  4. 无需参数微调(No parameter fine tuning):
    LSTM的设计减少了对参数进行精细调整的需求。虽然这并不意味着完全不需要调整参数,但LSTM的门控机制使得网络在一定程度上对参数选择不那么敏感。
  5. 长时间记忆(Memory for long time periods):
    LSTM具有长时间记忆的能力,这意味着它能够记住并利用在序列中较早时间步发生的信息。这对于处理需要考虑长期上下文的任务(如语言建模)非常有用。
3.5.3.3.5 LSTM的缺点

LSTM的缺点如下:

  1. 线性增长的细胞状态 c ( t ) c(t) c(t)
    公式 c ( t ) = z ( t ) ⊙ i ( t ) + c ( t − 1 ) c(t)=z(t)⊙i(t)+c(t−1) c(t)=z(t)i(t)+c(t1)描述了细胞状态的更新方式,其中 z ( t ) z(t) z(t)是候选记忆内容, i ( t ) i(t) i(t)是输入门的激活值, c ( t − 1 ) c(t−1) c(t1)是上一时间步的细胞状态。
    这种更新方式可能导致细胞状态 c ( t ) c(t) c(t)在处理时间序列时线性增长,这可能不是最优的,因为它可能不会充分利用非线性激活函数的能力。
  2. 信息和错误信号的长时间存储:
    LSTM能够存储信息跨越任意时间滞后,并且能够将错误信号携带到较远的时间点。
    这种能力虽然是一个潜在的优势,但也可能带来问题,因为细胞状态可能会无限制地增长。
  3. 连续输入流的问题:
    如果给LSTM一个连续的输入流,细胞状态可能会无限制地增长,这可能导致输出挤压函数 h ( c ( t ) ) h(c(t)) h(c(t))的饱和。
    输出挤压函数的饱和意味着网络在输出端可能失去表达能力,无法有效地响应输入的变化。
Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐