前面我们学习了多层感知机和卷积神经网络。多层感知机适合处理表格特征卷积神经网络适合处理图片。所谓“表格特征”就是每个样本能用一行固定长度的字段来描述像 Excel 里的一行数据。比如房价预测里的面积、楼层、朝向、房龄、地段评分或风控里的年龄、收入、负债比例、信用评分。这些字段没有先后顺序拼成一个固定长度的向量就可以直接输入 MLP。它们有一个共同特点通常把每个样本当成相对独立的对象来看。例如一张猫图和一张狗图顺序调换后不影响分类一条房价数据和另一条房价数据通常可以分别预测一张手写数字图片不需要知道上一张图片是什么。但现实里还有很多数据不能打乱顺序。顺序一变意思就变了。股票价格今天的走势会影响明天的判断。语音信号前一个音节会影响后一个音节的理解。文本句子“我喜欢你”和“你喜欢我”字一样顺序不同意思不同。天气记录连续几天的温度变化比某一天单独的温度更有信息。这些数据有一个共同名字序列数据Sequence Data。这一篇我们先不急着讲 RNN而是先搞懂两件事序列数据到底特殊在哪里文本这种人类语言怎样变成神经网络能处理的数字一、什么是序列数据序列数据就是一串按顺序排列的数据。这个顺序通常代表时间、位置或逻辑关系。我们常用下标表示它x1, x2, x3, ..., xt其中xt表示第t个时间步的数据。举几个例子场景一个时间步可能是什么股票预测某一天的价格天气预测某一天的温度、湿度语音识别某一小段声音信号文本生成一个字、一个词或一个 token序列数据最重要的特点是当前数据往往和过去的数据有关。比如你看到一句话我今天晚上想吃你会自然猜后面可能是“火锅”“面条”“烧烤”而不太可能是“显卡”。原因不是“吃”这个字单独决定的而是前面整句话提供了上下文。二、序列预测用过去猜未来序列模型常见任务是根据前面的内容预测后面的内容。比如已知x1, x2, x3, ..., xt 预测x(t1)这类模型叫自回归模型Autoregressive Model。名字听起来很学术其实意思很简单用自己过去的历史预测自己的下一步。股票预测、天气预测、文本续写都属于这个思路。1. 最直接的方法看固定长度的历史假设我们要预测明天的温度可以只看过去 3 天输入前3天温度 输出明天温度如果写成机器学习任务它就像普通表格数据前3天前2天前1天明天2021232421232422这时用多层感知机也能做因为我们把过去几天当作几个普通特征输入了。2. 问题历史到底看多长只看过去 3 天可能不够。文本尤其明显。比如虽然这本书前面铺垫了很多复杂人物关系但最后真正改变主角命运的人是想预测下一个词可能要理解很远之前的人名和情节。固定只看前 3 个词、前 5 个词就不够用了。于是我们需要一种模型它能按顺序读取数据并且把读过的信息压缩成某种“记忆”。这就是 RNN 的动机。不过在进入 RNN 之前我们先处理一个更基础的问题文字怎么喂给神经网络三、机器不认识文字只认识数字神经网络本质上做的是矩阵运算。它不能直接理解深度学习很好玩我们必须把文本变成数字。这个过程叫文本预处理。一条基本流水线通常包括读取文本 - 词元化 - 建立词表 - 转成数字序列 - 切成小批量下面一步一步看。四、词元化把句子切成小块词元Token是文本被切分后的基本单位。词元化就是把一段文本拆成一个个 token。常见切法有两种。1. 按词切英文可以按单词切deep learning is fun切成[deep, learning, is, fun]优点是语义比较完整缺点是词表会很大而且没见过的新词不好处理。2. 按字符切中文入门教学里经常按字切深度学习很好玩切成[深, 度, 学, 习, 很, 好, 玩]优点是简单、词表小缺点是单个字的信息有限需要模型自己从上下文里组合含义。小白学习 RNN 时推荐先从字符级文本开始因为它更容易实现。五、建立词表给每个 token 一个编号切成 token 后机器还是不认识。我们要给每个 token 分配一个整数编号这个表叫词表Vocabulary。比如unk - 0 深 - 1 度 - 2 学 - 3 习 - 4unk表示未知 token。遇到词表里没有的内容就统一映射到它。下面是一份简化版词表代码classVocab:def__init__(self,tokens):# 初始化“编号 - token”的列表先放一个未知词占位self.idx_to_token[unk]# 初始化“token - 编号”的字典未知词的编号固定为 0self.token_to_idx{unk:0}# 去重并排序保证编号分配稳定可复现fortokeninsorted(set(tokens)):# 把 token 追加到列表末尾self.idx_to_token.append(token)# token 的编号就是它在列表中的位置self.token_to_idx[token]len(self.idx_to_token)-1def__getitem__(self,tokens):# 如果输入的是单个 token直接返回编号ifnotisinstance(tokens,(list,tuple)):# get 的默认值 0 表示词表里没有时返回 unkreturnself.token_to_idx.get(tokens,0)# 如果输入是一组 token就递归地转换成编号列表return[self.__getitem__(token)fortokenintokens]defto_tokens(self,indices):# 如果输入的是单个编号直接返回对应 tokenifnotisinstance(indices,(list,tuple)):returnself.idx_to_token[indices]# 如果输入是一组编号就逐个转回 token 列表return[self.idx_to_token[index]forindexinindices]有了词表文本就可以转换成数字序列[深, 度, 学, 习] - [1, 2, 3, 4]注意这些数字只是编号不代表大小关系。编号 4 的“习”并不比编号 1 的“深”更大、更重要。这个细节很重要下一篇和第三篇会继续用到。六、把长序列切成训练样本一本书可能有几十万字我们不能一次性全部塞进模型。训练时通常会把长文本切成很多小片段。比如原始序列是[1, 2, 3, 4, 5, 6, 7, 8]如果每次看 4 个 token可以构造输入 [1, 2, 3, 4] 标签 [2, 3, 4, 5]这是什么意思模型读到1时希望预测2读到2时希望预测3读到3时希望预测4。也就是每个位置都在练习“根据当前和过去预测下一个 token”。生活化例子想象你在听一句话“我今天晚上想吃”。你听到“我”时会猜下一词可能是“今天”。你听到“我 今天”时会猜下一词可能是“晚上”。你听到“我 今天 晚上”时会猜下一词可能是“想吃”。这就是“输入序列”和“标签序列”错开一位的意义每个位置都在训练“下一步该接什么”。1. 随机采样随机采样就是从长文本中随机抽取片段。优点打乱程度高训练样本更随机。缺点相邻批次之间可能没有连续关系隐状态不方便延续。这里的“隐状态”可以理解为 RNN 的“短期记忆本”它保存了上一段序列的上下文信息。如果下一批数据是随机切出来的、和上一批不相邻那么继续沿用上一批的隐状态就会把“错误的上下文”带进来反而干扰学习所以就不方便延续。2. 顺序分区顺序分区就是按原文顺序切片。优点更符合文本原本顺序适合让 RNN 的状态连续传递。缺点实现时要更注意批量之间的状态管理。入门阶段你只要知道随机采样更像打散练习题顺序分区更像按原文一路读下去。七、小结这一篇我们为 RNN 打了地基你需要记住序列数据的关键是“顺序有意义”不能随便打乱。自回归模型就是用过去预测未来。文本必须先经过词元化和词表映射才能变成神经网络能处理的数字。token 的整数编号只是身份标记不代表数值大小。训练语言模型时常把长文本切成“输入序列”和“向后错一位的标签序列”。如果用一句话收尾RNN 要解决的问题是让模型一边读序列一边记住前面发生过什么。下一篇我们正式认识 RNN 的核心隐状态。它就像模型随身携带的一本“短期记忆本”让机器不再只看当前 token而能结合前文做判断。注文档部分内容参考《动手学深度学习》《动手学深度学习》循环神经网络https://zh.d2l.ai/chapter_recurrent-neural-networks/index.html
循环神经网络(一):从预测股票到读懂文字,踏入序列数据的新世界
发布时间:2026/6/1 21:07:40
前面我们学习了多层感知机和卷积神经网络。多层感知机适合处理表格特征卷积神经网络适合处理图片。所谓“表格特征”就是每个样本能用一行固定长度的字段来描述像 Excel 里的一行数据。比如房价预测里的面积、楼层、朝向、房龄、地段评分或风控里的年龄、收入、负债比例、信用评分。这些字段没有先后顺序拼成一个固定长度的向量就可以直接输入 MLP。它们有一个共同特点通常把每个样本当成相对独立的对象来看。例如一张猫图和一张狗图顺序调换后不影响分类一条房价数据和另一条房价数据通常可以分别预测一张手写数字图片不需要知道上一张图片是什么。但现实里还有很多数据不能打乱顺序。顺序一变意思就变了。股票价格今天的走势会影响明天的判断。语音信号前一个音节会影响后一个音节的理解。文本句子“我喜欢你”和“你喜欢我”字一样顺序不同意思不同。天气记录连续几天的温度变化比某一天单独的温度更有信息。这些数据有一个共同名字序列数据Sequence Data。这一篇我们先不急着讲 RNN而是先搞懂两件事序列数据到底特殊在哪里文本这种人类语言怎样变成神经网络能处理的数字一、什么是序列数据序列数据就是一串按顺序排列的数据。这个顺序通常代表时间、位置或逻辑关系。我们常用下标表示它x1, x2, x3, ..., xt其中xt表示第t个时间步的数据。举几个例子场景一个时间步可能是什么股票预测某一天的价格天气预测某一天的温度、湿度语音识别某一小段声音信号文本生成一个字、一个词或一个 token序列数据最重要的特点是当前数据往往和过去的数据有关。比如你看到一句话我今天晚上想吃你会自然猜后面可能是“火锅”“面条”“烧烤”而不太可能是“显卡”。原因不是“吃”这个字单独决定的而是前面整句话提供了上下文。二、序列预测用过去猜未来序列模型常见任务是根据前面的内容预测后面的内容。比如已知x1, x2, x3, ..., xt 预测x(t1)这类模型叫自回归模型Autoregressive Model。名字听起来很学术其实意思很简单用自己过去的历史预测自己的下一步。股票预测、天气预测、文本续写都属于这个思路。1. 最直接的方法看固定长度的历史假设我们要预测明天的温度可以只看过去 3 天输入前3天温度 输出明天温度如果写成机器学习任务它就像普通表格数据前3天前2天前1天明天2021232421232422这时用多层感知机也能做因为我们把过去几天当作几个普通特征输入了。2. 问题历史到底看多长只看过去 3 天可能不够。文本尤其明显。比如虽然这本书前面铺垫了很多复杂人物关系但最后真正改变主角命运的人是想预测下一个词可能要理解很远之前的人名和情节。固定只看前 3 个词、前 5 个词就不够用了。于是我们需要一种模型它能按顺序读取数据并且把读过的信息压缩成某种“记忆”。这就是 RNN 的动机。不过在进入 RNN 之前我们先处理一个更基础的问题文字怎么喂给神经网络三、机器不认识文字只认识数字神经网络本质上做的是矩阵运算。它不能直接理解深度学习很好玩我们必须把文本变成数字。这个过程叫文本预处理。一条基本流水线通常包括读取文本 - 词元化 - 建立词表 - 转成数字序列 - 切成小批量下面一步一步看。四、词元化把句子切成小块词元Token是文本被切分后的基本单位。词元化就是把一段文本拆成一个个 token。常见切法有两种。1. 按词切英文可以按单词切deep learning is fun切成[deep, learning, is, fun]优点是语义比较完整缺点是词表会很大而且没见过的新词不好处理。2. 按字符切中文入门教学里经常按字切深度学习很好玩切成[深, 度, 学, 习, 很, 好, 玩]优点是简单、词表小缺点是单个字的信息有限需要模型自己从上下文里组合含义。小白学习 RNN 时推荐先从字符级文本开始因为它更容易实现。五、建立词表给每个 token 一个编号切成 token 后机器还是不认识。我们要给每个 token 分配一个整数编号这个表叫词表Vocabulary。比如unk - 0 深 - 1 度 - 2 学 - 3 习 - 4unk表示未知 token。遇到词表里没有的内容就统一映射到它。下面是一份简化版词表代码classVocab:def__init__(self,tokens):# 初始化“编号 - token”的列表先放一个未知词占位self.idx_to_token[unk]# 初始化“token - 编号”的字典未知词的编号固定为 0self.token_to_idx{unk:0}# 去重并排序保证编号分配稳定可复现fortokeninsorted(set(tokens)):# 把 token 追加到列表末尾self.idx_to_token.append(token)# token 的编号就是它在列表中的位置self.token_to_idx[token]len(self.idx_to_token)-1def__getitem__(self,tokens):# 如果输入的是单个 token直接返回编号ifnotisinstance(tokens,(list,tuple)):# get 的默认值 0 表示词表里没有时返回 unkreturnself.token_to_idx.get(tokens,0)# 如果输入是一组 token就递归地转换成编号列表return[self.__getitem__(token)fortokenintokens]defto_tokens(self,indices):# 如果输入的是单个编号直接返回对应 tokenifnotisinstance(indices,(list,tuple)):returnself.idx_to_token[indices]# 如果输入是一组编号就逐个转回 token 列表return[self.idx_to_token[index]forindexinindices]有了词表文本就可以转换成数字序列[深, 度, 学, 习] - [1, 2, 3, 4]注意这些数字只是编号不代表大小关系。编号 4 的“习”并不比编号 1 的“深”更大、更重要。这个细节很重要下一篇和第三篇会继续用到。六、把长序列切成训练样本一本书可能有几十万字我们不能一次性全部塞进模型。训练时通常会把长文本切成很多小片段。比如原始序列是[1, 2, 3, 4, 5, 6, 7, 8]如果每次看 4 个 token可以构造输入 [1, 2, 3, 4] 标签 [2, 3, 4, 5]这是什么意思模型读到1时希望预测2读到2时希望预测3读到3时希望预测4。也就是每个位置都在练习“根据当前和过去预测下一个 token”。生活化例子想象你在听一句话“我今天晚上想吃”。你听到“我”时会猜下一词可能是“今天”。你听到“我 今天”时会猜下一词可能是“晚上”。你听到“我 今天 晚上”时会猜下一词可能是“想吃”。这就是“输入序列”和“标签序列”错开一位的意义每个位置都在训练“下一步该接什么”。1. 随机采样随机采样就是从长文本中随机抽取片段。优点打乱程度高训练样本更随机。缺点相邻批次之间可能没有连续关系隐状态不方便延续。这里的“隐状态”可以理解为 RNN 的“短期记忆本”它保存了上一段序列的上下文信息。如果下一批数据是随机切出来的、和上一批不相邻那么继续沿用上一批的隐状态就会把“错误的上下文”带进来反而干扰学习所以就不方便延续。2. 顺序分区顺序分区就是按原文顺序切片。优点更符合文本原本顺序适合让 RNN 的状态连续传递。缺点实现时要更注意批量之间的状态管理。入门阶段你只要知道随机采样更像打散练习题顺序分区更像按原文一路读下去。七、小结这一篇我们为 RNN 打了地基你需要记住序列数据的关键是“顺序有意义”不能随便打乱。自回归模型就是用过去预测未来。文本必须先经过词元化和词表映射才能变成神经网络能处理的数字。token 的整数编号只是身份标记不代表数值大小。训练语言模型时常把长文本切成“输入序列”和“向后错一位的标签序列”。如果用一句话收尾RNN 要解决的问题是让模型一边读序列一边记住前面发生过什么。下一篇我们正式认识 RNN 的核心隐状态。它就像模型随身携带的一本“短期记忆本”让机器不再只看当前 token而能结合前文做判断。注文档部分内容参考《动手学深度学习》《动手学深度学习》循环神经网络https://zh.d2l.ai/chapter_recurrent-neural-networks/index.html