循环神经网络
序列模型
实际中很多数据是有时序结构的。例如,电影的评价随时间变化而变化:拿奖后评分上升,直到奖项被忘记;看了很多好电影后,人们的期望变高;季节性:贺岁片、暑期档等等。其他的,音乐、语言、文本、和视频等等都是连续的。处理序列数据需要统计工具和新的深度神经网络架构。举例说明,我们预测 t 时刻的股价,需要 1 到 t-1 时间的股价数据,并且这个数据随着 t 的增加而不断增大,那我们该如何处理呢?
在时间 t 观察 x,那么得到 T 个不独立的随机变量:p(x)=p(x1)⋅p(x2∣x1)⋅p(x3∣x1,x2)⋅…p(xT∣x1,…xT−1)
我们有两个策略的近似方法解决:策略1:假设当前当前数据只跟 τ 个过去数据点相关,这是马尔可夫假设。p(xt∣x1,…xt−1)=p(xt∣xt−τ,…xt−1)=p(xt∣f(xt−τ,…xt−1)).策略2:潜变量模型。引入潜变量 ht 来表示过去信息 ht=f(x1,…xt−1),这样的话 xt=p(xt∣ht),使用 ht=g(ht−1,xt−1) 更新我们的模型。
自回归模型使用自身过去数据来预测未来,例如我们的马尔可夫假设就是使用历史数据预测未来。马尔科夫模型假设当前只跟最近少数数据相关,从而简化模型。潜变量模型使用潜变量来概括历史信息,而不是像马尔可夫假设仅与附近相邻的 τ 个数据相关。
文本预处理
一篇文章可以被简单地看作是一串单词序列,甚至是一串字符序列。我们将解析文本的常见预处理步骤。这些步骤通常包括:
- 将文本作为字符串加载到内存中。
- 将字符串拆分为词元(如单词和字符)。
- 建立一个词表。将拆分的词元映射到数字索引。
- 将文本转换为数字索引序列,方便模型操作。
在 github 中没少费时间研究李老师的数据预处理的代码,这里 text_preprocessing 链接一下代码部分,然后简单总结一下代码都干了啥。
我们在代码处理的过程中,并不是真正的把词元传入作为输入,而是传入数字。数字和词元有着一一对应的关系。而且,并不是所有的词元都需要我们进行处理,有的词元出现的频率很高,但它们往往是停用词,并没有实在的意义。有的词元出现的频率超低,也没有处理的意义。
所以我们在做词元和数字对应转换的过程中需要统计词元出现的频率。在 text_preprocessing 代码中是使用 count_corpus 函数计算所有 tokens 和相应出现的次数,也就是一个字典对象。随后,我们创建了一个类 Vocab,负责主要两个事:一个是维护好类的两个对象。另外一个是在类的调用时要返回这两个对象数据。两个对象是什么?一个是字典。key = token,value 是代码处理过程中其对应的数字值。第二个是根据 value 取得相应的 token。我这里说的都是大白话,但也是看了将近一个半小时的代码才看懂的结果,形式化的总结可以见上四条。
语言模型
给定文本序列 x1…xp,语言模型的目标是估计联合概率 p(x1,…,xp)。语言模型的应用有:
- 做预训练模型 (eg BERT,GPT-3)
- 生成本文,给定前面几个词,不断的使用 xt∼p(xt∣x1,…,xt−1) 来生成后续文本
- 判断多个序列中哪个更常见,e.g."to recognize speech”vs“to wreck a nice beach
我们将马尔可夫模型应用于语言建模:N-gram.涉及一个、两个和三个变量的概率公式分别被称为 “一元语法”(unigram)、“二元语法”(bigram)和“三元语法”(trigram)模型。
P(x1,x2,x3,x4)=P(x1)P(x2)P(x3)P(x4)P(x1,x2,x3,x4)=P(x1)P(x2∣x1)P(x3∣x2)P(x4∣x3)P(x1,x2,x3,x4)=P(x1)P(x2∣x1)P(x3∣x1,x2)P(x4∣x2,x3)