序列数据的首选模型,带“记忆”的神经网络

一、什么是循环神经网络(RNN)?

在深度学习领域,循环神经网络(Recurrent Neural Network, RNN) 是一类专门用于处理序列数据的神经网络。

所谓序列数据,是指在不同时间点(或位置)收集到的数据,这类数据的一个关键特点是:后面的数据与前面的数据存在依赖关系。例如:

  • 文本句子:“我爱你” —— 词的顺序决定了语义

  • 时间序列:股票价格、天气变化

  • 语音信号、音乐旋律

传统的全连接网络或卷积网络假设输入之间相互独立,无法有效利用序列中的历史信息。而 RNN 通过引入循环结构,让网络拥有了“记忆”能力,能够记住前面时间步的信息,并用于当前时刻的计算。

RNN 的典型应用场景

  • 自然语言处理(NLP):文本生成、机器翻译、情感分析

  • 时间序列预测:股市预测、气象预报、传感器数据分析

  • 语音识别:将语音信号转换为文字

  • 音乐生成:学习音乐的时序模式并生成新乐曲

二、RNN 的核心原理

2.1 循环结构 vs 展开视角

RNN 的名字来源于它的“循环”连接:每个时间步的隐藏状态(hidden state)会传递给下一个时间步。

下图展示了 RNN 单元在时间上展开后的结构:

  • 输入:当前时刻的输入 xt, 和上一时刻的隐藏状态 ht−1

  • 输出:当前时刻的隐藏状态 ht​ 和预测输出 yt

  • 隐藏状态:相当于网络的“记忆”,携带了截止到当前时刻的历史信息

重要理解:虽然展开后看起来像多个单元,但实际上只有一个 RNN 神经元,它在不同时间步被重复使用。

2.2 数学公式

RNN 神经元内部的计算分为两步:

1)更新隐藏状态

  • xt:当前时刻的输入向量

  • ht−1:上一时刻的隐藏状态

  • Wih,Whh​:权重矩阵

  • bih,bhh:偏置项

  • tanh⁡:激活函数,将输出限制在 [−1,1][−1,1]

2)计算当前时刻输出

  • yt通常是一个向量,表示当前时刻的原始输出

  • 在实际任务(如文本生成)中,yt会再接一个全连接层 + Softmax,得到词汇表上每个词的概率分布,概率最大的词即为当前时刻的预测结果。

2.3 工作流程举例(文本生成)

假设我们想用 RNN 做文本生成:输入“我爱”,预测出“你”。

  1. 初始化隐藏状态 h0​(通常为零向量)

  2. 将“我”转换为词向量,输入 RNN,得到 h1

  3. 将 h1 和“爱”输入 RNN,得到 h2

  4. 将 h2 送入输出层(全连接 + Softmax),得到词汇表上的概率分布

  5. 选择概率最高的词“你”作为输出

三、词嵌入层:让文字变成向量

RNN 无法直接处理文字,需要先将每个词转换为数值向量。词嵌入层(Word Embedding Layer) 就是完成这一转换的关键组件。

3.1 为什么不用 one-hot?

  • one-hot 编码:向量长度等于词表大小,绝大部分位置为 0,高维稀疏且无法表达词之间的语义相似性。

  • 词嵌入:将每个词映射为低维稠密向量(如 128 维),语义相近的词在向量空间中距离更近。例如,“猫”和“狗”的向量会比“猫”和“汽车”更接近。

3.2 词嵌入矩阵

词嵌入层本质上是一个查找表(Lookup Table)

  • 假设词表大小为 V,词向量维度为 D

  • 则词嵌入矩阵的形状为 V×D

  • 每个词对应矩阵中的一行向量

输入一个词的索引,嵌入层直接返回对应的行向量。

