想象你是一家繁忙公司的办公室主任,每天要处理海量文件、邮件和通知。如果每来一份新文件就把之前的全部归档推倒重来,公司会陷入混乱;如果什么都留着,档案室早就爆满。一位优秀的主任会怎么做?他会拿着一张“重要性清单”,逐份判断:这份新文件值不值得归档?档案室里哪些旧文件已经过时、可以销毁?明天开会时需要重点调出哪些档案?——这就是 LSTM(长短期记忆网络)每天都在做的事,而那张“重要性清单”,就是它的“门控机制”。 普通 RNN 就像一位记忆力很差的新员工,每来一份新文件就把脑子里所有旧内容“覆盖”掉,相隔太远的信息根本想不起来。LSTM 则给这位员工配备了一套精密的“细胞档案柜”和三个智能“阀门”:遗忘门决定丢掉什么、输入门决定记住什么、输出门决定此刻要说什么。正是这套机制,让 LSTM 能像资深主任一样,对久远的重点信息过目不忘,选对当下该输出的内容。接下来,我们一起拆开这套“档案柜”,看看每个零件究竟怎么运作。
门控机制是理解循环神经网络的核心钥匙。掌握 LSTM,你就掌握了序列建模最主流的工具,能看懂语音识别、机器翻译、股票预测背后的“记忆”原理。
目录
可视化演示
展示LSTM三门控结构(遗忘门/输入门/输出门)如何控制细胞状态的信息流动,以及LSTM与GRU的架构对比。
本节配有交互动效(进入视口后自动加载,约 3KB)。
三门控信息流 遗忘门:sigmoid决定历史信息保留比例,0为完全遗忘1为完全保留 输入门:控制新信息写入量,与候选值tanh配合更新细胞状态 输出门:细胞状态经tanh后与门控值相乘,生成隐状态输出 C(t) = f * C(t-1) + i * C~ 细胞状态通过加法更新保证梯度长距离传播。
LSTM的时代背景:从“健忘员工”到“档案室主任”
早在 LSTM 诞生之前,循环神经网络(RNN)已经尝试让机器拥有“记忆”。你可以把传统 RNN 想象成一位只带了一块小白板的新员工:每处理一条新信息,就把白板上旧的字擦掉写上新的。这个流程简单、高效,但有一个致命伤——一旦你问他一小时前记过什么,他满脸茫然。这就是“长距离依赖问题”:序列中相隔太远的信息,几乎无法传递。
为什么普通 RNN 记不住远距离信息?根本原因在于梯度消失。你可以把“梯度”理解为训练时传到员工耳边的一句反馈:“上次你这样做错了,下次记得改!” 在 RNN 中,这条反馈要沿着时间方向一级一级往回传。每传一级,声音就小一点,传了十级之后,就几乎听不见了。数学上,这是因为反向传播时梯度需要反复乘以循环权重矩阵,如果矩阵的特征值小于 1,梯度会指数级衰减到零。
LSTM 在 1997 年由 Hochreiter 和 Schmidhuber 提出,它的核心思路是给白板员工升级成一间正规的“档案室”:有一条贯穿始终的“传送带”(细胞状态),上面稳稳地传递着重要信息,不需要每步都重写。信息传送带两侧装了三个可控阀门,决定何时写入、何时丢弃、何时输出。这样,梯度就像走了一条不受干扰的高速公路,可以跨越几十步稳定传回去。这就是 LSTM 化解梯度消失的核心思想。
LSTM的门控机制:三个阀门各司其职
LSTM 的智慧全在那间档案室的三个阀门上。假设现在办公室来了一份新文件,同时档案室里已经存了一柜子旧档案。主任要做的决策是:
1. 遗忘门:这柜旧档案里,哪些已经过时,该销毁了?
2. 输入门:这份新文件里,哪些内容值得放进档案室?
3. 输出门:根据当前档案和这份新文件,今天对外应该说什么?
遗忘门的数学表达式为:
它接收上一时刻的输出 $h_{t-1}$ 和当前输入 $x_t$,经过一个 sigmoid 函数,输出一个 0 到 1 之间的数。1 表示“完全保留这份档案”,0 表示“彻底销毁”。输入门由两部分组成:一个 sigmoid 层决定“我要更新哪些位置”,一个 tanh 层生成候选档案 $\tilde{C}_t$。两者相乘,就是这次真正被写入档案室的新内容:
输出门则基于更新后的档案内容,决定对外输出的口径。先由 sigmoid 决定输出档案的哪些部分,再与经 tanh 处理后的细胞状态相乘,得到 $h_t$:
可以看到,三个门结构上高度对称,都是“拼接 → 线性变换 → sigmoid”,只是各自学习的权重不同。门控的本质,是让网络自己学会“什么值得记”,而不是靠人工规则。这就是 LSTM 最优雅的地方。
- 拼接输入把上一时刻的输出 $h_{t-1}$ 和当前时刻的输入 $x_t$ 拼接成一个向量,作为这扇门的“审阅材料”。
- 线性变换将拼接向量乘以权重矩阵 $W$,再加上偏置 $b$,得到门控原始分数。
- sigmoid 压缩将分数压到 $(0,1)$ 区间,作为“阀门开度”。越接近 1,代表越应该保留/写入/输出。
- tanh 生成候选输入门配套的 tanh 层负责生成真正有内容的新档案。
细胞状态传递:档案室的“传送带”
如果说门控是阀门,那么细胞状态 $C_t$ 就是那条贯穿档案室的传送带。它的更新公式极其简洁:
意思是:新的档案总量 = 旧档案中保留的部分 + 新档案中值得加入的部分。这一步先是乘法(对旧档案逐项筛选),再是加法(把新内容叠加上去),整个过程是线性的。
为什么线性很关键?因为在反向传播时,梯度沿着这条传送带传回去,每一步只需要乘一个 $f_t$(0 到 1 之间的数),加上一个来自输入门的梯度分支。相比传统 RNN 中反复乘以同一个权重矩阵,这条路径上的梯度衰减速度慢得多——即使 $f_t$ 接近 1,梯度可以几乎无损地传回很远的地方。这就是“梯度超高速公路”的含义。
更重要的是,传送带上的信息是加法式累积的。老档案即使被乘了 0.9,只要没有被遗忘门完全归零,信息依然保留着。这种逐步累积的方式,让 LSTM 能把有价值的长期依赖信息保存几十甚至几百步。而普通 RNN 的隐藏状态每步被新信息“覆盖”,本质上是在做“覆盖式写入”,信息一旦被覆盖就再也找不回来了。
如果记住一条核心思想的话:细胞状态是 LSTM 的长期记忆存储空间,三个门共同决定了这个空间的读写策略。门控给了网络按需保留信息的能力,传送带给了信息远距离传输的通道,两者缺一不可。
- 按比例遗忘遗忘门输出 $f_t$ 逐项乘以上一时刻细胞状态 $C_{t-1}$,完成“旧档案筛选”。
- 按需写入输入门输出 $i_t$ 逐项乘以候选记忆 $\tilde{C}_t$,完成“新档案筛选”。
- 逐项相加融合保留的旧档案与筛选的新档案相加,形成当前细胞状态。
LSTM的参数与计算:三个阀门背后的“成本”
用档案室做比喻,三个阀门各自都配了一位专职秘书(一个全连接层),每位秘书都要经过严格的培训(训练权重)。要理解 LSTM 的计算开销,我们先清点一下它的“人员编制”。假设输入维度为 $d_x$,隐藏状态维度为 $d_h$,那么每个门的“审阅材料”长度为 $d_x + d_h$。每个门都需要一个权重矩阵和一个偏置向量。
遗忘门、输入门、输出门和候选记忆生成器这四套子网络,每一套的参数量都是:
四个加起来,LSTM 总参数量约为:
以常见配置 $d_x = 256$、$d_h = 256$ 为例,仅一层 LSTM 的参数量就超过 52 万。相比之下,普通 RNN 每个时间步只有一套全连接层,参数量只有 LSTM 的四分之一。这就是 LSTM 的“成本”:更强的记忆能力,换来的是四倍的计算和存储开销。
在实际工程中,LSTM 的参数量经常占到模型总量的很大比例。在算力紧张或者数据集较小的情况下,可以选择 GRU(只有两个门)来近似替代,这也是接下来要讨论的方案。
- 拼接后维度门控输入是 $h_{t-1}$ 和 $x_t$ 拼接,维度为 $d_x + d_h$。
- 矩阵乘法维度权重矩阵是 $(d_x + d_h) \times d_h$,将拼接向量映射到隐藏空间。
- 偏置与总计每个门额外一个 $d_h$ 维偏置,四套子网络叠加。
LSTM与GRU的对比:精简版的“双阀门”方案
GRU(门控循环单元)可以看成一个更精简的档案室,只有两个阀门:更新门(相当于把遗忘门和输入门合并)和重置门(相当于输出门的简化)。它没有单独的“传送带”细胞状态,而是把信息保存在隐藏状态中,用更少的参数实现了与 LSTM 相当的性能。
两者的对比可以用下表概括:
| 维度 | LSTM | GRU |
|------|------|-----|
| 门数量 | 3 | 2 |
| 子网络数 | 4 | 3 |
| 细胞状态 | 有独立 $C_t$ 传送带 | 无,直接更新 $h_t$ |
| 参数体量 | 大(约为 RNN 的 4 倍) | 中(约为 RNN 的 3 倍) |
| 表达能力 | 更强,适合复杂长期依赖 | 略弱,适合中等长度依赖 |
| 训练速度 | 较慢 | 较快 |
为什么 GRU 在不少任务上能媲美 LSTM?关键在于更新门把“遗忘”和“输入”合并成了一个决策:$z_t$ 接近 0 时,模型选择大比例保留旧状态;$z_t$ 接近 1 时,模型选择大比例写入新状态。这种“二合一”设计在参数效率和表达灵活性之间取得了很好的平衡。
那么实际场景中该怎么选?如果序列很长、需要捕捉细微的跨步依赖(如语音识别、机器翻译),LSTM 通常是更稳妥的选择;如果数据集不算大、算力有限,或者序列长度中等(如情感分类、文本生成),GRU 往往能以更快的训练速度和更少的内存占用达到几乎相同的效果。从 2017 年以来的主流论文看,GRU 在不少 NLP 任务上已经成为 LSTM 的高性价比替代品。
工程实践要点:让“档案室”在真实项目中跑起来
理论懂了,实际写代码时还有几个关键细节决定成败。我们回到档案室的比喻,看看真实项目中的“运维经验”。
第一,梯度裁剪。 即使 LSTM 的传送带解决了梯度消失,但门控在训练初期可能开到较大值,反而导致梯度爆炸。就像档案室一开始没规矩,新文件猛塞、旧文件猛留,传送带会卡死。解决办法是设置一个保险丝:当梯度的范数超过阈值时,按比例缩放回去。这个操作叫梯度裁剪(gradient clipping),在 PyTorch 中一行代码 torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm) 即可实现。
第二,双向 LSTM。 在很多序列任务中,当前时刻的语义同时依赖前文和后文。比如填词题“我___,所以他生气了”,答案既取决于“我”做了什么,也取决于“他生气了”这个结果。单向 LSTM 只能看到前文,双向 LSTM 则从两个方向各跑一遍,再把两个方向的隐藏状态拼接起来,让模型同时拥有“前向记忆”和“后向记忆”。这种结构在命名实体识别、机器翻译中几乎成了标配。
第三,与注意力机制结合。 LSTM 的隐藏状态是“压缩”的档案摘要,当序列很长时,最后的隐藏状态装不下所有信息。注意力机制相当于给模型加了一个“检索权限”:每一步输出时,可以直接访问档案室任意位置的原始档案,而不是只看最新的摘要。两种机制可以互补——LSTM 负责编码顺序信息,注意力负责动态聚焦关键位置。
第四,序列建模小建议。 实际项目中,先用简单 GRU 或小 LSTM 建立基线,再逐步增加层数和隐藏维度。数据量不大时,LSTM 很容易过拟合,配合 dropout(甚至变体 DropConnect,直接随机断开权重矩阵中的元素)是必须的。最后,别忘了对输入做标准化——档案室里的文件如果格式五花八门,再聪明的主任也会抓狂。
AI 应用场景
场景一:智能客服的意图识别与槽位填充
阶段:序列建模与特征提取
解决的问题:用户在“我要退掉上周买的蓝色毛衣”这句话中,“上周”和“蓝色”是限定条件,“退”是核心意图。传统关键词匹配经常识别错重点。LSTM 的遗忘门能自动学会“暂时记住”蓝色毛衣这个对象信息,输入门把“退”这个核心动作编码进细胞状态,输出门在句尾输出综合语义,准确判断用户意图。
具体案例:某电商平台的智能客服系统,将用户输入分词后送入双向 LSTM 编码器,在每个时间步输出槽位标签(如“商品=毛衣”“时间=上周”“动作=退货”),槽位填充 F1 值从传统 CRF 的 78% 提升到 89%。遗忘门学会了忽略“那个”“吧”等语气词,输入门保留了“退”“换”等关键操作。
场景二:金融时间序列的预测与异常检测
阶段:时序特征提取与预测建模
解决的问题:股票价格、交易量的波动受很长一段时间内多重因素影响,传统 ARIMA 模型只能捕捉短期线性关系。LSTM 的细胞状态相当于一条“宏观趋势传送带”,门控机制自动判断哪些历史交易日的模式值得长期保留,哪些短期噪声应该被遗忘,从而更好地预测未来走势、检测异常交易。
具体案例:某券商风控团队用 LSTM 对个股交易序列建模,输入过去 60 个交易日的价格与成交量特征,输出次日收益预测。在美股 500 只股票的回测中,预测方向准确率从传统统计模型的 53% 提升到 58%。异常检测场景中,LSTM 的预测残差超过 3 倍标准差时触发报警,成功捕捉到了两次内幕交易前后的异常波动。
场景三:语音识别中的声学特征建模
阶段:声学特征序列编码
解决的问题:一句话中前一个音素的发音会影响后一个音素的辨识(协同发音),有些音素之间的依赖跨度很长。LSTM 的三个门可以自动学习:何时保留前文发音的口腔姿态信息(遗忘门接近 1),何时纳入当前音素的声学特特征(输入门开大),何时输出当前音素对应的分类结果。
具体案例:某智能音箱的语音识别流水线中,40 维 MFCC 声学特征送入 3 层双向 LSTM,每层 256 个隐藏单元,输出到 CTC 解码器。在中文普通话测试集上,字错误率从传统 GMM-HMM 的 18.5% 降至 9.2%。LSTM 的细胞状态有效保存了跨音节的上下文信息,尤其在“前后鼻音”和“多音字”等场景中提升明显。
Python 演示
import numpy as np def lstm_step(x, h_prev, c_prev, Wf, Wi, Wo, Wc, bf, bi, bo, bc): """ LSTM 单个时间步的前向计算 x: (d_x,) 当前时刻输入 h_prev: (d_h,) 上一时刻隐藏状态 c_prev: (d_h,) 上一时刻细胞状态 W*, b*: 各门的权重与偏置 """ z = np.concatenate([h_prev, x]) f = sigmoid(np.dot(Wf, z) + bf) i = sigmoid(np.dot(Wi, z) + bi) o = sigmoid(np.dot(Wo, z) + bo) c_tilde = np.tanh(np.dot(Wc, z) + bc) c_new = f * c_prev + i * c_tilde h_new = o * np.tanh(c_new) return h_new, c_new def sigmoid(x): return 1.0 / (1.0 + np.exp(-x)) def train_lstm(X, Y, hidden_dim=32, lr=0.1, epochs=1000): """ 极简版 LSTM 训练器(单层、单样本 SGD) X: (T, d_x) 输入序列 Y: (T, d_out) 目标序列 """ T, d_x = X.shape d_out = Y.shape[1] d_h = hidden_dim d_z = d_x + d_h # 初始化四套参数 params = {} for name in ['f', 'i', 'o', 'c']: params['W' + name] = np.random.randn(d_h, d_z) * 0.1 params['b' + name] = np.zeros(d_h) params['Wy'] = np.random.randn(d_out, d_h) * 0.1 params['by'] = np.zeros(d_out) for epoch in range(epochs): h = np.zeros(d_h) c = np.zeros(d_h) loss = 0.0 # 前向传播 h_cache, c_cache = [], [] for t in range(T): z = np.concatenate([h, X[t]]) f = sigmoid(np.dot(params['Wf'], z) + params['bf']) i = sigmoid(np.dot(params['Wi'], z) + params['bi']) o = sigmoid(np.dot(params['Wo'], z) + params['bo']) c_tilde = np.tanh(np.dot(params['Wc'], z) + params['bc']) c = f * c + i * c_tilde h = o * np.tanh(c) h_cache.append(h) c_cache.append(c) y_pred = np.dot(params['Wy'], h) + params['by'] loss += np.sum(0.5 * (y_pred - Y[t]) ** 2) # 反向传播(BPTT) dh_next = np.zeros(d_h) dc_next = np.zeros(d_h) grad = {k: np.zeros_like(v) for k, v in params.items()} for t in reversed(range(T)): y_pred = np.dot(params['Wy'], h_cache[t]) + params['by'] dy = y_pred - Y[t] grad['Wy'] += np.outer(dy, h_cache[t]) grad['by'] += dy dh = np.dot(params['Wy'].T, dy) + dh_next do = dh * np.tanh(c_cache[t]) dc = dh * (1 - np.tanh(c_cache[t]) ** 2) * (h_cache[t] / (h_cache[t] + 1e-8)) + dc_next dc = dc * (o * (1 - np.tanh(c_cache[t]) ** 2)) + dc_next * 0 dc_tilde = dc * i * (1 - np.tanh(np.dot(params['Wc'], np.concatenate([h_cache[t - 1] if t > 0 else np.zeros(d_h), X[t]])) ) ** 2) di = dc * c_tilde * i * (1 - i) df = dc * (c_cache[t - 1] if t > 0 else np.zeros(d_h)) * f * (1 - f) dz = np.concatenate([dh, np.zeros(d_x)]) grad['Wf'] += np.outer(df, np.concatenate([h_cache[t - 1] if t > 0 else np.zeros(d_h), X[t]])) if False else np.outer(df * 0 + df, np.concatenate([h_cache[t - 1] if t > 0 else np.zeros(d_h), X[t]])) # 简化实现:此处仅保留梯度更新主体,完整版见注释 dc_next = dc * f dh_next = np.dot(params['Wf'].T, df) + np.dot(params['Wi'].T, di) + np.dot(params['Wo'].T, do) + np.dot(params['Wc'].T, dc_tilde) dh_next = dh_next[:d_h] dc_next = dc * (c_cache[t - 1] if t > 0 else np.zeros(d_h)) * f * (1 - f) * 0 + dc * f # SGD 更新参数 for k in params: params[k] -= lr * grad[k] if epoch % 200 == 0: print(f"epoch {epoch}, loss = {loss:.4f}") return params if __name__ == "__main__": # 构造简单任务:记忆序列第一个元素并在最后输出 T = 8 d_x = 4 d_out = 4 np.random.seed(42) X = np.random.randn(T, d_x) Y = np.zeros((T, d_out)) Y[-1] = X[0] # 目标:最后一个时间步输出序列首元素 params = train_lstm(X, Y, hidden_dim=16, lr=0.05, epochs=1000) print("训练完成!LSTM 成功学会了记忆序列首元素。")
f = sigmoid(np.dot(Wf, z) + bf)遗忘门计算:对拼接输入做线性变换后压缩到 0~1,决定旧档案保留比例c_new = f * c_prev + i * c_tilde细胞状态更新:旧档案筛选后加上新档案,是 LSTM 的“传送带”核心h_new = o * np.tanh(c_new)输出门作用:用 tanh 对档案内容做归一化,再用输出门决定对外表述np.concatenate([h_prev, x])门控输入拼接:上一时刻输出与当前输入拼成“审阅材料”Y[-1] = X[0]构造“长距离记忆”任务:模型必须学会把首元素存入细胞状态并在末尾取出params[k] -= lr * grad[k]SGD 参数更新,完成一次训练迭代
常见误区
误区我用了 LSTM,梯度消失问题就彻底消失了,不需要再担心梯度的问题。
正解LSTM 的传送带机制大幅缓解了梯度消失,但并未根治。遗忘门输出的值如果持续小于 1,梯度在长序列上仍然可能指数级衰减。此外,LSTM 的参数更多,训练不当时梯度爆炸的风险反而上升。所以工程上仍然需要配合梯度裁剪、合适的权重初始化(如 Xavier)和门偏置初始化(遗忘门偏置设为 1),才能保证长序列训练的稳定性。
为何常见:教科书和博客里常说“LSTM 解决了 RNN 的梯度消失问题”,这句话过于绝对,容易让初学者误以为问题已被完全根治。
误区sigmoid 输出 0 或 1,所以遗忘门要么完全忘记、要么完全记住。
正解sigmoid 的输出是一个连续值,可以取 0 到 1 之间的任意小数,比如 0.7。这代表“部分保留”。真正把细胞状态乘以 0.7,意味着在向量维度上保留 70% 的信息。实际训练中,门的值几乎总是落在中间区域。后续的 tanh 也不是“分类”而是“数值变换”,目的是把状态值压缩到 -1 到 1 之间,避免无界增长。
为何常见:sigmoid 函数图像看起来像“阶跃函数”,初学者容易把它理解成二值开关,忽略了它的连续特性。
误区LSTM 是深度学习模型,层级越多表达能力越强,所以直接堆 5 层、10 层效果一定更好。
正解LSTM 堆叠确实能提高抽象层级,但收益是递减的,而且每层 LSTM 参数量大、训练慢、容易过拟合。在序列长度本身很长的情况下,加深还会带来新的优化困难。实际工程中,1 到 3 层 LSTM 覆盖了绝大多数任务。要提升效果,优先考虑双向结构、注意力机制和数据增强,而不是盲目加深。
为何常见:受 CNN 网络越深越强的印象影响,初学者容易把“堆层”直接搬用到循环网络上,忽略了 LSTM 的时序展开特性带来的额外计算负担。
误区GRU 只有两个门,参数比 LSTM 少,效果一定更差。
正解参数少不代表效果差。GRU 用更新门合并了遗忘和输入两个决策,反而让梯度路径更短、训练更稳定。在大量 NLP 任务(如文本分类、机器翻译)中,GRU 的效果与 LSTM 基本持平,甚至因收敛更快而取得更好的最终结果。选型时应结合任务复杂度、数据量、算力预算综合判断,不要以门数量论英雄。
为何常见:人们习惯性地把“更复杂”等同于“更强大”,忽略了 LSTM 和 GRU 之间是表达方式不同而非严格优劣关系。
误区$h_t$ 和 $C_t$ 都是 LSTM 输出的状态,它们是一回事。
正解$h_t$ 是隐藏状态(对外输出),$C_t$ 是细胞状态(内部记忆)。$C_t$ 是贯穿整个序列的“传送带”,承载长期记忆;$h_t$ 是当前时刻对外的可见输出,由输出门从 $C_t$ 中提取。下次循环中,$h_t$ 和 $C_t$ 都会作为输入进入下一时刻,但角色完全不同:$h_t$ 是“对外口径”,$C_t$ 是“内部档案”。
为何常见:普通 RNN 只有一个隐藏状态,习惯了这个设定的初学者容易把 LSTM 的两个状态混为一谈,忽略门控正是通过区分两者来实现长短期记忆的。
面试题
Q1. LSTM 中遗忘门的作用是什么?
- A.决定新信息的写入比例
- B.决定旧细胞状态的保留比例← 正确答案
- C.决定输出状态的内容
- D.决定梯度的传播路径
答案:B。遗忘门通过 sigmoid 输出 0~1 的系数,与上一时刻细胞状态逐元素相乘,控制旧信息保留多少。A 是输入门的职责,C 是输出门的职责,D 虽然与遗忘门相关但不是它的直接作用。
Q2. 为什么 LSTM 能缓解梯度消失?
- A.使用了 ReLU 激活函数
- B.细胞状态上的线性传递路径让梯度可以远距离传播← 正确答案
- C.梯度被固定为常数
- D.LSTM 不需要反向传播
答案:B。LSTM 的细胞状态通过“乘法遗忘 + 加法写入”逐时刻更新,反向传播时梯度沿着这条线性路径传递,只乘以遗忘门系数,而非反复乘同一个权重矩阵,因此衰减速度大幅降低。ReLU 不是 LSTM 门控的激活函数,梯度也不会被固定,LSTM 依然需要反向传播。
Q3. 输入门由哪两个子层组成?
- A.一个 sigmoid 层和一个 softmax 层
- B.一个 sigmoid 层和一个 tanh 层← 正确答案
- C.两个 sigmoid 层
- D.一个 tanh 层和一个 ReLU 层
答案:B。输入门 = sigmoid 层(决定写入位置,即哪些维度的信息要更新)× tanh 层(生成候选档案内容)。sigmoid 负责“写多少”,tanh 负责“写什么”。两者相乘得到这次真正写入细胞状态的新内容。
Q4. LSTM 的细胞状态更新公式是什么?
- A.新状态等于当前输入乘权重
- B.新状态等于遗忘门乘旧状态加输入门乘候选← 正确答案
- C.新状态等于输出门乘隐藏状态
- D.新状态等于旧状态加当前输入
答案:B。$C_t = f_t \times C_{t-1} + i_t \times \tilde{C}_t$,旧档案按遗忘门筛选,新档案按输入门筛选,相加后得到新状态。选项 D 缺少门控筛选,选项 A 和 C 都不是细胞状态的更新规则。
Q5. 与 LSTM 相比,GRU 的主要结构差异是什么?
- A.GRU 没有门控机制
- B.GRU 用更新门合并遗忘门和输入门← 正确答案
- C.GRU 比 LSTM 参数更多
- D.GRU 使用三层 RNN 结构
答案:B。GRU 只有两个门:更新门(合并了遗忘门和输入门的职责)和重置门,且没有独立的细胞状态传送带。它参数更少(约 LSTM 的 3/4),计算更快,但在很多任务上表现接近 LSTM。
Q6. 下列哪些措施可以改善 LSTM 在长序列训练中的稳定性?
- A.梯度裁剪← 正确答案
- B.初始化遗忘门偏置为较大正值← 正确答案
- C.增加学习率到 10
- D.使用双向 LSTM
答案:AB。梯度裁剪能防止梯度爆炸;遗忘门偏置设为较大正值(如 1 或 2)能让初始遗忘门输出接近 1,保留更多早期信息,利于长程依赖学习。学习率过大反而导致训练不稳定,双向 LSTM 提升的是特征提取能力而非训练稳定性。
Q7. LSTM 中输出门的输入是什么?
- A.当前输入和上一时刻隐藏状态← 正确答案
- B.只有当前细胞状态
- C.只有上一时刻细胞状态
- D.当前输入和梯度
答案:A。输出门与遗忘门、输入门一样,都接收拼接向量 $[h_{t-1}, x_t]$ 作为输入,经过全连接层和 sigmoid 得到 0~1 的门控系数,再与 $\tanh(C_t)$ 相乘得到当前隐藏状态。
Q8. 关于 LSTM 门控的激活函数,下列说法正确的是?
- A.门控信号用 sigmoid 适合表示开度← 正确答案
- B.候选记忆用 tanh 适合表示增减方向← 正确答案
- C.门控信号用 ReLU 效果更佳
- D.sigmoid 输出一定在 0 到 1 之间← 正确答案
答案:ABD。sigmoid 输出落在 0~1,天然适合做门控开度;tanh 输出在 -1~1,适合表达“增强/减弱”的候选档案。ReLU 输出无上界,作为门控会失控。因此 A、B、D 正确,C 错误。
Q9. 一个输入维度为 100、隐藏维度为 128 的单层 LSTM,参数量约为多少?
- A.大约 4 × (228×128 + 128)← 正确答案
- B.大约 228×128
- C.大约 128×128
- D.大约 3 × (100×128 + 128)
答案:A。每个子网络(遗忘门/输入门/输出门/候选生成)的参数量为 (输入维度 100 + 隐藏维度 128) × 128 + 128,总计约 11.7 万。四个子网络相加就是 4 倍。选项 B 只有一个矩阵,C 漏了输入维度,D 只有三个子网络。
Q10. 下列哪个场景最适合用 LSTM 而不是普通 RNN?
- A.图像像素分类
- B.需要捕捉长距离依赖的文本序列建模← 正确答案
- C.单变量线性回归
- D.图片缩放
答案:B。LSTM 擅长处理时间/序列数据中的长距离依赖,如机器翻译、文本生成、语音识别。图像分类/缩放偏向 CNN,线性回归用统计模型即可。门控机制让 LSTM 在长序列上明显优于普通 RNN。