LSTM 论文(Hochreiter & Schmidhuber, 1997)精读(四)

文章:Sepp Hochreiter, Jürgen Schmidhuber; Long Short-Term Memory. Neural Comput 1997; 9 (8): 1735–1780. doi: https://doi.org/10.1162/neco.1997.9.8.1735

传统 反向传播算法(BPTT, Backpropagation Through Time) 的误差传播特性,Hochreiter(LSTM 的提出者之一)在 1991 年对其误差随时间衰减的数学分析,重点揭示 “误差消失(vanishing gradients)” 的根本原因。


3 CONSTANT ERROR BACKPROP(恒定误差反向传播)


3.1 EXPONENTIALLY DECAYING ERROR(指数衰减误差)

 背景知识:为什么要强调“非输入单元 i”、“非输出神经元 j”?

这是因为在 反向传播(Backpropagation) 中,不同类型的神经元 —— 输入层、中间隐藏层、输出层 —— 处理方式是不同的


🌟 一、输入单元(Input Units)

输入单元 不进行反向传播计算,因为:

  • 它们只是接收外部输入数据(比如特征向量),

  • 并不会有激活函数和误差信号可计算,

  • 它们不需要被“更新”或“训练”——它们就是数据本身。

👉 所以反向传播过程不涉及输入单元。


🌟 二、输出单元(Output Units)

输出单元的误差是最容易计算的:

\delta_k(t) = f_k'(net_k(t)) \cdot (d_k(t) - y_k(t))

  • 这里的 d_k(t) 是目标输出,y_k(t) 是模型实际输出。

  • 所以对于输出神经元来说,误差信号是已知的,直接从目标值与预测值计算而来。


🌟 三、非输出单元(Hidden Units,隐藏层)

这才是重点:

  • 隐藏层没有目标值可比较,它的误差信号只能通过“传播回来”的方式计算

  • 它们通过从下一层的所有神经元接收到的误差信号,反向传播回来进行计算:

\delta_j(t) = f_j'(net_j(t)) \cdot \sum_i w_{ij} \cdot \delta_i(t+1)

这就是后面在原文里看到的公式。

单元类型是否参与误差计算误差来源方式
输入单元❌ 不参与没有误差,只是传递输入
输出单元✅ 参与从预测值和目标值直接算
非输出单元(隐藏层)✅ 参与通过反向传播间接计算

所以原文才会特意说:

"is the activation of a non-input unit i…"
"some non-output unit j’s backpropagated error signal is…"

这是在告诉你 —— “这些公式是用于计算隐藏层的误差,不是输入层,也不是输出层。”

而原文开头特意提到输出神经元:

对于输出神经元 k,其在时间步 t 的目标值记为 d_k(t),使用的是 mean squared error(均方误差,MSE)

 原因:一、在反向传播中,误差的源头就是输出层

神经网络的训练目标是:
👉 让输出尽可能接近目标值,也就是最小化损失函数。

而损失函数(像 MSE)只能在输出层才能直接计算,因为:

  • 只有输出层有“模型预测值y_k(t)

  • 只有它能和“目标值d_k(t) 比较

比如均方误差公式:

E = \frac{1}{2} \sum_k (d_k(t) - y_k(t))^2

这个公式就是在输出神经元那里才成立的。

 二、输出层的误差是反向传播的“起点”

输出层误差信号的计算公式是:

\delta_k(t) = f_k'(net_k(t)) \cdot (d_k(t) - y_k(t))

你可以理解成:

  • 差值部分: (d_k(t) - y_k(t))是“你到底错了多少”

  • 导数部分:f_k'(net_k(t)) 是这个误差对前面神经元影响有多大(灵敏度)

这个误差信号 \delta_k(t) 是第一步计算出来的,然后才“传”回去给前面的隐藏层。

角色为什么要特别提原因
输出神经元起点 & 可对比目标是误差的源头,是唯一能直接计算误差的地方
隐藏神经元间接计算误差要依赖从输出层回传下来的误差信号

