返回介绍

4. 基于迭代的方法

发布于 2025-02-18 23:44:02 字数 11457 浏览 0 评论 0 收藏 0

现在我们退后一步,来尝试一种新的方法。在这里我们并不计算和存储全局信息,因为这会包含太多大型数据集和数十亿句子。我们尝试创建一个模型,它能够一步步迭代地进行学习,并最终得出每个单词基于其上下文的条件概率。

词语的上下文: 一个词语的上下文是它周围 C 个词以内的词。如果 C=2 ​,句子 The quick brown fox jumped over the lazy dog 中单词 fox 的上下文为 {"quick", "brown", "jumped", "over"} ​。

我们想建立一个概率模型,它包含已知和未知参数。每增加一个训练样本,它就能从模型的输入、输出和期望输出(标签),多学到一点点未知参数的信息。

在每次迭代过程中,这个模型都能够评估其误差,并按照一定的更新规则,惩罚那些导致误差的参数。这种想法可以追溯到 1986 年(Learning representations by back-propagating errors. David E. Rumelhart, Geoffrey E. Hinton, and Ronald J.Williams (1988)),我们称之为误差“反向传播”法。

4.1 语言模型(1-gram,2-gram 等等)

首先,我们需要建立一个能给“分词序列”分配概率的模型。我们从一个例子开始:

"The cat jumped over the puddle."(猫 跳 过 水坑)

一个好的语言模型会给这句话以很高的概率,因为这是一个在语法和语义上完全有效的句子。同样地,这句”stock boil fish is toy”(股票 煮 鱼 是 玩具)就应该有一个非常低的概率 ,因为它是没有任何意义的。在数学上,我们可以令任意给定的 n 个有序的分词序列的概率为:


我们可以采用一元语言模型。它假定词语的出现是完全独立的,于是可以将整个概率拆开相乘:

看到这里,肯定很多同学就要喷了,这不对,词和词之间没有关联吗?确实,我们知道一句话中每一个词语都跟它前面的词语有很强的依赖关系,忽略这一点的话,一些完全无意义的句子,可能会有很高的概率。咱们稍微改一改,让一个词语的概率依赖于它前面一个词语。我们将这种模型称作 bigram(2-gram,二元语言模型),表示为:

看起来还是有点简单?恩,也对,我们只考虑一个词语依赖于其相邻的一个词语的关系,而不是考虑其依赖整个句子的情况。别着急,接下来将会看到,这种方法能让我们有非常显著的进步。考虑到前面 “词-词”矩阵的情况,我们至少可以算出两个词语共同出现的概率。但是,旧话重提,这仍然要求储存和计算一个非常的大数据集里面的全部信息。
现在我们理解了“分词序列”的概率(其实就是 N-gram 语言模型啦),让我们观察一些能够学习到这些概率的例子。

4.2 连续词袋模型(CBOM)

有种模型是以{“The”, “cat”, ’over”, “the’, “puddle”}为上下文,能够预测或产生它们中心的词语”jumped”,叫做连续词袋模型。

上面是最粗粒度的描述,咱们来深入一点点,看点细节。

首先,我们要建立模型的一些已知参数。它们就是将句子表示为一些 one-hot 向量,作为模型的输入,咱们记为 x(c) 吧。模型的输出记为 y(c) 吧。因为连续词袋模型只有一个输出,所以其实我们只需记录它为 y。在我们上面举的例子中,y 就是我们已经知道的(有标签的)中心词(如本例中的”jumped”)。

好了,已知参数有了,现在我们一起来定义模型中的未知参数。我们建立两矩阵, 。其中的 n 是可以任意指定的,它用来定义我们“嵌入空间”(embedding space)的维度。V 是输入词矩阵。当词语(译注:是只有第 i 维是 1 其他维是 0 的 one-hot 向量)作为模型的一个输入的时候,V 的第 i 列就是它的 n 维“嵌入向量”(embedded vector)。我们将 V 的这一列表示为。类似的,U 是输出矩阵。当作为模型输出的时候,U 的第 j 行就是它的 n 维“嵌入向量”。我们将 U 的这一行表示为。要注意我们实际上对于每个词语学习了两个向量。(作为输入词的向量,和作为输出词的向量)。

连续词袋模型(CBOM)中的各个记号:

  • :单词表 V 中的第 i 个单词
  • :输入词矩阵
  • :V 的第 i 列,单词的输入向量
  • :输出词矩阵
  • :U 的第 i 行,单词的输出向量

