☰
NYU-DLSP20 第 6 周技术笔记:CNN 三大应用与 RNN/GRU/LSTM 序列建模实战指南
2026/10/10 1:25:06 网站建设 项目流程
  • 示例工程

【免费下载链接】NYU-DLSP20

NYU Deep Learning Spring 2020

项目地址:https://gitcode.com/gh_mirrors/pyt/pytorch-Deep-Learning
点击查看免费下载

本篇文章以 NYU Deep Learning Spring 2020(仓库目录 docs/pt/week06/06.md 的葡萄牙语周摘要)为核心骨架,系统梳理第 6 周的全部技术主线:卷积神经网络在数字识别、多尺度人脸检测与语义分割三大场景的落地方法,以及循环神经网络(RNN)的梯度问题与 Attention、GRU、LSTM、Seq2Seq、记忆网络等演进方案。同时结合仓库中对应的英文详细课堂笔记(docs/en/week06/06-1.md、docs/en/week06/06-2.md、[docs/en/week06/06-3.md))与可运行的 PyTorch 实践(08-seq_classification.ipynb、09-echo_data.ipynb、res/sequential_tasks.py),还原从模型架构到训练循环的完整实战链路。读者学完后将掌握:多尺度检测与 NMS 的系统设计思路、RNN 梯度消失/爆炸的原理与缓解手段、GRU/LSTM 门控公式的逐项解读,以及用 PyTorch 复现"RNN vs LSTM"对比实验并解释其性能差异的能力。

一、Lecture Part A:卷积神经网络的三大典型应用

原文档第一部分(对应英文详细笔记 docs/en/week06/06-1.md)聚焦于把上一讲学到的卷积网络"用起来":从最经典的数字识别出发,逐步过渡到目标检测与逐像素分类的语义分割。三个案例共享一个核心思想——用卷积输出的空间结构来对应输入上的窗口,即卷积网络天然是"滑动窗口"式的,输出图上每个位置都代表输入上一个窗口的分类得分。

1. 邮政编码(5 位数字)识别:多分类器投票 + 最短路径约束

第一个案例是从单个数字识别升级到"5 位非重叠邮政编码"的识别。系统没有被告知如何切分每一位数字,只知道必须输出 5 个数字。解决方案是训练4 个不同卷积核宽度的卷积网络,每个网络在最后一层使用不同宽度的卷积核(水平宽度分别为 5、4、3、2),从而让每个模型以不同大小的"观察窗口"去预测每个位置上的数字。

每个网络的输出都是矩阵形式:10 行对应 0~9 十个类别,列对应输入上的位置;矩阵中越亮的方块表示该位置属于该类别的得分越高。最后对这些模型做多数投票,选出每个窗口内得分最高的类别。由于并非所有字符组合都是合法的邮政编码,利用输入本身的约束(数字位置与位数)做纠错,可以进一步保证输出是真实可用的邮编。

这里还引入了一个关键技巧:用最短路径算法施加字符顺序约束。已知每个位置可能的字符范围与总位数后,问题转化为在图中求一条从左下角单元格到右上角单元格、只允许"从左到右、从下到上"移动的连续路径,路径代价即产生各字符及字符间转移的最小成本。需要注意:如果相同数字相邻出现,算法必须能区分这是两个重复数字,而不是合并成单个数字。

2. 多尺度人脸检测:从单窗口分类到金字塔推理

人脸检测的基本做法是:收集含人脸与不含人脸的图像数据集,训练一个窗口大小约 30×30 像素的卷积网络判断"有无人脸";检测时把模型滑过整张新图像,输出在对应位置"点亮"表示检测到人脸。但直接这样做会遇到两个典型问题:

  • 假阳性(False Positives):非人脸物体的形态千变万化,训练阶段很难覆盖全部。例如网络若从未见过"手"的样本,可能仅凭肤色就把含手的图像块误判为人脸。
  • 人脸尺寸不一:并非所有人脸都是 30×30 像素,尺寸差异会导致漏检。标准解法是生成同一图像的多尺度版本:以 √2 为缩放因子逐级缩小图像,原尺寸检测器负责 30×30 左右的人脸,缩小后的图像让模型能检测到原图中更小的人脸;反向缩小图像则可检测更大的人脸。这个多尺度过程代价很低:计算量正比于图像边长的平方,图像按 √2 缩小后所需网络的计算量减半,总开销约为 1+1/2+1/4+1/8+… = 2,即多尺度检测仅让总计算成本翻倍。

