深度学习第五课 序列模型

序列模型

week1 循环序列模型

1.1 为什么选择序列模型

image-20240713151724354在进行语音识别时,给定了一个输入音频片段 X ,并要求输出对应的文字记录 Y。这个例子里输入和输出数据都是序列模型,因为 X 是一个按时播放的音频片段,输出 Y 是一系列单词。所以之后将要学到的一些序列模型,如循环神经网络等等在语音识别方面是非常有用的。

这些问题都可以被称作使用标签数据 (X,Y) 作为训练集的监督学习。但从这一系列例子中你可以看出序列问题有很多不同类型。有些问题里,输入数据 X 和输出数据 Y 都是序列,但就算在那种情况下, X 和 Y 有时也会不一样长。或者像上图编号1所示和上图编号2的 X 和 Y 有相同的数据长度。在另一些问题里,只有 X 或者只有 Y 是序列。

1.2 数学符号

image-20240713160243540

想要表示一个句子里的单词,第一件事是做一张词表,有时也称为词典,意思是列一列你的表示方法中用到的单词。

image-20240713160707637

如果你遇到了一个不在你词表中的单词,答案就是创建一个新的标记,也就是一个叫做Unknow Word的伪造单词,用<UNK>作为标记,来表示不在词表中的单词

1.3 循环神经网络模型

image-20240713161019090

建立一个神经网络来学习 X到 Y 的映射,可以尝试的方法之一是使用标准神经网络,在我们之前的例子中,我们有9个输入单词。想象一下,把这9个输入单词,可能是9个one-hot向量,然后将它们输入到一个标准神经网络中,经过一些隐藏层,最终会输出9个值为0或1的项,它表明每个输入单词是否是人名的一部分。

image-20240713161029539

但结果表明这个方法并不好,主要有两个问题,

  1. 输入和输出数据在不同例子中可以有不同的长度
  2. 并不共享从文本的不同位置上学到的特征

而且上面的输入都是10000维的one-hot向量,这是非常大的输入层,这第一层的权重矩阵就有着巨大的参数。

image-20240713161801750

每个时间步都是使用的相同的参数\(W_{ax}\)

image-20240713162411578

在计算\(\hat{y}^{<3>}\)的时候会使用到\(x^{<1>},x^{<2>},x^{<3>}\)来预测

缺点就是只使用了这个序列之前的信息来做出预测,没有用到后面的\(x^{<4>}\)...等,这里给定句子,需要知道句中后部分的信息

所以这样特定的神经网络结构的一个限制是它在某一时刻的预测仅使用了从序列之前的输入信息并没有使用序列中后部分的信息,我们会在之后的双向循环神经网络(BRNN)的视频中处理这个问题。

选用哪个激活函数是取决于你的输出 y ,如果它是一个二分问题,那么我猜你会用sigmoid函数作为激活函数,如果是 k 类别分类问题的话,那么可以选用softmax作为激活函数

image-20240713163413249

循环神经网络用的激活函数经常是tanh,不过有时候也会用ReLU

一般开始先输入$ a^{<0>}$ ,它是一个零向量。接着就是前向传播过程,先计算激活值$ a^{<1>}$ ,然后再计算 \(y^{<1>}\)

\[a^{<1>} = g_1(W_{aa}a^{<0>}+W_{ax}x^{<1>}+b_a) \]

\[\hat{y}^{<1>} = g_2(W_{ya}a^{<1>}+b_y) \]

在t时刻:

\[a^{<t>} = g_1(W_{aa}a^{<t-1>}+W_{ax}x^{<t>}+b_a) \]

\[\hat{y}^{<t>} = g_2(W_{ya}a^{<t>}+b_y) \]

image-20240713164821188

为了方便建立更复杂的神经网络,我们将这里的符号简化一下:

\[a^{<t>} = g_1(W_{a}[a^{<t-1>},x^{<t>}]+b_a) \]

\[\hat{y}^{<t>} = g_2(W_{y}a^{<t>}+b_y) \]

\[W_a = \begin{bmatrix} W_{aa}&W_{ax} \end{bmatrix} \]

\[W_{ya} = W_y \]

这里\([a^{<t-1>},x^{<t>}]\),是将向量堆在一起

\[\begin{bmatrix} a^{<t-1>}\\ x^{<t>} \end{bmatrix} \]

这样这两个乘在一起还是原来的结果

\[W_{a}[a^{<t-1>}] = \begin{bmatrix} W_{aa}&W_{ax} \end{bmatrix} \begin{bmatrix} a^{<t-1>}\\ x^{<t>} \end{bmatrix} = W_{aa}a^{<t-1>}+W_{ax}x^{<t>} \]

1.4 通过时间的反向传播

image-20240713165343031

1.5 不同类型的循环网络

image-20240713165758293

\(T_x\) 和$T_y $并不一定相等。

image-20240713170117750

image-20240713170455364

1.6 语言模型和序列生成

image-20240713171511064

建立语言模型:

1.你首先需要一个训练集,包含一个很大的英文文本语料库(corpus)或者其它的语言,你想用于构建模型的语言的语料库。

2.将这个句子标记化,建立一个字典,然后将每个单词都转换成对应的one-hot向量,也就是字典中的索引。EOS标记可以被附加到训练集中每一个句子的结尾。UNK的代表未知词

完成标识化的过程后,这意味着输入的句子都映射到了字典中的各个词上。

3.建立RNN

总体的损失函数:

\[L = \sum_t(\hat{y}^{<t>},y^{<t>}) \]

1.7 对新序列采样

在你训练一个序列模型之后,要想了解到这个模型学到了什么,一种非正式的方法就是进行一次新序列采样

