news 2026/4/3 5:47:24

MindSpore开发之路(十一):构建循环神经网络(RNN):`RNN`, `LSTM`, `Embedding`层

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MindSpore开发之路(十一):构建循环神经网络(RNN):`RNN`, `LSTM`, `Embedding`层

在上一篇文章中,我们探索了卷积神经网络(CNN)如何像“火眼金睛”一样高效地处理图像数据。然而,现实世界中的数据并非都是静态的图片,还有大量按顺序排列的数据,例如一段文字、一首乐曲、或者一段时间内的股票价格。这类数据被称为序列数据

1. RNN是什么

对于序列数据,CNN那种“一视同仁”的局部感知能力就不太够用了,因为序列中的每个元素都可能与它之前的所有元素相关。这时,我们就需要一种新的网络结构——循环神经网络(Recurrent Neural Network, RNN)

RNN就像一个拥有“记忆”的阅读者。当它处理序列中的一个元素时(比如一个单词),它不仅会关注这个单词本身,还会参考它对前面所有单词的“记忆”。这种循环往复、承前启后的机制,使得RNN在自然语言处理(NLP)、时间序列预测等领域取得了巨大成功。

本篇文章将带您走进RNN的世界,重点介绍在MindSpore中构建RNN模型所需的三个核心“零件”。

2. RNN的核心“零件”

处理序列数据,尤其是文本数据时,我们通常需要以下三个关键组件的配合。

2.1 词嵌入层 (nn.Embedding):文字到向量的桥梁

计算机无法直接理解“你好”、“世界”这样的文字。为了让神经网络能够处理文本,我们首先需要将每个字或词转换成一个固定长度的数字向量。这个过程就叫做词嵌入(Word Embedding)

  • 工作原理nn.Embedding层就像一本“密码本”(或字典)。你首先要确定你的词汇表有多大(vocab_size),以及你想用多长的向量来表示一个词(embedding_size)。nn.Embedding层内部会维护一个vocab_size * embedding_size大小的查询表。当你输入一个词的索引(一个整数)时,它就会从表中查出对应的向量作为输出。

  • 关键参数

    • vocab_size(int): 词汇表的大小。例如,如果你的词典里有1000个不同的词,这个值就是1000。
    • embedding_size(int): 用来表示一个词的向量的维度。
  • 代码示例

importmindsporefrommindsporeimportnn,Tensorimportnumpyasnp# 假设我们的词汇表大小为1000,每个词用100维的向量表示vocab_size=1000embedding_size=100# 定义一个Embedding层embedding_layer=nn.Embedding(vocab_size,embedding_size)# 假设我们有一句话,它包含4个词,其在词典中的索引分别是 1, 5, 99, 0# 输入的shape通常是 (batch_size, sequence_length)input_indices=Tensor([[1,5,99,0]],mindspore.int32)# 将索引输入Embedding层output_vectors=embedding_layer(input_indices)print("输入索引的尺寸:",input_indices.shape)print("输出词向量的尺寸:",output_vectors.shape)# (1, 4, 100)

2.2 循环神经网络层 (nn.RNN):最初的“记忆”单元

nn.RNN是MindSpore中基础的循环神经网络层。

  • 工作原理:RNN的核心在于其内部的“循环”。对于一个长度为L的序列,RNN层会按时间步从t=0t=L-1依次处理每个元素的向量。在每个时间步t,它会接收两个输入:

    1. 当前时间步的输入向量x_t
    2. 上一个时间步的隐藏状态h_{t-1}(可以理解为“短期记忆”)。

    它将这两个输入融合,计算出当前时间步的输出output_t和新的隐藏状态h_t,然后将h_t传递给下一个时间步。这个h_t就构成了RNN的“记忆”。

  • 关键参数

    • input_size(int): 输入向量的维度(通常等于embedding_size)。
    • hidden_size(int): 隐藏状态向量的维度。
    • batch_first(bool): 如果为True,则输入和输出Tensor的维度顺序为(batch, seq_len, input_size),这通常更直观。
  • 代码示例

# 承接上例,词向量维度为100,我们设定RNN的隐藏层维度为32input_size=100hidden_size=32seq_len=4# 序列长度batch_size=1# 批量大小# 定义一个RNN层# batch_first=True 让输入的第一维是batch_sizernn_layer=nn.RNN(input_size,hidden_size,batch_first=True)# 将Embedding层的输出作为RNN的输入# output_vectors 的 shape 是 (1, 4, 100)output,hidden_state=rnn_layer(output_vectors)print("RNN输出(所有时间步)的尺寸:",output.shape)# (1, 4, 32)print("RNN最后一个时间步的隐藏状态尺寸:",hidden_state.shape)# (1, 1, 32)

局限性:基础的RNN存在一个著名的问题——梯度消失/爆炸。当序列很长时,它很难学习到序列开头的“长期依赖”信息,就像一个人记性不好,读到后面就忘了前面讲了什么。

2.3 长短期记忆网络层 (nn.LSTM):更强大的“记忆”单元

为了解决RNN的“记性差”的问题,研究者们设计了长短期记忆网络(Long Short-Term Memory, LSTM)。LSTM是RNN的一种变体,也是目前应用最广泛的循环神经网络之一。

  • 工作原理:LSTM的核心在于其内部精巧的“门控机制”。相比于RNN简单的隐藏状态,LSTM引入了一个细胞状态(Cell State),可以看作是“长期记忆”。它还设计了三个“门”来控制信息的流动:

    1. 遗忘门(Forget Gate):决定从长期记忆中丢弃哪些信息。
    2. 输入门(Input Gate):决定将哪些新的信息存入长期记忆。
    3. 输出门(Output Gate):决定从长期记忆中输出哪些信息作为当前时间步的隐藏状态。

    通过这套机制,LSTM能够有选择地记忆和遗忘,从而有效地捕捉长距离依赖关系。

  • 关键参数:与nn.RNN基本相同。

  • 代码示例