非极大值抑制(NMS)用于消除重叠框:对每个高得分区域,若其附近检测到多个相邻的框,只保留得分最高的那个,其余剔除,最终得到唯一的最优位置框。

负例挖掘(Negative Mining)用于对抗假阳性:把模型在"已知不含人脸"的输入上误判为人脸的图像块收集起来,组成负例数据集,再用这些负例重新训练检测器。该过程可反复迭代,持续提升模型对假阳性的鲁棒性。

3. 语义分割:为每个像素分类

语义分割的任务是为输入图像的每一个像素赋予一个类别标签。文中给出两个具体落地案例:

案例一:远程自适应机器人视觉(DARPA LAGR 项目,2005–2008)。目标是从图像中区分可行驶区域(绿色)与障碍物(红色),共分 5 类:super green、green、purple(障碍物脚线)、red、super red。训练时从图像中取小块、人工标注是否可通行,训练网络预测块的颜色;系统成熟后应用到整幅图像,为全图逐区域标注。其标注来源是双目立体视觉:机器人携带 4 个相机、组成 2 组双目对,利用立体对相机间的已知距离估计每个像素的 3D 位置(与人类大脑估计距离的方式类似),再拟合地平面,贴近地面的像素标绿、高于地面的标红。立体视觉的工作距离上限约 10 米,而机器人长距离行驶需要更远的感知,这正是引入卷积网络的动机——训练得当的 ConvNet 可检测 50~100 米外的物体(系统曾因此提前"看见"远处的屏障并规划绕行路线)。输入预处理采用尺度不变的距离归一化图像金字塔(类似前文多尺度人脸检测);模型对地平线以上每个像素输出标签。系统的"自适应"体现在:机器人持续获得立体标签,可在线仅重训网络的最后一层(前层在实验室固定),从而适应新环境。当时的限制是算力:机器人约每秒处理 1 帧,无法及时响应突然闯入的行人,因此还配套了基于非神经网络、视距约 2.5 米但反应快速的低成本视觉里程计作为补充。

案例二:城市场景解析(Scene Parsing)。模型为每个像素输出物体类别(建筑、汽车、天空等),架构同样是多尺度。关键在于:把 CNN 某个输出反投影回输入,它对应拉普拉斯金字塔最底层原图上 46×46 的输入窗口——即用 46×46 像素的上下文来决定中心像素的类别。当上下文不足以判定较大物体的类别时,多尺度方案提供更宽视野,步骤如下:将同一图像分别缩小 2 倍与 4 倍;把两张缩放图喂给**同一个 ConvNet(共享权重与卷积核)**得到另外两组 Level 2 特征;将特征上采样到与原图 Level 2 特征相同尺寸;把三组特征堆叠后送入分类器。由此,来自 1/4 缩放图的最大有效上下文达到 184×184 像素(46×4=184)。该方案无需后处理、逐帧运行,即使训练数据量很小(约 2k~3k)也能在标准硬件上取得当时破纪录的结果。

二、Lecture Part B:从 RNN 到 GRU、LSTM、Attention、Seq2Seq 与记忆网络

原文档第二部分(对应详细笔记 docs/en/week06/06-2.md)从"把复杂函数拆成可学习功能模块图"的深度学习视角切入,系统讲解循环网络家族。

1. 循环网络:有环路的计算图与按时间展开