记住一个序列模型模拟了任意特定单词序列的概率,我们要做的就是对这些概率分布进行采样来生成一个新的单词序列。

image-20240713172245915

如果你建立一个基于字符的语言模型,比起基于词汇的语言模型,你的序列在你的训练数据中将会是单独的字符,而不是单独的词汇。

image-20240713172730477

优点:

  • 不用担心会出现未知的标识

缺点:

  • 序列太长
  • 捕捉依赖关系范围小
  • 计算成本高昂

1.8 循环神经网络的梯度消失

image-20240713173202385

因为同样的梯度消失的问题,后面层的输出误差(上图编号6所示)很难影响前面层(上图编号7所示的层)的计算。这就意味着,实际上很难让一个神经网络能够意识到它要记住看到的是单数名词还是复数名词,然后在序列后面生成依赖单复数形式的was或者were。,所以基本的RNN模型会有很多局部影响,意味着这个输出 \(\hat{y}^{<3>}\)(上图编号9所示)主要受\(\hat{y}^{<3>}\)附近的值(上图编号10所示)的影响,上图编号11所示的一个数值主要与附近的输入(上图编号12所示)有关,上图编号6所示的输出,基本上很难受到序列靠前的输入(上图编号10所示)的影响,这是因为不管输出是什么,不管是对的,还是错的,这个区域都很难反向传播到序列的前面部分,也因此网络很难调整序列前面的计算。这是基本的RNN算法的一个缺点。

尽管我们一直在讨论梯度消失问题,但是,你应该记得我们在讲很深的神经网络时,我们也提到了梯度爆炸,我们在反向传播的时候,随着层数的增多,梯度不仅可能指数型的下降,也可能指数型的上升。事实上梯度消失在训练RNN时是首要的问题,尽管梯度爆炸也是会出现,但是梯度爆炸很明显,因为指数级大的梯度会让你的参数变得极其大,以至于你的网络参数崩溃。****所以梯度爆炸很容易发现,因为参数会大到崩溃,你会看到很多NaN,或者不是数字的情况,这意味着你的网络计算出现了数值溢出。如果你发现了梯度爆炸的问题,一个解决方法就是用梯度修剪。梯度修剪的意思就是观察你的梯度向量,如果它大于某个阈值,缩放梯度向量,保证它不会太大,这就是通过一些最大值来修剪的方法。所以如果你遇到了梯度爆炸,如果导数值很大,或者出现了NaN,就用梯度修剪,这是相对比较鲁棒的,这是梯度爆炸的解决方法。然而梯度消失更难解决,这也是我们下几节视频的主题。

1.9 GRU 单元

门控循环单元,它改变了RNN的隐藏层,使其可以更好地捕捉深层连接,并改善了梯度消失问题

image-20240713173430097

image-20240713174637329

[!TIP]

(Chung J, Gulcehre C, Cho K H, et al. Empirical Evaluation of Gated Recurrent Neural Networks on Sequence Modeling[J]. Eprint Arxiv, 2014.

Cho K, Merrienboer B V, Bahdanau D, et al. On the Properties of Neural Machine Translation: Encoder-Decoder Approaches[J]. Computer Science, 2014.)

ct用来记忆前面的词语,门用来控制什么时候更新ct

image-20240713174934290

1.10 长短期记忆

[!TIP]

Hochreiter S, Schmidhuber J. Long Short-Term Memory[J]. Neural Computation, 1997, 9(8):1735-1780.)

这篇论文比较难读懂,深入介绍了梯度消失的理论

image-20240713175851452

LSTM的新特性:

不只有一个更新门控制,使用其他的项来代替$\Gamma_u $和\(1-\Gamma_u\)。增加一个\(\Gamma_f\),使用了单独的更新门和遗忘门。

image-20240713180439952

门值不仅取决于 \(a^{<t-1>}\) 和 $x^{} $,有时候也可以偷窥一下 $ c^{}\(的值(上图编号13所示),这叫做“窥视孔连接”(**peephole connection**)。虽然不是个好听的名字,但是你想,“**偷窥孔连接**”其实意思就是**门值不仅取决于\)a^{}$ 和 \(x^{<t>}\) ,也取决于上一个记忆细胞的值( $c^{} \()**,然后“偷窥孔连接”就可以结合这三个门(\)\Gamma_u、\Gamma_f、\Gamma_o$ )来计算了。

GRU的优点是这是个更加简单的模型,所以更容易创建一个更大的网络,而且它只有两个门,在计算性上也运行得更快,然后它可以扩大模型的规模。

但是LSTM更加强大和灵活,因为它有三个门而不是两个。如果你想选一个使用,我认为LSTM在历史进程上是个更优先的选择,所以如果你必须选一个,我感觉今天大部分的人还是会把LSTM作为默认的选择来尝试。虽然我认为最近几年GRU获得了很多支持,而且我感觉越来越多的团队也正在使用GRU,因为它更加简单,而且还效果还不错,它更容易适应规模更加大的问题。

1.11 双向循环神经网络

双向RNN模型,这个模型可以让你在序列的某点处不仅可以获取之前的信息,还可以获取未来的信息

image-20240713180850536

image-20240713181353179

你就可以用一个用RNNGRULSTM构建的模型,并且能够预测任意位置,即使在句子的中间,因为模型能够考虑整个句子的信息。这个双向RNN网络模型的缺点就是你需要完整的数据的序列,你才能预测任意位置。比如说你要构建一个语音识别系统,那么双向RNN模型需要你考虑整个语音表达,但是如果直接用这个去实现的话,你需要等待这个人说完,然后获取整个语音表达才能处理这段语音,并进一步做语音识别。对于实际的语音识别的应用通常会有更加复杂的模块,而不是仅仅用我们见过的标准的双向RNN模型。