那这个模型是如何运作的呢?我们把整个过程拆分成以下几步:

  1. 对于 m 个词长度的输入上下文,我们产生它们的 one-hot 向量()。
  2. 我们得到上下文的嵌入词向量(
  3. 将这些向量取平均
  4. 产生一个得分向量
  5. 将得分向量转换成概率分布形式
  6. 我们希望我们产生的概率分布 ,与真实概率分布相匹配。而刚好也就是我们期望的真实词语的 one-hot 向量。

用一幅图来表示就是下面这个样子:

通过上面说的种种步骤,我们知道有了矩阵 U、V 整个过程是如何运作的,那我们怎样找到 U 和 V 呢?——我们需要有一个目标函数。通常来说,当我们试图从已知概率学习一个新的概率时,最常见的是从信息论的角度寻找方法来评估两个概率分布的差距。其中广受好评又广泛应用的一个评估差异/损失的函数是交叉熵:

结合我们当下的例子,y 只是一个 one-hot 向量,于是上面的损失函数就可以简化为:

我们用 c 表示 y 这个 one-hot 向量取值为 1 的那个维度的下标。所以在我们预测为准确值的情况下。于是损失为 ?1 log(1) = 0。所以对于一个理想的预测值,因为预测得到的概率分布和真实概率分布完全一样,因此损失为 0。现在让我们看一个相反的情况,也就是我们的预测结果非常不理想,此时。计算得到的损失为?1 log(0.01) ≈ 4.605,损失非常大,原本这才是标准结果,可是你给了一个非常低的概率,因此会拿到一个非常大的 loss 。可见交叉熵为我们提供了一个很好的衡量两个概率分布的差异的方法。于是我们最终的优化函数为:


我们用梯度下降法去更新每一个相关的词向量

4.3 Skip-Gram 模型

很上面提到的模型对应的另一种思路,是以中心的词语”jumped”为输入,能够预测或产生它周围的词语”The”, “cat”, ’over”, “the”, “puddle”等。这里我们叫”jumped”为上下文。我们把它叫做 Skip-Gram 模型。
这个模型的建立与连续词袋模型(CBOM)非常相似,但本质上是交换了输入和输出的位置。我们令输入的 one-hot 向量(中心词)为 x(因为它只有一个),输出向量为 y(j)。U 和 V 的定义与连续词袋模型一样。

Skip-Gram 模型中的各个记号:

  • :单词表 V 中的第 i 个单词
  • :输入词矩阵
  • :V 的第 i 列,单词的输入向量
  • :输出词矩阵
  • :U 的第 i 行,单词的输出向量

对应到上面部分,我们可以把 Skip-Gram 模型的运作方式拆分成以下几步:

  1. 生成 one-hot 输入向量 x。
  2. 得到上下文的嵌入词向量
  3. 因为这里不需要取平均值的操作,所以直接是
  4. 通过产生 2m 个得分向量
  5. 将得分向量转换成概率分布形式
  6. 我们希望我们产生的概率分布与真实概率分布 相匹配,也就是我们真实输出结果的 one-hot 向量。

用一幅图来表示这个过程如下:


像连续词袋模型一样,我们需要为模型设定一个目标/损失函数。不过不同的地方是我们这里需要引入朴素贝叶斯假设来将联合概率拆分成独立概率相乘。如果你之前不了解它,可以先跳过。这是一个非常强的条件独立性假设。也就是说只要给出了中心词,所有的输出词是完全独立的。


我们可以用随机梯度下降法去更新未知参数的梯度。

4.4 负面抽样(Negative Sampling)

我们再次观察一下目标函数,注意到对整个单词表|V|求和的计算量是非常巨大的,任何一个对目标函数的更新和求值操作都会有 O(|V|) 的时间复杂度。我们需要一个思路去简化一下,我们想办法去求它的近似。
对于每一步训练,我们不去循环整个单词表,而只是抽象一些负面例子就够了!我们可以从一个噪声分布中抽样,其概率分布与单词表中的频率相匹配。为了将描述问题的公式与负面抽样相结合,我们只需要更新我们的:

  • 目标函数
  • 梯度
  • 更新规则

Mikolov ET AL.在他的《Distributed Representations of Words and Phrases and their Compositionality》中提出了负面抽样。虽然负面抽样是基于 Skip-Gram 模型,它实际上是对一个不同的目标函数进行最优化。考虑一个“词-上下文”对(w,c),令 P(D = 1|w, c) 为(w, c) 来自于语料库的概率。相应的,P(D = 0|w, c) 则是不来自于语料库的概率。我们首先对 P(D = 1|w, c) 用 sigmoid 函数建模:


现在我们需要建立一个新的目标函数。如果(w, c) 真是来自于语料库,目标函数能够最大化 P(D = 1|w, c)。反之亦然。我们对这两个概率采用一个简单的最大似然法。(这里令θ为模型的参数,在我们的例子中,就是对应的 U 和 V。)

注意这里的表示“错误的”或者“负面的”语料库,像句子”stock boil fish is toy”就是从这样的语料库来的。不自然的句子应该有比较低的发生概率,我们可以从词库中随机采样来产生这样的“负面的”语料库。我们的新目标函数就变成了:

在这里是从(Pn(w)) 中抽样取到的。需要多说一句的是,虽然关于怎么样最好地近似有许多讨论和研究,但是工作效果最好的似乎是指数为 3/4 的一元语言模型。至于为什么是 3/4,下面有几个例子来帮助大家感性地理解一下:

你看,经过 3/4 这样一个指数处理,”Bombastic”(少见) 被采样的概率是之前的 3 倍,而“is”这个词(多见) 被采样的概率只是稍微增长了一点点。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文