卷积网络的模块图不允许存在环路(模块间至少存在偏序关系,计算输出时输入已就绪);而 RNN 的图存在环路。展开(unroll)环路后,输入是序列 x₁, x₂, …, x_T:t=0 时输入 x(0) 经编码器生成表示 h(0)=Enc(x(0)),交给函数 G 生成隐藏状态 z(0)=G(h₀, z′, w)(初始 z′ 可设 0 或随机初始化);z(0) 一方面送入解码器生成输出,另一方面传给下一时间步。展开后网络中不再有环路,因此可以实施反向传播——这就是BPTT(Backpropagation Through Time,时间反向传播)。展开后的网络具有一个重要特性:不同时间步的编码器、解码器与 G 分别共享同一套权重。不幸的是,朴素形式的 BPTT 在标准 RNN 上效果不佳,根源在于梯度问题。

2. 梯度消失与梯度爆炸:原因与对策

  • 梯度消失:长序列中,梯度在每个时间步都会被权重矩阵(的转置)相乘;若权重矩阵含较小值,梯度范数会指数级缩小。
  • 梯度爆炸:若权重矩阵数值较大、且循环层非线性不饱和,梯度将指数级放大,导致权重更新发散,往往被迫使用极小的学习率。

文中给出的经典例子是判断一段 C 程序语法是否正确:网络需要在隐藏状态里像计数器一样记住未闭合的括号数量,但由于梯度消失,它在长程序中无法保持这类信息。

常用对策("RNN Tricks"):

  • 梯度裁剪(clipping gradients):梯度过大时将其压缩,避免爆炸。
  • 初始化:让权重矩阵初始就保持一定范数,例如正交初始化把权重矩阵初始化为随机正交矩阵,使状态传递更稳定。

3. 乘法模块与 Attention

传统模块只计算输入的加权和;乘法模块则先计算输入的乘积、再对乘积做加权和。设 x∈R^{n×1}、W∈R^{m×n}、U∈R^{m×n×d}、z∈R^{d×1},则权重本身也由权重与输入加权求和得到(w_ij = Σ_k u_ijk·z_k),即"权重也是权重与输入的加权和"——这种"权重由另一个网络计算"的架构被称为超网络(Hypernetwork)。

Attention(注意力)的思想非常直观:w₁x₁ + w₂x₂ 是 x₁、x₂ 的加权和,w₁、w₂ 经 softmax 后介于 0~1 且和为 1;通过调整 w₁、w₂ 的相对大小,输出可以在 x₁、x₂ 或其线性组合之间切换。当输入不止两个向量时,系统选取何种组合由另一个变量 z 决定——注意力机制让神经网络把"注意力"聚焦到特定输入上、忽略其余输入。这一机制在基于 Transformer 的 NLP 系统中日益重要。笔记同时指出:由于 z 与数据无关,此时的权重是"数据无关"的。

4. GRU(门控循环单元)公式逐项解读

GRU(Cho 等,2014)是乘法模块的典型应用,属于带记忆的循环网络(LSTM 是另一例),目标是缓解 RNN 的梯度问题与长期记忆缺失。其更新方程为:

z_t = σ_g(W_z·x_t + U_z·h_{t-1} + b_z) r_t = σ_g(W_r·x_t + U_r·h_{t-1} + b_r) h_t = z_t ⊙ h_{t-1} + (1 − z_t) ⊙ φ_h(W_h·x_t + U_h·(r_t ⊙ h_{t-1}) + b_h)

其中 ⊙ 为逐元素乘法(Hadamard 积),x_t 为输入向量,h_t 为输出向量,z_t 为更新门向量,r_t 为重置门向量,φ_h 为 tanh,W、U、b 为可学习参数。

  • 更新门 z_t:对输入 x_t 与前一状态 h_{t-1} 的两个线性层之和施加 sigmoid,输出 0~1 的系数,决定多少过去信息传递给未来。最终输出 h_t 是 h_{t-1} 与新内容 φ_h(W_h·x_t + U_h·(r_t ⊙ h_{t-1}) + b_h) 经 z_t 的凸组合。系数为 1 时,单元输出就是前一状态的拷贝、忽略当前输入(默认行为);小于 1 时则纳入部分新信息。
  • 重置门 r_t:决定忘记多少过去信息。新记忆内容中若 r_t 系数为 0,则不保留任何过去信息;若此时 z_t 也为 0,系统完全重置,h_t 只看当前输入。

5. LSTM(长短期记忆网络)公式逐项解读