1.12 深层循环神经网络

image-20240713182033601

week2 自然语言处理与词嵌入

2.1 词汇表征

image-20240716170005981

我们一直用one-hot向量来表示词,缺点就是它把每个词孤立起来,这样使得算法对相关词的泛化能力不强。

任何两个one-hot向量的内积都是0,很难区分它们之间的差别,因为这些向量内积都是一样的,所以无法知道appleorange要比kingorange,或者queenorange相似地多。

image-20240716170544543

这种高维特征的表示能够比one-hot更好的表示不同的单词

image-20240716170842547

[!TIP]

常用的可视化算法是t-SNE算法,来自于Laurens van der MaatenGeoff Hinton的论文。

这种词嵌入算法对于相近的概念,学到的特征也比较类似,在对这些概念可视化的时候,这些概念就比较相似,最终把它们映射为相似的特征向量。

2.2 使用词嵌入

image-20240716171903448

学习词嵌入的算法会考察非常大的文本集。尽管你只有一个很小的训练集,也许训练集里有100,000个单词,甚至更小,这就使得你可以使用迁移学习,把你从互联网上免费获得的大量的无标签文本中学习到的知识,能够分辨orange(橙子)、apple(苹果)和durian(榴莲)都是水果的知识,然后把这些知识迁移到一个任务中,比如你只有少量标记的训练数据集的命名实体识别任务中。

用词嵌入做迁移学习的步骤:

  1. 先从大量的文本集中学习词嵌入。
  2. 你可以用这些词嵌入模型把它迁移到你的新的只有少量标注训练集的任务中
  3. 当你在你新的任务上训练模型时,在你的命名实体识别任务上,只有少量的标记数据集上,你可以自己选择要不要继续微调,用新的数据调整词嵌入。(只有第二步有很大的数据量的情况下才去微调)

之前人脸识别的Siamese网络会用一个128维的向量来代表不同的人脸。

在人脸识别中我们训练一个网络,任给一个人脸照片,甚至是没有见过的照片,神经网络都会计算出相应的一个编码结果。

我们学习词嵌入则是有一个固定的词汇表,比如10000个单词,我们学习向量\(e_1\)\(e_{10000}\) ,学习一个固定的编码,每一个词汇表的单词的固定嵌入

人脸识别中的算法未来可能涉及到海量的人脸照片,而自然语言处理有一个固定的词汇表,而像一些没有出现过的单词我们就记为未知单词。

2.3 词嵌入的特性

词嵌入能帮助实现类比推理

image-20240716173426791

\[e_{man}-e_{woman} = \begin{bmatrix} -1 \\ 0.01 \\ 0.03 \\ 0.09 \end{bmatrix}- \begin{bmatrix} 1 \\ 0.02 \\ 0.02 \\ 0.01 \end{bmatrix} =\begin{bmatrix} -2 \\ -0.01 \\ 0.01 \\ 0.08 \end{bmatrix} ≈ \begin{bmatrix} -2 \\ 0 \\ 0 \\ 0 \end{bmatrix} \]

类似的,用\(e_king\)减去\(e_queen\)也是类似的结果

这个结果表示,manwoman主要的差异是gender(性别)上的差异,而kingqueen之间的主要差异,根据向量的表示,也是gender(性别)上的差异,这就是为什么 $ e_{man}-e_{woman}$ 和$e_{king}-e_{queen} $结果是相同的。

所以得出这种类比推理的结论的方法就是,当算法被问及manwoman相当于king对什么时,算法所做的就是计算\(e_{man}-e_{woman}\) ,然后找出一个向量也就是找出一个词,使得 \(e_{man}-e_{woman}\approx e_{king}-e_?\) ,也就是说,当这个新词是queen时,式子的左边会近似地等于右边。

[!TIP]

这种思想首先是被Tomas MikolovWen-tau Yih还有Geoffrey Zweig提出的,这是词嵌入领域影响力最为惊人和显著的成果之一,这种思想帮助了研究者们对词嵌入领域建立了更深刻的理解。

(Mikolov T, Yih W T, Zweig G. Linguistic regularities in continuous space word representations[J]. In HLT-NAACL, 2013.)

找到相似度最大化的答案,就能找到正确的答案

\[arg maxSim(e_w,e_{king}-e_{man+e_{woman}}) \]

image-20240716174924108

如果你查看一些研究论文就不难发现,通过这种方法来做类比推理准确率大概只有30%~75%,只要算法猜中了单词,就把该次计算视为正确,从而计算出准确率

t-SNE算法所做的就是把这些300维的数据用一种非线性的方式映射到2维平面上,可以得知t-SNE中这种映射很复杂而且很非线性。在进行t-SNE映射之后,你不能总是期望使等式成立的关系,会像左边那样成一个平行四边形,尽管在这个例子最初的300维的空间内你可以依赖这种平行四边形的关系来找到使等式成立的一对类比,通过t-SNE算法映射出的图像可能是正确的。但在大多数情况下,由于t-SNE的非线性映射,你就没法再指望这种平行四边形了,很多这种平行四边形的类比关系在t-SNE映射中都会失去原貌。

image-20240716175636397

最常用的相似度函数叫做余弦相似度。这是我们上个幻灯片所得到的等式,在余弦相似度中,假如在向量 u 和 v 之间定义相似度:

\[sim(u,v)=\frac{u^Tv}{||u||_2||v||_2} \]

如果u和v非常相似,它们的内积会很大

[!NOTE]