# 定义一个LSTM层,参数与RNN类似lstm_layer=nn.LSTM(input_size,hidden_size,batch_first=True)# 将同样的词向量输入LSTM层# LSTM的输出包含 output, (h_n, c_n)output,(h_n,c_n)=lstm_layer(output_vectors)print("LSTM输出(所有时间步)的尺寸:",output.shape)# (1, 4, 32)print("LSTM最后一个时间步的隐藏状态尺寸:",h_n.shape)# (1, 1, 32)print("LSTM最后一个时间步的细胞状态尺寸:",c_n.shape)# (1, 1, 32)

3. 组装一个简单的序列处理模型

现在,我们将这三个“零件”组装起来,构建一个可用于文本分类等任务的基础模型结构。

importmindsporefrommindsporeimportnnclassSimpleSentimentClassifier(nn.Cell):def__init__(self,vocab_size,embedding_size,hidden_size,num_classes):super(SimpleSentimentClassifier,self).__init__()# 1. Embedding层self.embedding=nn.Embedding(vocab_size,embedding_size)# 2. LSTM层self.lstm=nn.LSTM(embedding_size,hidden_size,batch_first=True)# 3. 全连接层 (分类器)self.fc=nn.Dense(hidden_size,num_classes)defconstruct(self,x):# x 的 shape: (batch_size, seq_len)# 1. 经过Embedding层# embedded 的 shape: (batch_size, seq_len, embedding_size)embedded=self.embedding(x)# 2. 经过LSTM层# lstm_out shape: (batch_size, seq_len, hidden_size)# h_n shape: (1, batch_size, hidden_size)lstm_out,(h_n,c_n)=self.lstm(embedded)# 3. 我们通常取最后一个时间步的输出来代表整句话的语义# last_output shape: (batch_size, hidden_size)last_output=lstm_out[:,-1,:]# 4. 经过全连接层得到分类结果# logits shape: (batch_size, num_classes)logits=self.fc(last_output)returnlogits# 实例化网络model=SimpleSentimentClassifier(vocab_size=1000,embedding_size=100,hidden_size=32,num_classes=2)# 假设是二分类(如情感积极/消极)print(model)

4. 总结

在本篇文章中,我们学习了处理序列数据的利器——循环神经网络,并掌握了其在MindSpore中的三个核心组件:

  • nn.Embedding:将离散的词符转换为密集的向量,是处理文本数据的第一步。
  • nn.RNN:基础的循环网络层,通过传递隐藏状态来维持“短期记忆”。
  • nn.LSTM:RNN的强大变体,通过精巧的门控机制实现了“长短期记忆”,能更好地捕捉序列中的长距离依赖。

通过组合这三个组件,我们构建了一个简单的序列处理模型,为后续进行文本分类、机器翻译等NLP实战任务奠定了基础。

在下一篇文章中,我们将学习训练过程中的得力助手——回调函数(Callbacks),敬请期待!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/31 15:26:28

OpenNebula企业级云平台完整使用指南:从入门到实战

OpenNebula企业级云平台完整使用指南:从入门到实战 【免费下载链接】one The open source Cloud & Edge Computing Platform bringing real freedom to your Enterprise Cloud 🚀 项目地址: https://gitcode.com/gh_mirrors/on/one 还在为复杂…

作者头像 李华
网站建设 2026/3/24 3:00:16

如何快速配置macOS网络存储:完整iSCSI连接指南

如何快速配置macOS网络存储:完整iSCSI连接指南 【免费下载链接】iSCSIInitiator iSCSI Initiator for macOS 项目地址: https://gitcode.com/gh_mirrors/is/iSCSIInitiator macOS iSCSI Initiator是一款专为苹果电脑设计的开源工具,能够让Mac用户…

作者头像 李华
网站建设 2026/4/2 18:41:26

Dify可视化编辑器支持拖拽式节点连接

Dify可视化编辑器支持拖拽式节点连接 在企业加速落地AI能力的今天,一个现实问题摆在面前:如何让非技术背景的产品经理、运营人员也能参与AI应用的设计?如何将复杂的RAG流程、Agent逻辑以直观方式呈现并快速迭代?传统基于代码的开发…

作者头像 李华
网站建设 2026/3/27 8:23:21

Dify镜像支持多模型接入,灵活调配token资源

Dify镜像支持多模型接入,灵活调配token资源 在企业加速拥抱AI的今天,一个现实问题摆在面前:如何快速、安全、低成本地将大语言模型(LLM)集成到实际业务中?直接调用API看似简单,但面对复杂的提示…

作者头像 李华
网站建设 2026/3/30 5:36:14

企业ICT网络系统评估规划要点

数字化转型的基石在数字化浪潮席卷全球的今天,企业网络系统的重要性日益凸显。企业CIT标准化网络系统 的评估规划,不仅是企业数字化转型的基石,更是确保信息安全、提升运营效率的关键。本 文将从评估规划的角度,深入探讨企业网络系…

作者头像 李华
网站建设 2026/3/24 11:56:37

深度解析:基于预训练ResNet-50的U-Net图像分割架构

深度解析:基于预训练ResNet-50的U-Net图像分割架构 【免费下载链接】pytorch-unet-resnet-50-encoder 项目地址: https://gitcode.com/gh_mirrors/py/pytorch-unet-resnet-50-encoder 在当今计算机视觉领域,图像分割技术正以前所未有的速度发展。…

作者头像 李华