十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

第299篇 RNN与LSTM——序列建模的基础

第299篇 RNN与LSTM——序列建模的基础 前面聊了视觉里程计中的DeepVO里面用到了LSTM来处理图像序列。你可能对RNN和LSTM有个大概印象但细节记不太清了。这篇我们来好好捋一捋这两个在机器人领域曾经非常重要的序列建模工具。虽然现在Transformer在很多任务上已经取代了RNN/LSTM但在一些实时性要求高的场景比如机器人控制、传感器信号处理LSTM仍然是主流选择。面试中问到序列建模RNN/LSTM是绕不开的基础。为什么需要循环神经网络传统的CNN和全连接网络有个假设输入之间是独立的。图像分类就是这个情况一张猫的图片跟另一张狗的图片没有时序关系。但机器人处理的数据很多是序列性质的。激光雷达的连续扫描、IMU的时间序列、语音信号、关节角度的历史轨迹——当前时刻的值跟过去密切相关。你要预测机器人下一秒的位置不能只看当前的速度还得知道加速度和历史轨迹。RNN的核心思想是引入记忆。每个时间步网络不仅接收当前输入还接收上一步的隐藏状态。这个隐藏状态就像网络的记忆编码了之前所有输入的信息。# 最简单的RNN单元 class SimpleRNN: def __init__(self, input_size, hidden_size): self.Wx np.random.randn(hidden_size, input_size) * 0.01 self.Wh np.random.randn(hidden_size, hidden_size) * 0.01 self.b np.zeros(hidden_size) def step(self, x, h_prev): # 当前输入 上一步隐藏状态 - 新的隐藏状态 h np.tanh(self.Wx x self.Wh h_prev self.b) return h看起来很简单对吧每个时间步就做一次矩阵乘法加一个tanh。但问题就出在这个简单的结构上。梯度消失RNN的致命伤RNN训练用的是BPTTBackpropagation Through Time把循环展开成多层网络然后反向传播。问题在于当你需要回溯很多时间步时梯度会指数级衰减或爆炸。想象一下隐藏状态的更新是h_t tanh(W·h_{t-1} ...)。反向传播时梯度要连乘W的转置很多遍。如果W的特征值小于1梯度会指数衰减到接近零如果大于1梯度会爆炸。这就是梯度消失和梯度爆炸问题。梯度消失意味着网络学不到长距离的依赖关系。比如一个序列中第1步的信息对第100步很重要但梯度传了100步后已经消失了网络无法建立这个联系。举个具体的例子。假设你在训练一个LSTM来预测机器人的未来轨迹输入是过去50步的关节角度。如果第5步的一个关键动作比如碰到障碍物对第50步的输出很重要简单RNN很难学到这个关系因为梯度从第50步传回第5步时已经衰减到几乎为零了。网络只能学到最近几步的局部模式。梯度爆炸相对好处理用梯度裁剪gradient clipping就行——梯度超过某个阈值就按比例缩小。PyTorch里一行代码就能搞定torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm)。但梯度消失没有这么简单的解法。LSTM用门控机制解决长期依赖LSTMLong Short-Term Memory是Hochreiter在1997年提出的专门解决RNN的梯度消失问题。它的核心设计是引入了三个门和一个独立的细胞状态cell state。细胞状态C是一条信息高速公路信息可以沿着它几乎无衰减地传递。三个门控制信息的流入流出遗忘门决定丢弃哪些旧信息输入门决定写入哪些新信息输出门决定读出哪些信息。# LSTM的核心计算 # f_t sigmoid(Wf [h_prev, x_t] bf) # 遗忘门 # i_t sigmoid(Wi [h_prev, x_t] bi) # 输入门 # o_t sigmoid(Wo [h_prev, x_t] bo) # 输出门 # C_t f_t * C_prev i_t * tanh(Wc [h_prev, x_t] bc) # h_t o_t * tanh(C_t)关键在遗忘门。当遗忘门接近1时细胞状态几乎原封不动地传到下一步梯度也能畅通无阻地回传。这就解决了长距离依赖的问题。网络可以学会在合适的时机记住和遗忘信息。LSTM的参数量比简单RNN大不少。四个权重矩阵三个门加一个候选值每个都是(hidden_size, input_size hidden_size)的维度。这意味着更容易过拟合训练时需要更多的数据和正则化。GRULSTM的简化版GRUGated Recurrent Unit是2014年Cho提出的LSTM简化版。它把遗忘门和输入门合并成一个更新门还去掉了独立的细胞状态只用隐藏状态来传递信息。GRU的参数比LSTM少约三分之一训练速度更快在很多任务上效果和LSTM相当。如果你的数据量不大或者序列不太长GRU通常是个不错的选择。但在一些需要精确控制长期记忆的任务上比如长文本生成、复杂的时序推理LSTM的表现通常更好。机器人领域两种都有人用没有绝对的优劣。还有个变种叫双向LSTMBiLSTM。它同时从前向后和从后向前处理序列把两个方向的隐藏状态拼接起来。这在离线分析任务中很有用比如给一段录制的传感器数据做标注前后文信息都能利用。但在实时控制中不能用因为你没有未来的信息。面试时如果被问到BiLSTM要能区分在线和离线场景的适用性。在机器人中的应用场景RNN/LSTM在机器人中有哪些实际应用场景传感器融合是一个典型场景。机器人有多种传感器IMU、编码器、激光雷达采样率各不相同。用LSTM可以融合这些异构的时间序列数据输出统一的狀態估计。相比卡尔曼滤波LSTM能处理非线性的观测模型但需要大量训练数据。运动预测也很常见。预测周围行人和车辆的未来轨迹对机器人的路径规划至关重要。用LSTM编码历史轨迹序列预测未来若干步的位置。Social LSTM2016是这个方向的经典工作它引入了社会池化机制来建模行人之间的交互。控制策略中也会用到LSTM。对于需要记忆的任务比如迷宫导航、物体搜索纯前馈网络不够用需要某种记忆机制。LSTM可以作为策略网络的记忆模块让agent记住之前探索过的区域。面试要点面试中聊RNN/LSTM有几个点要能讲清楚。梯度消失的原因和LSTM的解决方案。这是最基础的面试官一定会问。你要能解释为什么连乘导致梯度消失LSTM的细胞状态为什么能缓解这个问题。LSTM和Transformer的对比。Transformer用自注意力机制直接建模任意两个位置之间的关系不受距离限制。而LSTM的信息传递是逐步的距离越远衰减越多。但Transformer的计算复杂度是O(n²)对长序列不友好LSTM是O(n)的推理速度快。在机器人实时控制场景中这个差异很关键。实际使用中的调参经验。LSTM的层数一般1-3层就够了太深容易过拟合。hidden_size根据任务复杂度选通常128到512之间。dropout一般加在层与层之间而不是时间维度上。序列长度也是个关键参数太长训练慢且梯度仍然可能消失太短丢失上下文信息。实践中一般截断到100-200步用truncated BPTT来训练。这些经验在面试中能体现你的实战能力。PyTorch还是TensorFlow两个框架都支持LSTM但PyTorch的接口更直观。PyTorch中nn.LSTM的输入格式是(seq_len, batch, input_size)很多人会被这个维度顺序搞晕。建议一开始就写个小脚本验证输入输出的shape避免在调试时浪费时间在维度问题上。给你的建议虽然现在NLP领域基本被Transformer统治了但在机器人的时序处理中LSTM仍然有用武之地。建议你动手实现一个简单的LSTM不用框架纯numpy写前向和反向传播。这个过程会帮你真正理解门控机制的工作原理。然后找一个机器人相关的时序任务练手比如用IMU数据做手势识别或者用关节角度预测机器人末端轨迹。跑通之后你就算有实战经验了。上一篇第298篇 视觉里程计中的深度学习方法下一篇预告第300篇 Transformer——从注意力机制到机器人应用
返回列表