GRU 实际上是更早提出的 LSTM(Hochreiter & Schmidhuber,1997)的简化版。LSTM 通过构造**记忆单元(memory cell)**来保存过去信息,缓解 RNN 的长期记忆丢失。其更新方程为:

f_t = σ_g(W_f·x_t + U_f·h_{t-1} + b_f) i_t = σ_g(W_i·x_t + U_i·h_{t-1} + b_i) o_t = σ_o(W_o·x_t + U_o·h_{t-1} + b_o) c_t = f_t ⊙ c_{t-1} + i_t ⊙ tanh(W_c·x_t + U_c·h_{t-1} + b_c) h_t = o_t ⊙ tanh(c_t)

其中 f_t 为遗忘门激活向量,i_t 为输入/更新门激活向量,o_t 为输出门激活向量,h_t 为隐藏状态(即输出),c_t 为单元状态向量。

  • 遗忘门 f_t:结合当前输入与上一隐藏状态,产生 0~1 的系数决定从上一单元状态 c_{t-1} 保留多少信息。
  • 候选更新:tanh(W_c·x_t + U_c·h_{t-1} + b_c) 计算用于更新单元状态的新候选;输入门 i_t决定施加多少更新。
  • 输出 h_t:基于单元状态 c_t,先过 tanh 再经输出门 o_t过滤。

笔记还指出:虽然 LSTM 在 NLP 中曾广泛使用,但其热度正在下降——语音识别转向时间卷积网络(temporal CNN),NLP 转向 Transformer。

6. Seq2Seq:编码器-解码器与 Attention 的引入

Sequence-to-Sequence 模型(Sutskever,NIPS 2014)是首个性能可媲美经典方法的神经机器翻译系统:编码器与解码器都是多层 LSTM,编码器的时间步数等于待翻译句子的长度,每个时间步是一叠 LSTM(论文中使用 4 层),上一 LSTM 的隐藏状态喂给下一层;最后时间步的最后一层输出代表整句含义的向量,再送入多层 LSTM 解码器逐词生成目标语言文本(每步产出一个词并作为下一步输入)。该架构有两个缺陷:整句含义必须被压缩进编码器与解码器之间的隐藏状态;且 LSTM 实际上难以保留超过约 20 个词的信息。改进方案是Bi-LSTM(双向 LSTM)——两个 LSTM 分别从左到右、从右到左运行,含义编码在两个向量中,可让句长翻倍而不丢失太多信息。

Seq2Seq + Attention(Bahdanau, Cho, Bengio)的思路是:与其让一个巨型网络把整句含义压进单一向量,不如在每个时间步只把注意力聚焦到源语言中语义对应的相关位置。具体地:网络学习为编码器的每个输入隐藏表示打分(衡量其与解码器当前输出的匹配度),分数经 softmax 归一化后作为系数,对编码器各时间步的隐藏状态做加权和。这一机制的妙处在于:计算系数的网络可通过反向传播端到端训练,无需手工设计。注意力彻底改变了神经机器翻译;随后 Google 发表Attention Is All You Need(2017),提出 Transformer——每一层、每一组神经元都在实现注意力。

7. 记忆网络:可寻址的联想记忆

记忆网络源于 Facebook 的研究(Bordes 2014;Sukhbaatar 2015),受大脑启发:**皮层(cortex)**存放长期记忆,**海马体(hippocampus)**负责短期记忆并在睡眠时把信息固化到皮层。机制如下:输入 x(可视为"记忆的地址")与一组"键"向量 k₁, k₂, k₃, … 做点积,经 softmax 得到一组和为 1 的标量;再用这组标量对另一组"值"向量 v₁, v₂, v₃, … 加权求和得到输出:

α_i = k_iᵀ·x c = softmax(α) s = Σ_i c_i·v_i