这个公式实际就是计算两向量夹角Φ角的余弦。你应该还记得在微积分中,Φ角的余弦图像是这样的(下图编号3所示),所以夹角为0度时,余弦相似度就是1,当夹角是90度角时余弦相似度就是0,当它们是180度时,图像完全跑到了相反的方向,这时相似度等于-1,这就是为什么余弦相似度对于这种类比工作能起到非常好的效果。

距离用平方距离或者欧氏距离来表示: \(||u-v||^2\)

2.4 嵌入矩阵

image-20240716180541112

\[Eo_j = e_j = embedding \quad for \quad word \quad j \]

E嵌入矩阵 ✖️ onehot = 嵌入向量

但在具体实现的时候,因为one-hot是一个维度非常高的向量,并且所有元素几乎都是0,所以矩阵向量相乘效率太低,在实现的时候有专门方法,而不使用矩阵乘法。

2.5 学习词嵌入

image-20240717090455448

假如你在构建一个语言模型,并且用神经网络来实现这个模型。于是在训练过程中,你可能想要你的神经网络能够做到比如输入:“I want a glass of orange ___.”,然后预测这句话的下一个词。在每个单词下面,我都写上了这些单词对应词汇表中的索引。实践证明,建立一个语言模型是学习词嵌入的好方法,我提出的这些想法是源于Yoshua Bengio,Rejean Ducharme,Pascal Vincent,Rejean Ducharme,Pascal Vincent还有Christian Jauvin

具体的建立过程:

  • 我们从第一个词I开始,建立一个one-hot向量表示这个单词I。这是一个one-hot向量(上图编号1所示),在第4343个位置是1,它是一个10,000维的向量。
  • 由矩阵乘以one-hot向量得到嵌入向量。
  • 将300维的嵌入向量放入神经网络,经过神经网络之后再通过softmax层,这个softmax有自己的参数,然后softmax分类器会在10000个可能的输出中预测结尾的这个单词。
  • 隐藏层的参数\(W^{[1]}\)\(b^{[1]}\),输出层的参数\(W^{[2]}\)\(b^{[2]}\)。如果用的是300维的嵌入向量,这里有6个词,输入那么就是一个 300*6维的向量,就是将这6个嵌入向量堆在一起得到的。

image-20240717090512700

实际上更常见的是有一个固定的历史窗口,举个例子,你总是想预测给定四个单词(上图编号1所示)后的下一个单词,注意这里的4是算法的超参数。这就是如何适应很长或者很短的句子,方法就是总是只看前4个单词,所以说我只用这4个单词(上图编号2所示)而不去看这几个词(上图编号3所示)。如果你一直使用一个4个词的历史窗口,这就意味着你的神经网络会输入一个1200维的特征变量到这个层中(上图编号4所示),然后再通过softmax来预测输出,选择有很多种,用一个固定的历史窗口就意味着你可以处理任意长度的句子,因为输入的维度总是固定的。所以这个模型的参数就是矩阵 E ,对所有的单词用的都是同一个矩阵 E ,而不是对应不同的位置上的不同单词用不同的矩阵。然后这些权重(上图编号5所示)也都是算法的参数,你可以用反向传播来进行梯度下降来最大化训练集似然,通过序列中给定的4个单词去重复地预测出语料库中下一个单词什么。

image-20240717091110397

如果你要建立一个语言模型,那么一般选取目标词之前的几个词作为上下文。但如果你的目标不是学习语言模型本身的话,那么你可以选择其他的上下文。

2.6 Word2Vec

[!TIP]

(Mikolov T, Chen K, Corrado G, et al. Efficient Estimation of Word Representations in Vector Space[J]. Computer Science, 2013.)

image-20240717092222921

于是我们将构造一个监督学习问题,它给定上下文词,要求你预测在这个词正负10个词距或者正负5个词距内随机选择的某个目标词。显然,这不是个非常简单的学习问题,因为在单词orange的正负10个词距之间,可能会有很多不同的单词。但是构造这个监督学习问题的目标并不是想要解决这个监督学习问题本身,而是想要使用这个学习问题来学到一个好的词嵌入模型。

模型的细节:

假设使用一个10,000词的词汇表,有时训练使用的词汇表会超过一百万词。但我们要解决的基本的监督学习问题是学习一种映射关系从上下文c,比如单词orange到某个目标词,记为t,可能是单词juice或者单词glass或者单词my。延续上一张幻灯片的例子,在我们的词汇表中,orange是第6257个单词,juice是10,000个单词中的第4834个,这就是你想要的映射到输出 y 的输入 x

image-20240717092802282

为了表示输入,比如单词orange,你可以先从one-hot向量开始,我们将其写作$ O_c$ ,这就是上下文词的one-hot向量(上图编号1所示)。然后和你在上节视频中看到的类似,你可以拿嵌入矩阵 E 乘以向量 \(O_c\),然后得到了输入的上下文词的嵌入向量,于是这里\(e_c=EO_c\) 。在这个神经网络中(上图编号2所示),我们将把向量 \(e_c\) 喂入一个softmax单元。我通常把softmax单元画成神经网络中的一个节点(上图编号3所示),这不是字母O,而是softmax单元,softmax单元要做的就是输出 $ \hat{y}$。然后我们再写出模型的细节,这是softmax模型(上图编号4所示),预测不同目标词的概率:

\[softmax:p(t|c) = \frac{exp(\theta_t^Te_c)}{\sum_{j=1}^{10000}exp(\theta_j^Te_c)} \]

这里 \(\theta_t\) 是一个与输出 t 有关的参数,即某个词 t 和标签相符的概率是多少。我省略了softmax中的偏差项,想要加上的话也可以加上。

最终softmax的损失函数就会像之前一样,我们用 y 表示目标词,我们这里用的 y 和 \(\hat{y}\)都是用one-hot表示的,于是损失函数就会是:

