序列模型
处理序列数据需要统计工具和新的深度神经网络架构
链式法则:

(正向分解)

(反向分解)
我们不直接依赖完整的历史 (x1,...,xt−1) ,而是依赖一个对历史的压缩表示 f(*)
原因:输入维度固定,历史太长计算不可行
++++两种实现方式:++++

++++马尔可夫模型:++++
假设:未来只依赖于最近的历史,而非全部历史。用截断的历史 (xt−1,...,xt−τ) 代替完整历史 (xt−1,...,x1)
一阶马尔可夫模型:

可以沿着马尔可夫链精确计算各种概率:

++++潜变量模型:++++
引入一个潜变量ht来表示过去的信息(RNN)

尝试训练:
以简单的正弦函数加上一些噪音作为数据

将这个序列转换为模型的特征-标签(feature-label)对

我们使用一个相当简单的架构训练模型: 一个拥有两个全连接层的多层感知机,ReLU激活函数和平方损失。

训练模型:

文本预处理
(1)将文本作为字符串加载到内存中。
(2)将字符串拆分为词元(如单词和字符)。
(3)建立一个词表,将拆分的词元映射到数字索引。
(4)将文本转换为数字索引序列,方便模型操作。
将数据集读取到由多条文本行组成的列表中,其中每条文本行都是一个字符串。 为简单起见,我们在这里++++忽略了标点符号和字母大写++++。

Token化得到词元

++++词元的类型是字符串,而模型需要的输入是数字,因此这种类型不方便模型使用++++
构建一个字典,通常也叫做++++词表(vocabulary)++++, 用来将字符串类型的词元映射到从开始的数字索引中

创建一个Vocab类

省略为空的东西

按出现频率排序

unknow的token标号记为0

出现次数小于要求的去掉

其余的一些功能性函数

统计词元的频率
语言模型
将文本看作由词元(token,如字或词)组成的序列x1,x2,...,xT。
++++核心任务:估计整个序列的联合概率 P(x1,x2,...,xT) 。++++
语言模型的目标是估计序列的联合概率 P(x1,...,xT) 。根据概率的链式法则,可将其拆解为

因此,训练语言模型本质上就是++++学习这些条件概率参数。++++
朴素估计:++++基于语料库的词频统计++++ ++++(作为条件概率)++++
序列的联合概率 = 各条件概率的连乘,而每个条件概率都通过++++"出现次数 ÷ 前缀出现次数"++++从语料库中统计得到。

困境:随着序列长度增加,特定词组合的出现次数急剧下降。许多合理但罕见的三元组甚至二元组在语料库中++++计数为零,导致概率估计失效++++。
解决方案:++++拉普拉斯平滑++++
在所有计数中加入一个小的平滑常量 ϵ ,避免零概率:


用++++马尔可夫假设++++简化语言模型,通过限制历史依赖长度来定义 n-gram 模型。

好处:可以处理比较长的序列
1.词频分布遵循齐普夫定律
语言中的词频分布是高度不均衡的:极少数词占据了绝大部分出现次数,而绝大多数词处于"长尾"区域,出现次数极少。
- n-gram 同样面临稀疏性问题
将统计从一元词扩展到二元组、三元组后,发现:
二元语法:最频繁的词对大多由停用词组成(如 of the、in the),信息量低。
三元语法:开始出现有意义的短语(如 the time traveller、the time machine),但频率已大幅下降(最高仅 59 次)。
n-gram 也服从齐普夫定律,只是指数 α 更小,衰减相对平缓。
这说明:无论 n 取多少,基于频率统计的方法都会遇到++++"大量合理组合从未在语料中出现"的数据稀疏问题。++++
自然语言统计揭示了词频的++++幂律分布和n-gram 的稀疏性++++ ,证明了传统"数频率+平滑"的方法走不通,因此必须++++转向基于深度学习的语言模型++++。
语言模型和数据集:
训练语言模型时,需要通过++++随机偏移量++++ 将长文本切分为等长子序列,以兼顾数据的++++覆盖性和随机性++++ ,为神经网络提供高质量的小批量训练数据。++++打破局部相关性++++
随机采样:

corpus:展平后的词元序列(一维列表)。
batch_size:每个小批量包含的子序列样本数。
num_steps:每个子序列的时间步长度(即每个样本包含多少个词元)。

从 0, num_steps-1 范围内随机选一个整数作为起始偏移,截断语料库开头部分。这样每次调用时,子序列的划分边界都不同,增加了数据的随机性和覆盖范围。

计算可以划分出的子序列总数

生成所有子序列的起始索引

随机打乱起始索引的顺序。
这样相邻的小批量中的子序列在原始文本中可能相距很远,打破了原文的顺序依赖,使训练更具泛化性。

内部辅助函数,返回pos位置的切片

计算能切多少batch

顺序分区:
在迭代过程中,除了对原始序列可以随机抽样外, 我们还可以保证两个相邻的小批量中的子序列在原始序列上也是相邻的。