若某个键 k_i 与 x 精确匹配,其系数将非常接近 1,输出就基本是 v_i——这就是可寻址联想记忆:输入匹配到哪个键,就取回哪个值;softmax 使其可微,从而能通过梯度下降反向传播并更新向量。作者的实验是:把一系列句子编码成向量存入这种记忆,提问时把问题编码为 x 送入记忆并取回值,该值连同网络状态再次用于访问记忆,整个网络端到端训练以生成答案——经过大量训练,模型确实学会了存储故事并回答问题。这个"CPU + 外部可读写记忆"的架构与计算机非常相似,DeepMind 由此提出神经图灵机(Neural Turing Machine);笔记最后点明:比较输入与键、生成系数、产生值——这本质上就是 Transformer 在做的事。

三、Prática:Vanilla RNN 与 LSTM 的架构对比与实验验证

原文档第三部分(对应详细笔记 docs/en/week06/06-3.md)是实操环节:讨论 Vanilla RNN 与 LSTM 的架构并对比两者性能。核心结论是——LSTM 继承了 RNN 的优点,同时通过"记忆单元"长期存储信息,弥补了 RNN 的短板,在实验中显著优于 RNN。

1. Vanilla 网络 vs 循环网络:组合逻辑与时序逻辑

"Vanilla"意为"朴素/普通"。Vanilla 网络(三层:输入 x → 隐藏层 → 输出)如同数字电路中的组合逻辑:当前输出只取决于当前输入。而循环网络的当前输出不仅取决于当前输入,还取决于系统状态——如同数字电路中的时序逻辑(输出还依赖触发器等基本存储单元)。因此两者核心差异是:Vanilla 输出只依赖当前输入,RNN 输出还依赖系统状态。笔记还介绍了一种可视化约定:在神经元之间加入"映射形状"表示张量之间的仿射变换(旋转加扭曲),帮助理解 x → h → 输出的信息流。

2. 四种 RNN 架构类型

  • 向量→序列(vec2seq):输入一个向量(如图像),输出随时间演化的符号序列(如图像的英文描述)。其输出会作为下一次输入的一部分,因此被称为自回归网络(autoregressive network)。实例包括图像描述生成——笔记展示的结果中,有些描述非常精准("A herd of elephants walking across a dry grass field."),有些则明显出错(实际是三只狗却描述为"Two dogs play in the grass."),说明此类网络"时而严重失败、时而表现出色"。
  • 序列→向量(seq2vec):持续喂入符号序列,只在最后给出一个输出。实例是"解释 Python 程序"——输入若干行代码,网络输出程序运行的正确结果,说明可以通过强制最终输出为特定值来训练网络完成此类运算。
  • 序列→向量→序列(seq2vec2seq):曾是语言翻译的标准做法。输入序列先压缩进一个表示"含义"的向量 h,再解卷回另一种语言。对潜在空间做 PCA 可观察到单词按语义聚类(如所有月份聚在一起、表示时间的短语聚在一起),甚至出现经典的语义向量关系:woman − man ≈ queen − king、walking − walked ≈ swimming − swam,说明训练中网络学到了线性可迁移的语义特征。笔记指出该架构在 2018 年前后曾是翻译 SOTA,但如今已被 Transformer 超越。
  • 序列→序列(seq2seq):边输入边输出。实例包括 T9 短信联想、语音转字幕,以及基于科幻小说训练的 RNN-writer 文本自动补全(输入"the rings of Saturn glittered while"→ 续写"two men looked at each other")。

3. BPTT 与语言建模中的 Batchification(截断 BPTT)

RNN 的隐藏表示计算为:

h[t] = g(W_h·[x[t]; h[t−1]] + b_h),其中 W_h = [W_hx, W_hh] h[0] = 0 ŷ[t] = g(W_y·h[t] + b_y)

第一个式子表示对"拼接了上一隐藏配置的输入"做旋转后施加非线性;W_h 可拆成 W_hx 与 W_hh 两个矩阵,等价写法是 W_hx·x[t] + W_hh·h[t−1]。得到最终 y[t] 后,用链式法则把误差反传到前一时间步。

Batchification(分批化):处理符号序列时,把文本按批切分、时间轴垂直保留。例如 batch size = 4 时,序列按列组织;若 BPTT 周期 T=3,第一批输入 x[1:T] 与目标 y[1:T] 分别是 3×4 的符号矩阵,y 恰好是 x 的下一个时间步(a→b→c…,g→h→i…)。训练流程:喂入 x[1]=[a g m s]、强制输出 y[1]=[b h n t],隐藏表示 h[1] 送入下一步辅助预测;处理完第 T 步后,切断 h[T] 与 h[0] 的梯度传播(PyTorch 中即.detach()),避免梯度无限传播——这正是截断 BPTT的实现方式。