\[L(\hat{y},y) = -\sum_{i=1}^{10000}y_ilog\hat{y}_i \]

这是常用的softmax损失函数, y 就是只有一个1其他都是0的one-hot向量,如果目标词是juice,那么第4834个元素就是1,其余是0(上图编号5所示)。类似的 \(\hat{y}\)是一个从softmax单元输出的10,000维的向量,这个向量是所有可能目标词的概率。

如果优化这个关于所有这些参数的损失函数,你就会得到一个较好的嵌入向量集,这个就叫做Skip-Gram模型。它把一个像orange这样的词作为输入,并预测这个输入词,从左数或从右数的某个词,预测上下文词的前面一些或者后面一些是什么词。

image-20240717094458420

尤其是在softmax模型中,每次你想要计算这个概率,你需要对你词汇表中的所有10,000个词做求和计算,解决这个问题可以使用,如分级(hierarchical)的softmax分类器和负采样(Negative Sampling)。

意思就是说不是一下子就确定到底是属于10,000类中的哪一类。所以你不需要再为单次分类,对词汇表中所有的10,000个词求和了。实际上用这样的分类树,计算成本与词汇表大小的对数成正比(上图编号4所示),而不是词汇表大小的线性函数,这个就叫做分级softmax分类器。

在实践中分级softmax分类器不会使用一棵完美平衡的分类树或者说一棵左边和右边分支的词数相同的对称树(上图编号1所示的分类树)。实际上,分级的softmax分类器会被构造成常用词在顶部,然而不常用的词像durian会在树的更深处(上图编号2所示的分类树)

image-20240717094959898

那就是怎么对上下文c进行采样,一旦你对上下文c进行采样,那么目标词t就会在上下文c的正负10个词距内进行采样。但是你要如何选择上下文c?一种选择是你可以就对语料库均匀且随机地采样,如果你那么做,你会发现有一些词,像theofaandto诸如此类是出现得相当频繁的,于是你那么做的话,你会发现你的上下文到目标词的映射会相当频繁地得到这些种类的词,但是其他词,像orangeappledurian就不会那么频繁地出现了。你可能不会想要你的训练集都是这些出现得很频繁的词,因为这会导致你花大部分的力气来更新这些频繁出现的单词的 \(e_c\) (上图编号1所示),但你想要的是花时间来更新像durian这些更少出现的词的嵌入,即 $e_{durian} $。实际上词 $p(c) $的分布并不是单纯的在训练集语料库上均匀且随机的采样得到的,而是采用了不同的分级来平衡更常见的词和不那么常见的词。

CBOW,即连续词袋模型(Continuous Bag-Of-Words Model),它获得中间词两边的的上下文,然后用周围的词去预测中间的词。

总结下:CBOW是从原始语句推测目标字词;而Skip-Gram正好相反,是从目标字词推测出原始语句。CBOW对小型数据库比较合适,而Skip-Gram在大型语料中表现更好。

2.7 负采样

[!TIP]

Mikolov T, Sutskever I, Chen K, et al. Distributed Representations of Words and Phrases and their Compositionality[J]. 2013, 26:3111-3119.

image-20240717095918234

给定一对单词,比如orangejuice,我们要去预测这是否是一对上下文词-目标词(context-target)。

总结一下,生成这些数据的方式是我们选择一个上下文词(上图编号2所示),再选一个目标词(上图编号3所示),这(上图编号4所示)就是表的第一行,它给了一个正样本,上下文,目标词,并给定标签为1。然后我们要做的是给定几次,比如 K 次(上图编号5所示),我们将用相同的上下文词,再从字典中选取随机的词,king、book、the、of等,从词典中任意选取的词,并标记0,这些就会成为负样本(上图编号6所示)。出现以下情况也没关系,就是如果我们从字典中随机选到的词,正好出现在了词距内,比如说在上下文词orange正负10个词之内。

那么如何选取 K ?Mikolov等人推荐小数据集的话, K 从5到20比较好如果你的数据集很大, K 就选的小一点。对于更大的数据集 K就等于2到5,数据集越小 K 就越大。那么在这个例子中,我们就用 K = 4 。

\[softmax:p(t|c) = \frac{exp(\theta_t^Te_c)}{\sum_{j=1}^{10000}exp(\theta_j^Te_c)} \]

  • c代表上下文词
  • t表示可能的目标次
  • y=0代表不是一对上下文目标词,y=1代表是一对上下文目标词

定义一个逻辑回归模型,给定输入c,t对的条件下,y=1的概率:

\[P(y=1|c,t) = \sigma(\theta_t^Te_c) \]

如果你有 K 个样本,你可以把这个看作 \(\frac{1}{K}\)的正负样本比例,即每一个正样本你都有 K 个对应的负样本来训练一个类似逻辑回归的模型。

论文的作者Mikolov既不用经验频率,也就是实际观察到的英文文本的分布,也不用均匀分布,他们采用以下方式:

\[P(w_i) = \frac{f(w_i)^{\frac{3}{4}}}{\sum_{j=1}^{10000}f(w_j)^{\frac{3}{4}}} \]

2.8 GloVe词向量

[!TIP]