3.3 词嵌入层在 RNN 中的作用

  • 输入表示:将离散的单词索引转换为连续的向量,作为 RNN 的输入

  • 降低维度:将高维稀疏的 one-hot 转化为低维稠密向量,减少计算量

  • 捕捉语义:通过训练(或使用预训练的词向量),使得语义相似的词具有相似的向量表示

3.4 PyTorch 中的 nn.Embedding

import torch
import torch.nn as nn

# num_embeddings: 词表大小(词的数量)
# embedding_dim: 每个词映射成的向量维度
embed = nn.Embedding(num_embeddings=10, embedding_dim=4)

# 输入词索引(例如索引为 2 的词)
word_idx = torch.tensor([2])
word_vec = embed(word_idx)  # 输出形状: [1, 4]
print(word_vec)

实际使用中,我们需要先对文本进行分词、去重、构建“词 → 索引”的映射表,然后将文本中的每个词替换为对应的索引,再送入 nn.Embedding 层。

四、PyTorch 中的 RNN 层

PyTorch 提供了封装好的 nn.RNN 类,可以方便地构建循环神经网络层。

4.1 API 介绍

rnn = nn.RNN(input_size, hidden_size, num_layers=1)
  • input_size:输入数据 xtxt​ 的维度,通常等于词向量的维度

  • hidden_size:隐藏状态 htht​ 的维度,也是该层输出的维度

  • num_layers:RNN 堆叠的层数,默认为 1(即单层 RNN)

4.2 输入与输出的形状

output, hn = rnn(x, h0)
输入参数
  • x:形状 (seq_len, batch, input_size)

    • seq_len:序列长度(如句子中的词数)

    • batch:批量大小(一次处理几个句子)

    • input_size:每个输入向量的维度

  • h0:形状 (num_layers, batch, hidden_size)

    • 初始隐藏状态,通常可以初始化为全零

输出结果
  • output:形状 (seq_len, batch, hidden_size)

    • 每个时间步的输出(即每个位置的隐藏状态)

  • hn:形状 (num_layers, batch, hidden_size)

    • 最后一个时间步的隐藏状态(可用于下一批次的初始化)

4.3 完整示例

import torch
import torch.nn as nn

# 定义 RNN 层
rnn = nn.RNN(input_size=128, hidden_size=256, num_layers=1)

# 构造输入数据
# seq_len=5(5个词),batch=32(32个句子),input_size=128(词向量维度)
x = torch.randn(5, 32, 128)

# 初始化隐藏状态(1层,batch=32,hidden_size=256)
h0 = torch.zeros(1, 32, 256)

# 前向传播
output, hn = rnn(x, h0)

print("output 形状:", output.shape)   # torch.Size([5, 32, 256])
print("hn 形状:", hn.shape)           # torch.Size([1, 32, 256])

五、总结

本文介绍了循环神经网络(RNN)的基础知识,主要包括:

知识点 核心内容
RNN 概念 具有循环结构、能处理序列数据、拥有记忆能力的神经网络
隐藏状态 在不同时间步之间传递信息,是 RNN 的“记忆”载体
计算过程 ht=tanh⁡(Wihxt+bih+Whhht−1+bhh)ht​=tanh(Wih​xt​+bih​+Whh​ht−1​+bhh​)
词嵌入层 将离散词索引转换为低维稠密向量,nn.Embedding 实现
PyTorch RNN nn.RNN(input_size, hidden_size),输入输出形状需严格匹配

下一步

RNN 虽然强大,但存在长期依赖问题(梯度消失/爆炸),在实际应用中往往被 LSTM 或 GRU 替代。不过,理解 RNN 的原理是学习更高级循环网络的基础。

本文主要讲解 RNN 的理论基础与基本使用。关于如何使用 RNN 完成实际的文本生成任务(例如周杰伦歌词生成),将在下一篇文章中结合完整案例进行讲解,敬请期待!


希望这篇文章能帮助你快速入门 RNN。如果觉得有用,欢迎点赞、收藏、评论交流!

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