4. 梯度问题的深层机制与门控解法

典型 RNN 中,梯度会沿所有可能的箭头传播,这给了梯度很大的消失/爆炸机会:时间 1 处的大梯度(图中亮色)每经过一次循环就大幅缩水,到时间 3 可能已被"杀死"。预防思路是跳跃连接(skip connections):把原网络拆成多个子网络,让部分路径允许梯度通过(图中 ◦)、部分路径阻断传播(图中 −)——这种技术称为门控循环网络(gated recurrent network),LSTM 就是其中一种主流实现。

LSTM 的门控机制可直观理解为"乘法交互":i[t]、f[t]、o[t] 都是取值 0~1 的 sigmoid——乘以 0 即"关闭门",乘以 1 即"打开门"。输出可通过 o[t] 控制(0 时输出归零,1 时输出等于内部表示);记忆可通过遗忘门与输入门控制——f[t]、i[t] 均为 0 时记忆被重置;保持 f[t]=1、内部表示为 0 时记忆得以保留;i[t]=1 写入新值、f[t]=0 遗忘旧值,则完成"写入记忆"。

5. 实验一:序列分类——多对一任务(many-to-one)

实践采用 Hochreiter & Schmidhuber (1997) 的经典序列分类问题,目标复现于仓库 08-seq_classification.ipynb,数据生成器实现在 res/sequential_tasks.py 的TemporalOrderExp6aSequence类。任务设定:序列以B开头、以E(触发符号)结尾,其余位置在 {a, b, c, d} 中随机选取,但 t₁、t₂ 两个位置为 X 或 Y;4 个序列类别 Q、R、S、U 由 X、Y 的时间顺序决定:

X, X → Q X, Y → R Y, X → S Y, Y → U

在DifficultyLevel.HARD下(与 1997 年原论文一致),序列长度 100~110、t₁∈[10,20]、t₂∈[50,60]。源码中定义了 5 个难度档(EASY、NORMAL、MODERATE、HARD、NIGHTMARE),例如 EASY 下长度 7~9、t₁∈[1,3]、t₂∈[4,6],通过get_predefined_generator(difficulty_level, batch_size, seed)直接获取生成器(源码见 res/sequential_tasks.py)。

数据形式:生成器返回二元组——批序列形状 (32, 9, 8)(8 个符号 X/Y/a/b/c/d/B/E 的 one-hot 行,首行全零为 padding),批标签形状 (32, 4)。解码第一条序列如BbXcXcbE对应类别标签 [1,0,0,0] 即 Q。pad_sequences与to_categorical分别负责补零到批内最大长度与 one-hot 编码(源码见 res/sequential_tasks.py)。

模型定义(Notebook 中SimpleRNN与SimpleLSTM):均以torch.nn.RNN/torch.nn.LSTM(batch_first=True)接一个nn.Linear线性输出层;LSTM 版额外实现了get_states_across_time在torch.no_grad()下逐时间步收集 h、c 状态供可视化。训练循环严格遵循五步范式(注释中标注为 ①~⑤):

  1. 前向传播:output = model(data);
  2. 计算损失:loss = criterion(output, target)(取每个序列最后一个时间步的输出output[:, -1, :],目标做argmax转为类别索引交给CrossEntropyLoss);
  3. 清空梯度缓存:optimizer.zero_grad()(防止上一批梯度累积);
  4. 反向传播:loss.backward()计算参数偏导;
  5. 梯度下降一步:optimizer.step()。