💡 反向传播必须从输出层开始计算误差,然后才能传回隐藏层,所以它才是“第一步”,要特别提到!


传统 BPTT(例如 Williams 和 Zipser,1992)

对于输出神经元 k,其在时间步 t 的目标值记为 dk(t),使用的是mean squared error 均方误差(MSE)

其中:

“is the activation of a non-input unit i with differentiable activation function fᵢ

“是一个非输入单元 i 的激活值,该单元有一个可微分的的激活函数 fᵢ

🔹 non-input unit i
就是说这个单元不是输入层的神经元,而是在隐藏层或输出层的某个神经元,编号是 i

🔹 activation function fᵢ
激活函数就是决定神经元输出的函数,比如:

  • sigmoid

  • tanh

  • ReLU
    这些函数通常是可微分的(differentiable),这样才能进行梯度下降。


    "netᵢ(t) is unit i's current net input, and wᵢⱼ is the weight on the connection from unit j to i."

     net inputnet 不是 network,而是:

    net = 净的、总和之后的

    比如英语里还有这种说法:

    • net profit(净利润)

    • net weight(净重)

    • 这是说:unit i 当前的净输入是 net_i(t)

    • 通常计算方式是:

      net_i(t) = \sum_j w_{ij} \cdot y_j(t-1)

    • 即:所有连接到它的上一个时间步的单元 j 的输出值 y_j(t-1),乘以各自的权重 w_{ij},加在一起。

    • w_{ij}:从单元 j 到单元 i 的连接权重。


    Some non-output unit j's backpropagated error signal is

    中文解释:

    • 这里在讲:隐藏层中一个非输出神经元 j 的误差信号怎么计算

    🔹 拆解一下公式:

    1. \delta _j(t ):表示在时间 t,神经元 j 的反向传播误差。

    2. f'_j(net_j(t)):是 j 神经元的激活函数的导数(在 net_j(t) 处求导)。

    3. w_{ij} \cdot \delta_i(t + 1)将当前单元 j 的误差,反向传播回来:
      下一个时间步的所有目标神经元 i 处,获取误差信号 \delta_i,并乘以连接权重 w_{ij}

    🟡 换句话说:
    “反向传播时,神经元 j 的误差信号是下一个时刻各目标神经元误差,乘以对应权重,加权后再乘以激活函数的导数。”

    The corresponding contribution to wⱼₗ's total weight update is β δⱼ(t) · yₗ(t−1),
    where β is the learning rate, and l stands for an arbitrary unit connected to unit j.

    这一句在说:这个误差会怎样作用到权重更新上(也就是权重怎么学习)

    🔹 拆解:

    • w_{jl}:表示从单元 l 到单元 j 的连接权重

    • y_l(t-1):是上一个时间点,单元 l 的输出

    • \delta_j(t):当前时间点 j 单元的误差

    • β:学习率(控制每次权重调整的步长)

    🔸 所以这一项是:

    \Delta w_{jl} = \beta \cdot \delta_j(t) \cdot y_l(t-1)

    也就是说:

    我们根据当前误差大小\delta_j(t)上一个神经元输出y_l(t-1),来更新连接权重 w_{jl}

    这是标准的 反向传播权重更新公式,也称作梯度下降更新法则的一部分

    ✅ 总结成一句话:

    当前时刻某个非输出神经元的误差由下一时刻的误差反传回来,然后再用这个误差乘以上一时刻输入,乘以学习率,去更新连接到它的权重。


     Hochreiter 的分析(1991)

    分析重点:误差从某一单元 u 在时间 t,反向传播 q 步后到达另一个单元 v 时会经历怎样的“缩小”或“放大”?

    假设:
    • 网络为全连接;

    • 考虑非输入单元的误差从 uv 的传播;

    • 传播 q 步的误差变化率为:

    Outline of Hochreiter's analysis (1991, page 19–21). Suppose we have a fully connected net whose non-input unit indices range from 1 to n.

    我们考虑一个完全连接的递归神经网络(RNN),它的非输入神经元编号是从 1 到 n,也就是说,每个神经元都可以连接到其他所有神经元。

    Let us focus on local error flow from unit u to unit v (later we will see that the analysis immediately extends to global error flow).

    我们先聚焦在“局部误差传播”上,也就是从一个神经元 u 到另一个神经元 v 的误差信号传播过程。之后,这个分析可以很自然地扩展到整网的“全局误差传播”(global error flow)。

    The error occurring at an arbitrary unit u at time step t is propagated "back into time" for q time steps, to an arbitrary unit v.

    假设在时间 t,神经元 u 上有一个误差信号,我们把这个误差向后传播 q 个时间步,追踪它传播到了另一个神经元 v 的路径和变化。这就是 RNN 中所谓的 “反向传播通过时间”(BPTT)。
    🔸“The error occurring at an arbitrary unit u”

    在任意一个神经元 u 上产生的误差,(arbitrary 是“任意的”的意思,也就是说不固定是哪个神经元)

    🔸“at time step t”

    在第 t 个时间步发生的,(比如 RNN 的输入是一个序列,第 t 步代表第 t 个输入)

    🔸“is propagated 'back into time'”

    会“沿时间向后”传播,(这是指 RNN 的反向传播过程 BPTT——Backpropagation Through Time)

    🔸“for q time steps”往回传播 q 个时间步,(比如从时间点 t 向过去的 t-1, t-2, ..., t-q 传播误差信号)
    🔸“to an arbitrary unit v”传播到了某个任意的神经元 v 上

    整句简洁翻译:

    第 t 个时间步,在某个神经元 u 上产生的误差信号,会沿时间向后传播 q 个时间步,直到传播到某个神经元 v。

    🧠 举个小例子帮助你理解:

    比如你有一个 RNN,在时间步 t=5 的时候,你发现某个输出神经元(比如单元 u)有误差。你希望用 BPTT 把这个误差反向传播到网络前面几步,比如 t=4、3、2……,看看它是否是因为之前某个神经元 v 的输出影响了当前的误差。

    所以这个过程就是在分析:
    “t=5 的误差,是不是 t=2 的神经元 v 造成的?”
    如果是,那就要把这个误差信号,反向传播 q=3 步,传回 t=2 时刻的神经元 v。


    This will scale the error by the following factor:

    在这个传播过程中,这个误差会被缩放(scale)——要么变小(衰减),要么变大(爆炸)——关键就在下面这个公式。

    情况 1:q = 1

    很简单,就是激活函数导数 × 连接权重。

    情况 2:q > 1

    误差经过多个中间单元传播,需要使用链式法则逐步累乘

    其中:

    • l_0 = u, l_q = v

    • 外部的求和符号(多个 Σ)表示:

      • 枚举所有可能的中间神经元路径,比如从 u(l_0) → l₁ → l₂ → ... → v( l_q )。

      • 对应的是网络中所有从 u 到 v 的不同路径。

      • 内部的乘积符号(Π)表示:

        • 每条路径上传播误差时,每经过一个神经元,误差都会乘上:

          • f'_i(net_i):激活函数的导数(如 sigmoid 的导数 ≤ 0.25)

          • w_{ij}:权重

    • 这个公式的作用是什么?

      它是为了描述:在时间步 t 上,单元 u 的误差是如何“通过时间”反向传播 q 步,传递到时间   ( t - q) 的某个单元 v 上的。
    •  每一步发生了什么?

      在一个 RNN 中,误差是一步一步往回传的:

      🔁 每一步的传递:

      每一次从 t回传到 t-1,都要乘两个东西:

    • 激活函数的导数f'(net),通常 < 1
      👉 表示当前神经元对误差的“响应程度”,如果小于 1,误差就会缩小

    • 权重w_{ij}
      👉 当前连接的强度,也通常在 [−1,1] 范围

    • 所以每传一步,误差就变成了


    🧊 梯度消失是怎么来的?

    (note that since the summation terms may have different signs, increasing the number of units n does not necessarily increase error flow)

    解释:即使你网络中有很多神经元 n,这些误差路径相加起来也不一定会使误差总量变大,因为:

    • 有些路径会让误差变成正数,有些变成负数,它们相加可能互相抵消

    • 此外,如果每一步的激活函数导数都很小(比如 sigmoid 导数 < 1),这些连乘就会导致误差迅速衰减到接近 0

    这段内容是 Hochreiter  对 RNN 梯度爆炸和梯度消失问题的直观解释。

    Intuitive explanation of equation (2). If
    f'_{l_m}(net_{l_m}(t - m)) \cdot w_{l_m, l_{m-1}}| > 1.0
    for all m (as can happen, e.g., with linear f_{l_m}) then the largest product increases exponentially with q.

    如果每一层(或每一步)的导数乘权重的绝对值都 大于1,也就是说:

    \left| f'(net) \cdot w \right| > 1

    例如使用线性激活函数时,就可能出现这种情况。

    那么,多步相乘时,这个乘积会指数级增长。也就是说:

    📈 误差会不断放大(梯度爆炸)

    That is, the error blows up, and conflicting error signals arriving at unit v can lead to oscillating weights and unstable learning(for error blow-ups or bifurcations see also Pineda 1988, Baldi and Pineda 1991, Doya 1992)

    也就是说,误差会“爆炸”,最后导致:

    • 在某个神经元 v 上,来自不同路径的误差会互相冲突(可能正负不同)

    • 导致权重来回震荡(oscillate)

    • 网络训练不稳定,根本学不好!

    On the other hand, if
    |f'_{l_m}(net_{l_m}(t - m)) \cdot w_{l_m, l_{m-1}}| < 1.0
    for all m, then the largest product decreases exponentially with q.

    反过来,如果每一层导数乘权重的绝对值都小于 1,那么:

    • 多次相乘后会指数级减小

    • 误差会不断变小(📉梯度消失)

    That is, the error vanishes, and nothing can be learned in acceptable time.

    这叫梯度消失,网络无法学习长期依赖。你可能训练了一年,结果前面几个时间步的东西都没学会。

    If f_{l_m} is the logistic sigmoid function, then the maximal value of f'_{l_m}is 0.25.

    如果你用的是经典 sigmoid 激活函数:

    f(x) = \frac{1}{1 + e^{-x}}

    它的导数最大值是 0.25,也就是说:

    f'(x) = f(x)(1 - f(x)) \leq 0.25

    If y_{l_{m-1}} is constant and not equal to zero, then |f'(net_{l_m}) \cdot w_{l_m, l_{m-1}}|takes on maximal values where it goes to zero for |w_{l_m, l_{m-1}}| \to \infty, and is less than 1.0 for |w| < 4.0

    即使你想通过“增大权重”来让误差不消失,也行不通

    • 权重太大:w \to \infty,sigmoid 饱和,导数 f' \to 0,乘积依然趋近于0

    • 权重在 4 以内:导数本来就小,乘积依然 < 1,误差仍然会衰减

    • 为什么是 4?来源是:

      如果使用的是 sigmoid 激活函数(logistic sigmoid):

      • 它的导数最大值是 0.25

      • 所以,只要权重 ∣w∣<4|w| < 4,就会导致:

      |w| \cdot f'(net) < 1 ]

      ⇒ 梯度在传播过程中会 每一步都乘以一个 <1 的数 ⇒ 逐渐变小 ⇒ 梯度消失

    Hence with conventional logistic sigmoid activation functions, the error flow tends to vanish as long as the weights have absolute values below 4.0...

    即使你调整初始化权重大小、或者增大学习率,都解决不了这个根本问题:

    • 学习率再大,也只是在传回误差后乘个系数,不会改变误差 自身的传递比例

    • 大权重会让激活函数饱和 → 导数为0 → 传递彻底断掉

    🚨 无论你怎么调学习率和权重,只要使用 sigmoid 激活函数,误差在反向传播时都会被不断压缩,最终导致梯度消失,模型学不到长期依赖。


    总结:

    1. Sigmoid 函数的特点决定了“梯度消失”几乎不可避免:

    • sigmoid 的导数最大是 0.25(出现在输入是0的时候)

    • 输入一旦偏大或偏小,导数很快就趋近于 0(函数进入“饱和区”)

    • 所以在反向传播时,链式法则中一堆导数连乘:

      \delta \propto f'_1 \cdot w_1 \cdot f'_2 \cdot w_2 \cdot \cdots

      每个 f'_i \leq 0.25,乘多了就会接近 0 ⟶ 梯度消失

    • 即使你:

      • 把权重初始化很大(但这样会让 sigmoid 饱和,反而导数变得更小)

      • 学习率设置很大(只会加快训练,但不会解决梯度传不回来的问题)


    2. 其他激活函数可能导致“梯度爆炸”:

    • 比如 ReLU、tanh、线性激活函数,导数不一定小于1

    • 如果再配合权重比较大,就可能出现:

      • \delta \propto f'_i \cdot w_i > 1

      • 连乘放大 ⟶ 梯度爆炸

    • 例如 RNN 中的 tanh 激活配合长时间传播,很容易出现爆炸

    只要使用的是 sigmoid 激活函数,反向传播过程中不管权重大小或学习率如何,最终都会出现梯度消失的问题。而使用其他激活函数时,如果导数和权重的乘积大于 1,就有可能引起梯度爆炸。

    ### 关于双向LSTM的经典学术论文 双向LSTM(Bidirectional LSTM, BiLSTM)是一种扩展的循环神经网络模型,通过结合前向和后向的信息来增强对序列数据的理解能力。以下是几篇经典的学术论文,这些论文奠定了BiLSTM的基础并展示了其应用价值。 #### 1. **Schafer and Cuay&aacute;huitl (2008)** 这篇论文首次提出了双向RNN的概念,并讨论了如何利用过去和未来的上下文信息来提高预测精度[^3]。虽然该论文主要关注的是语音识别任务,但它为后续的研究提供了理论基础。 #### 2. **Graves et al., &ldquo;Speech Recognition with Deep Recurrent Neural Networks,&rdquo; ICASSP 2013** 在这项工作中,Alex Graves等人探讨了深度双向LSTM在语音识别中的表现。他们证明了通过堆叠多层双向LSTM可以获得更高的抽象层次,从而显著提升性能。这项工作被认为是现代深度学习框架中广泛采用双向LSTM的重要原因之一。 #### 3. **Hochreiter and Schmidhuber, &ldquo;Long Short-Term Memory,&rdquo; Neural Computation, 1997** 尽管这不是专门针对双向LSTM的文章,但它是LSTM的核心奠基之作。文中提到的方向性局限启发了许多后来的工作,包括引入双向机制以解决单向LSTM无法充分利用未来信息的问题。 #### 4. **Schuster and Paliwal, &ldquo;Bidirectional Recurrent Neural Networks,&rdquo; IEEE Transactions on Signal Processing, 1997** 这是最早提出双向RNN概念的一篇文章之一。作者描述了一种方法,即同时训练正向传播和反向传播路径上的隐藏状态表示,这成为构建现代双向LSTM的关键技术思路。 #### 实验对比分析 为了进一步验证不同模型的效果差异,可以参考表1的内容,其中列出了线性回归、CNN、LSTM以及融合版本(如CNN-LSTM)等多种算法的表现比较[^4]。这种定量评估有助于理解为何双向LSTM能够在某些场景下脱颖而出。 ```python import tensorflow as tf from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Bidirectional, LSTM, Dense model = Sequential() model.add(Bidirectional(LSTM(64), input_shape=(timesteps, features))) model.add(Dense(units=1)) model.compile(optimizer=&#39;adam&#39;, loss=&#39;mse&#39;) print(model.summary()) ``` 上述代码片段展示了一个简单的双向LSTM实现方式,可供初学者快速上手测试基本功能。 ---
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值