(Pennington J, Socher R, Manning C. Glove: Global Vectors for Word Representation[C]// Conference on Empirical Methods in Natural Language Processing. 2014:1532-1543.)

GloVe代表用词表示的全局变量(global vectors for word representation)。

假定\(X_{ij}\)是单词 i 在单词 j上下文中出现的次数,遍历你的训练集,然后数出单词 i 在不同单词 j 上下文中出现的个数,会得出\(X_{ij} = X_{ji}\)如果将上下文和目标词的范围定义为出现于左右各10词 以内的话,就会有一种对称关系。如果你对上下文的选择是,上下文总是目标词前一个单词的话,那么 $X_{ij} \(和\)X_{ji}$就不会像这样对称了。

不过对于GloVe算法,我们可以定义上下文和目标词为任意两个位置相近的单词,假设是左右各10词的距离,那么 \(X_{ij}\)就是一个能够获取单词 i 和单词 j 出现位置相近时或是彼此接近的频率的计数器。

GloVe模型做的就是进行优化,我们将他们之间的差距进行最小化处理:

\[minimize\sum_{i=1}^{10000}\sum_{j=1}^{10000}f(X_{ij})(\theta_i^{T}e_j+b_i+b_{j^{'}}-logX_{ij})^2 \]

\(\theta_i^Te_j\)表示的是这两个单词之间有多少联系,就是它们同时出现的平率是多少

image-20240717110119133

image-20240717112006632

假设说有个空间,里面的第一个轴(上图编号1所示)是Gender,第二个轴(上图编号2所示)是Royal,你能够保证的是第一个嵌入向量对应的轴(上图编号3所示)是和这个轴(上面提到的第一和第二基轴,编号1,2所示)有联系的,它的意思可能是Gender、Royal、AgeFood。具体而言,这个学习算法会选择这个(上图编号3所示)作为第一维的轴,所以给定一些上下文词,第一维可能是这个轴(上图编号3所示),第二维也许是这个(上图编号4所示),或者它可能不是正交的,它也可能是第二个非正交轴(上图编号5所示),它可以是你学习到的词嵌入中的第二部分。当我们看到这个(上图编号6所示)的时候,如果有某个可逆矩阵 A ,那么这项(上图编号6所示)就可以简单地替换成 \((A\theta_i)^T(A^{-T}e_j)\) ,因为我们将其展开:

\[(A\theta_i)^T(A^{-T}e_j) = \theta_i^{T}A^TA^{-T}e_j = \theta_i^{T}e_j \]

老师意思应该是说,轴的意义不一定明确,并且轴之间不一定正交

用人话说就是这个表是机器学习出来给自己看的,人类可能无法理解这是什么玩意,更无法解释

2.9 情感分类

image-20240717113046714

一个更复杂的情感分类器:不是简单的将所有的相加

image-20240717153536559

image-20240717153719889

不用简单的把所有的词嵌入都加起来,我们用一个RNN来做情感分类。我们这样做,首先取这条评论,“Completely lacking in good taste, good service, and good ambiance.”,找出每一个one-hot向量,这里我跳过去每一个one-hot向量的表示。用每一个one-hot向量乘以词嵌入矩阵 E ,得到词嵌入表达 e ,然后把它们送进RNN里。RNN的工作就是在最后一步(上图编号1所示)计算一个特征表示,用来预测 $\hat{y} $,这是一个多对一的网络结构的例子,我们之前已经见过了。有了这样的算法,考虑词的顺序效果就更好了,它就能意识到"things are lacking in good taste",这是个负面的评价,“not good”也是一个负面的评价。而不像原来的算法一样,只是把所有的加在一起得到一个大的向量,根本意识不到“not good”和 “good”不是一个意思,"lacking in good taste"也是如此,等等。

2.10 词嵌入除偏

image-20240717154457107

image-20240717155121426

week3 序列模型和注意力机制

3.1 基础模型

image-20240718150926576

基本的seq2seq模型

image-20240718151158663

image to sequence模型

image-20240718151740993

不过这两个模型运作方式有一些不同,主要体现在如何用语言模型合成新的文本,并生成对应序列的方面。

3.2 选择最可能的句子

image-20240718152649950

机器翻译想成是建立一个条件语言模型

image-20240718152918829

所以当你使用这个模型来进行机器翻译时,你并不是从得到的分布中进行随机取样,而是你要找到一个英语句子 y(上图编号1所示),使得条件概率最大化。所以在开发机器翻译系统时,你需要做的一件事就是想出一个算法,用来找出合适的 y 值,使得该项最大化,而解决这种问题最通用的算法就是束搜索(Beam Search)

为什么不用贪心搜索(Greedy Search)呢?生成第一个词的分布以后,它将会根据你的条件语言模型挑选出最有可能的第一个词进入你的机器翻译模型中,在挑选出第一个词之后它将会继续挑选出最有可能的第二个词,然后继续挑选第三个最有可能的词,这种算法就叫做贪心搜索,但是你真正需要的是一次性挑选出整个单词序列

3.3 集束搜索

集束搜索则会考虑多个选择,集束搜索算法会有一个参数B,叫做集束宽(beam width)。在这个例子中我把这个集束宽设成3,这样就意味着集束搜索不会只考虑一个可能结果,而是一次会考虑3个,比如对第一个单词有不同选择的可能性,最后找到in、jane、september是英语输出的第一个单词的最可能的三个选项,然后集束搜索算法会把结果存到计算机内存里以便后面尝试用这三个词。

image-20240718155004151

集束算法接下来会针对每个第一个单词考虑第二个单词是什么(下图编号1所示)。

image-20240718155412231

为了评估第二个词的概率值,我们用这个神经网络的部分,绿色是编码部分(上图编号2所示),而对于解码部分,当决定单词in后面是什么,别忘了解码器的第一个输出 \(y^{<1>}\) ,我把$ y^{<1>}\(设为单词**in**(上图编号3所示),然后把它喂回来,这里就是单词**in**(上图编号4所示),因为它的目的是努力找出第一个单词是**in**的情况下,第二个单词是什么。这个输出就是\) y^{<2>}$(上图编号5所示),有了这个连接(上图编号6所示),就是这里的第一个单词in(上图编号4所示)作为输入,这样这个网络就可以用来评估第二个单词的概率了,在给定法语句子和翻译结果的第一个单词in的情况下。

\[P(y^{<1>},y^{<2>}|x) = P(y^{<1>}|x)P(y^{<2>}|x) \]

注意,在第二步里我们更关心的是要找到最可能的第一个和第二个单词对,所以不仅仅是第二个单词有最大的概率,而是第一个、第二个单词对有最大的概率(上图编号7所示)。按照条件概率的准则,这个可以表示成第一个单词的概率(上图编号8所示)乘以第二个单词的概率(上图编号9所示),这个可以从这个网络部分里得到(上图编号10所示),对于已经选择的in、jane、september这三个单词,你可以先保存这个概率值(上图编号8所示),然后再乘以第二个概率值(上图编号9所示)就得到了第一个和第二个单词对的概率(上图编号7所示)。

image-20240718160006906

针对第二个单词所有10,000个不同的选择,最后对于单词september也一样,从单词a到单词zulu,用这个网络部分,我把它画在这里。来看看如果第一个单词是september,第二个单词最可能是什么。所以对于集束搜索的第二步,由于我们一直用的集束宽为3,并且词汇表里有10,000个单词,那么最终我们会有3乘以10,000也就是30,000个可能的结果,因为这里(上图编号1所示)是10,000,这里(上图编号2所示)是10,000,这里(上图编号3所示)是10,000,就是集束宽乘以词汇表大小,你要做的就是评估这30,000个选择。按照第一个词和第二个词的概率,然后选出前三个,这样又减少了这30,000个可能性,又变成了3个,减少到集束宽的大小。假如这30,000个选择里最可能的是“in September”(上图编号4所示)和“jane is”(上图编号5所示),以及“jane visits”(上图编号6所示),画的有点乱,但这就是这30,000个选择里最可能的三个结果,集束搜索算法会保存这些结果,然后用于下一次集束搜索。

注意一件事情,如果集束搜索找到了第一个和第二个单词对最可能的三个选择是“in September”或者“jane is”或者“jane visits”,这就意味着我们去掉了september作为英语翻译结果的第一个单词的选择,所以我们的第一个单词现在减少到了两个可能结果,但是我们的集束宽是3,所以还是有 \(y^{<1>}\)\(y^{<2>}\) 对的三个选择。

image-20240718160532952

3.4 改进集束搜索

image-20240718161256422

长度归一化(Length normalization)就是对束搜索算法稍作调整的一种方式。

因为 log 函数它是严格单调递增的函数,最大化 P(y) ,因为对数函数,这就是 log 函数,是严格单调递增的函数,所以最大化 \(logP(y|x)\)和最大化 \(P(y|X)\) 结果一样。

image-20240718161655604

如果参照原来的目标函数(this original objective),如果有一个很长的句子,那么这个句子的概率会很低,因为乘了很多项小于1的数字来估计句子的概率。概率的log 值通常小于等于1,实际上在log的这个范围内,所以加起来的项越多,得到的结果越负。我们不再最大化这个目标函数了,我们可以把它归一化,通过除以翻译结果的单词数量(normalize this by the number of words in your translation)。这样就是取每个单词的概率对数值的平均了,这样很明显地减少了对输出长的结果的惩罚(this significantly reduces the penalty for outputting longer translations.)。

image-20240718161912431

相比于直接除\(T_y\) ,也就是输出句子的单词总数,我们有时会用一个更柔和的方法(a softer approach),在 \(T_y\)上加上指数 α 可以等于0.7。如果\(\alpha\)等于1,就相当于完全用长度来归一化,如果 α 等于0,\(T_y\)的0次幂就是1,就相当于完全没有归一化,这就是在完全归一化和没有归一化之间。

image-20240718162400389

B越大,你考虑的选择越多,你找到的句子可能越好,但是B越大,你的算法的计算代价越大,因为你要把很多的可能选择保存起来。

3.5 集束搜索的误差分析

image-20240718162924219

人工是这样翻译的: Jane visits Africa in September,我会将这个标记为\(y^*\)

当你在已经完成学习的RNN模型,也就是已完成学习的翻译模型中运行束搜索算法时,它输出了这个翻译结果:Jane visited Africa last September,我们将它标记为 $ \hat{y}$

你的模型有两个主要部分,一个RNN模型,它实际上是个编码器和解码器( an encoder and a decoder)。另一部分是束搜索算法,以某个集束宽度B运行。如果你能够找出造成这个错误,这个不太好的翻译的原因,是两个部分中哪一个造成的?

image-20240718163227129

计算\(P(\hat{y}|x)\)\(P(y^*|x)\),比较这两个值的大小。

image-20240718163652379

  • \(P(y^*|x)\)>\(P(\hat{y}|x)\) beam引起的误差

    束搜索算法选择了 \(\hat{y}\) ,对吧? 你得到$ \hat{y} $的方式是,你用一个RNN模型来计算 \(P(y|x)\),然后束搜索算法做的就是尝试寻找使\(P(y|x)\)最大的 y,不过在这种情况下,相比于$\hat{y} $, $y^* $的值 \(P(y|x)\)更大,因此你能够得出束搜索算法实际上不能够给你一个能使 \(P(y|x)\)最大化的 y 值,因为束搜索算法的任务就是寻找一个 y 的值来使这项更大,但是它却选择了 \(\hat{y}\),而 \(y^*\) 实际上能得到更大的值。因此这种情况下你能够得出是束搜索算法出错了。

  • \(P(y^*|x)\)\(P(\hat{y}|x)\) RNN引起的误差

    \(y^*\) 是比$ \hat{y}$ 更好的翻译结果,不过根据RNN模型的结果, \(P(y^*)\) 是小于 \(P(\hat{y})\)的,也就是说,相比于$\hat{y} $, \(y^*\) 成为输出的可能更小。因此在这种情况下,看来是RNN模型出了问题。同时可能值得在RNN模型上花更多时间。

当你发现是束搜索算法造成了大部分错误时,才值得花费努力增大集束宽度。相反地,如果你发现是RNN模型出了更多错,那么你可以进行更深层次的分析,来决定是需要增加正则化还是获取更多的训练数据,抑或是尝试一个不同的网络结构

3.6 Bleu得分

Bleu(bilingual evaluation understudy)得分:如果有多个不错的答案,衡量准确性

[!TIP]

参考论文:Papineni, Kishore& Roukos, Salim & Ward, Todd & Zhu, Wei-jing. (2002). BLEU: a Method for Automatic Evaluation of Machine Translation.10.3115/1073083.1073135.

是一篇很好读的文章

image-20240718165555598

isolated word:

把出现在参考中的词在MT输出的所有词所占的比例作为精准度:

Precision:\(\frac{7}{7}\) 这里7个the在reference1和reference2都出现了

把每个单词的记分上限定为它在参考句子中出现的最多次数

Modified precision:\(\frac{2}{7}\) 在reference1中单词the出现了两次

image-20240719090457635

paired word:

precision:\(\frac{count求和}{count_{clip}求和} = \frac{1+0+1+1+1}{2+1+1+1+1} = \frac{4}{6}\)

image-20240719091055635

定义\(P_n\) 为 n 元词组精确度,用n-gram替代掉一元词组。所以这就是机器翻译输出中的 n 元词组的countclip之和除以 n 元词组的出现次数之和。

BP的意思是“简短惩罚”( brevity penalty)。这些细节也许并不是十分重要,但是你可以大致了解一下。 事实表明,如果你输出了一个非常短的翻译,那么它会更容易得到一个高精确度。因为输出的大部分词可能都出现在参考之中,不过我们并不想要特别短的翻译结果。因此简短惩罚(BP)就是一个调整因子,它能够惩罚输出了太短翻译结果的翻译系统。

image-20240719091317582

3.7 注意力模型直观理解

有了注意力模型,机器翻译系统的表现会像这个一样,因为翻译只会翻译句子的一部分,你不会看到这个有一个巨大的下倾(huge dip),这个下倾实际上衡量了神经网络记忆一个长句子的能力

image-20240719092111846

[!TIP]

注意力模型源于Dimitri, Bahdanau, Camcrun Cho, Yoshe Bengio。(Bahdanau D, Cho K, Bengio Y. Neural Machine Translation by Jointly Learning to Align and Translate[J]. Computer Science,2014.)

image-20240719093603670

S 来表示RNN的隐藏状态(the hidden state in this RNN),用 $ S^{<1>}$ 。我们希望在这个模型里第一个生成的单词将会是Jane

注意力模型就会计算注意力权重(a set of attention weights),我们将用 \(a^{<1,1>}\) 来表示当你生成第一个词时你应该放多少注意力在这个第一块信息处。接下去同理,计算\(a^{<1,2>}\)\(a^{<1,3>}\)...

\(S^{<2>}\)来计算第二个词...

RNN向前进一次生成一个词,在每一步直到最终生成可能是<EOS>。这些是注意力权重,\(a^{<t,t>}\) 告诉你,当你尝试生成第 t 个英文词,它应该花多少注意力在第 t 个法语词上面。当生成一个特定的英文词时,这允许它在每个时间步去看周围词距内的法语词要花多少注意力。

3.8 注意力模型

\(a^{<t>}\)表示前向的特征值和后向的特征值,\(a^{<t>}\)就是时间步t上的特征向量

\(\alpha\)参数告诉我们上下文有多少,取决于我们从不同时间步中得到的激活值。

\[a^{<t^{'}>} = \overleftarrow{a}^{<t^{'}>} + \overrightarrow{a}^{<t^{'}>} \]

\[\sum_{t^{'}} \alpha^{<1,t^{'}>} = 1 \]

\[C^{<1>} =\sum_{t^{'}} \alpha^{<1,t^{'}>} a^{<t^{'}>} \]

image-20240719100334283

\(\alpha^{<t,t^{'}>}\) 应该花费在\(a^{t^{'}}\)上的注意力的数量

如果你有$T_x $个输入单词和 $T_y \(个输出单词,于是注意力参数的总数就会是\)T_x*T_y $

3.9 语音识别

image-20240719101802506

语音识别系统中输入的时间步数量要比输出的时间步数量多很多。

image-20240719102748297

CTC损失函数的一个基本规则是将空白符之间的重复的字符折叠起来

[!TIP]

这篇论文来自于 Alex Grace

3.10 触发字检测

image-20240719103748178

把一个音频片段(an audio clip)计算出它的声谱图特征(spectrogram features)得到特征向量 \(x^{<1>},x^{<2>},x^{<3>}\cdots\),然后把它放到RNN中,最后要做的,就是定义我们的目标标签 y 。假如音频片段中的这一点是某人刚刚说完一个触发字,那么在这一点之前,你就可以在训练集中把目标标签都设为0,然后在这个点之后把目标标签设为1。不过该算法一个明显的缺点就是它构建了一个很不平衡的训练集,0的数量比1多太多了。

比起只在一个时间步上去输出1,其实你可以在输出变回0之前,多次输出1,或说在固定的一段时间内输出多个1。这样的话,就稍微提高了1与0的比例

posted @ 2024-07-19 10:44  记录学习Blog  阅读(18)  评论(0编辑  收藏  举报