实验结果(与课堂笔记一致):难度 EASY、训练 10 epoch 时,RNN 仅约 50% 准确率,而 LSTM 达到 100%;但 LSTM 参数量约为 RNN 的 4 倍且为两层,并非公平对比——训练到 100 epoch 后 RNN 也能达到 100%,只是耗时更长。当提高难度(加长序列)后,RNN 开始失败,而 LSTM 依然能工作。隐藏状态可视化解释了原因:把输入经 tanh 映射后(低于 −2.5 映射到 −1、高于 2.5 映射到 1),可以看到 LSTM 的某个隐藏单元在观察到第一个 X 时被点亮并保持"红色",直到遇到第二个 X 才熄灭——这正是利用长期记忆记录时序标志、从而判定序列类别的机制。

6. 实验二:信号回声——同步多对多任务(many-to-many)

回声 n 步是同步多对多任务的例子,实践于 09-echo_data.ipynb,数据生成器EchoData同样在 res/sequential_tasks.py(默认series_length=40000、batch_size=32、echo_step=3、truncated_length=10)。它用np.random.choice(2)生成 0/1 随机序列,目标y = np.roll(x, echo_step)并把前 echo_step 位置清零(源码见 res/sequential_tasks.py)。例如输入"1 1 0 0 1 0 1 1 0 0 0 0 0 0 0 0 1 1 1 1 …",目标为延迟 3 步的"0 0 0 1 1 0 0 1 0 1 1 0 0 0 0 0 0 0 0 1 …"——模型需要短期工作记忆保存信息(这与语言模型"预测尚未出现的内容"相反)。

关键工程要点:长序列必须先切成小块,喂入新块时把上一块的隐藏状态作为当前内部状态传入(SimpleRNN.forward接受hidden并在批次间共享,源码见 09-echo_data.ipynb);每个 epoch 开始时隐藏状态重置为None,批间调用hidden.detach_()切断跨批梯度(09-echo_data.ipynb)。模型为单层torch.nn.RNN(nonlinearity='relu',4 个隐藏单元)接线性层,损失用BCEWithLogitsLoss、优化器用RMSprop(lr=0.001),训练 5 个 epoch 后测试准确率,并用torch.where(my_out > 0.5)对随机输入做回声预测、与np.roll的期望输出逐位比对(09-echo_data.ipynb)。课堂结论:LSTM 只要容量足够就能长时间保持记忆;RNN 在序列超过一定长度后开始遗忘过去发生的事。

四、小结:本周知识脉络与仓库实践入口

第 6 周的内容可以概括为一条清晰的演进链:CNN 通过空间结构复用解决检测与分割 → 序列任务迫使引入循环与状态 → 朴素 RNN 遭遇梯度消失/爆炸 → 门控机制(GRU/LSTM)用记忆单元与乘法交互化解长期记忆难题 → Attention 与记忆网络进一步把"选择性读取记忆"变成可端到端学习的微分机制 → Seq2Seq/Transformer 将注意力推向现代 NLP 主流。

在本仓库中可按以下路径继续深入学习与复现:

  • 课堂详细笔记:docs/en/week06/06-1.md(CNN 应用)、docs/en/week06/06-2.md(RNN/GRU/LSTM/Attention/Seq2Seq/记忆网络)、docs/en/week06/06-3.md(RNN 与 LSTM 架构及实操);
  • 序列分类实验:08-seq_classification.ipynb(多对一),数据生成器 res/sequential_tasks.py 的TemporalOrderExp6aSequence;
  • 信号回声实验:09-echo_data.ipynb(多对多),数据生成器 res/sequential_tasks.py 的EchoData;
  • 课程环境依赖:environment.yml,涵盖 PyTorch 与 notebook 运行所需的 Python 环境。

两套实验(序列分类与信号回声)恰好对应笔记中 BPTT 与截断.detach()、批间隐藏状态共享、one-hot 编码与 padding 等关键工程细节,是理解"LSTM 为何显著优于 RNN"这一核心结论最直接的代码证据。

  • 示例工程

【免费下载链接】NYU-DLSP20

NYU Deep Learning Spring 2020

项目地址:https://gitcode.com/gh_mirrors/pyt/pytorch-Deep-Learning
点击查看免费下载
上一篇:InsightFace C++ SDK:一套人脸检测代码,从服务器编译到 Android 上线的完整路径
下一篇:PyMC4贝叶斯建模:7个常见问题终极解决方案指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询