资讯详情

从零实现深度学习框架——N-Gram语言模型(一)

引言

本着“如果我不能创造,我就不能理解这一系列的文章将以纯粹为基础Python以及NumPy从零开始创建自己的深度学习框架,类似于PyTorch实现自动求导。

要深入理解深度学习,从零开始创造的经验是非常重要的。从我们可以理解的角度来看,我们应该尽量不使用完整的外部框架来实现我们想要的模型。本系列文章的目的是让每个人都能有效地掌握深度学习的底层实现,而不仅仅是成为一个调整者。

从本文开始了解自然语言处理(Natural Language Processing)基本知识。虽然标题是从零开始实现深度学习框架,但它仍然侧重于NLP相关技术的方面。最重要的是L(Language),然后我不得不提到语言模型(Language model)本文主要介绍n-gram语言模型。

语言模型

给出一个句子,如何预测下一个单词?

明犯强汉,虽远必_ 

你可能会猜到下一个单词是惩罚。这里的单词不仅表示英语中的单词,也表示中文中的单词。在本文中,我们将引入一个可以给下一个单词概率的模型。它还可以为整个句子生成判断句子是否流畅的概率。

能够赋予单词序列概率的模型称为语言模型(Language model,LM),本文将介绍最简单的语言模型——n-gram。

N-Gram

假设句子: w 1 , ? ? , w m w_1,\cdots,w_m w1,?,wm。包含 m m m一个单词,我们可以计算出它的概率: P ( w 1 , ? ? , w m ) (1) P(w_1,\cdots,w_m) \tag{1} P(w1,?,wm​)(1) 给定单词出现的历史 h h h,我们可以计算单词 w w w在给定历史下出现的概率。假设历史 h h h为“今天天气好”,然后想知道下一个单词是“晴朗”的概率: P ( 晴 朗 ∣ 今 天   天 气   好 ) (2) P(晴朗|今天\,天气\,好) \tag{2} P(晴朗∣今天天气好)(2) 一种简单的方法是基于频数:拿一个非常大的语料库,统计我们看到“今天天气好晴朗”的次数,以及后面出现“晴朗”的次数,那么可以就可以计算出公式 ( 2 ) (2) (2)的概率: P ( 晴 朗 ∣ 今 天   天 气   好 ) = C ( 今 天   天 气   好   晴 朗 ) C ( 今 天   天 气   好 ) (3) P(晴朗|今天\,天气\,好) = \frac{C(今天\,天气\,好\,晴朗)}{C(今天\,天气\,好)} \tag{3} P(晴朗∣今天天气好)=C(今天天气好)C(今天天气好晴朗)​(3) 由于中文和英文不一样,中文需要分词,而分词本身是一个重要的NLP应用。我们这里假设已经用空格分好词了。

为了你的模型能很好的应用,你需要统计所有出现的情况,假设你能统计整个网络中所有出现的次数,但是由于语言具有创造性,新的词语或句子总是被创造出来,你就无法统计所有的句子。

我们需要一种更加聪明的方式。这里引入一些标记,为了表示某个随机变量 X i X_i Xi​取“晴朗”的概率 P ( X i = 晴 朗 ) P(X_i=晴朗) P(Xi​=晴朗),我们简记为 P ( 晴 朗 ) P(晴朗) P(晴朗)。然后我们表示 n n n个单词的序列(句子)为: w 1 ⋯ w n w_1 \cdots w_n w1​⋯wn​,或 w 1 : n w_{1:n} w1:n​。

我们想要知道某个句子中所有单词的联合概率,这个联合概率就是该句子出现的概率。

对于每个单词出现在句子中的联合概率 P ( X 1 = w 1 , X 2 = w 2 , ⋯   , X n = w n ) P(X_1=w_1,X_2=w_2,\cdots,X_n=w_n) P(X1​=w1​,X2​=w2​,⋯,Xn​=wn​),我们使用 P ( w 1 , w 2 , ⋯   , w n ) P(w_1,w_2,\cdots,w_n) P(w1​,w2​,⋯,wn​)来简化。

计算这个句子的联合概率有什么用呢?假设我们要设计一个聊天机器人,我们生成了两个句子,其中一个句子的联合概率明显高于另一个,那么肯定选择高的那个当成输出。

那我们如何计算整个序列的概率 P ( w 1 , w 2 , ⋯   , w n ) P(w_1,w_2,\cdots,w_n) P(w1​,w2​,⋯,wn​)呢,我们可以使用链式法则来分解联合概率: P ( X 1 ⋯ X n ) = P ( X 1 ) P ( X 2 ∣ X 1 ) P ( X 3 ∣ X 1 : 2 ) ⋯ P ( X n ∣ X 1 : n − 1 ) = ∏ k = 1 n P ( X k ∣ X 1 : k − 1 ) (4) \begin{aligned} P(X_1\cdots X_n) &= P(X_1) P(X_2|X_1) P(X_3|X_{1:2})\cdots P(X_n|X_{1:n-1}) \\ &= \prod_{k=1}^n P(X_k|X_{1:k-1}) \\ \end{aligned} \tag 4 P(X1​⋯Xn​)​=P(X1​)P(X2​∣X1​)P(X3​∣X1:2​)⋯P(Xn​∣X1:n−1​)=k=1∏n​P(Xk​∣X1:k−1​)​(4) 应用链式法则,我们带入单词就可以得到: P ( w 1 : n ) = P ( w 1 ) P ( w 2 ∣ w 1 ) P ( w 3 ∣ w 1 : 2 ) ⋯ P ( w n ∣ w 1 : n − 1 ) = ∏ k = 1 n P ( w k ∣ w 1 : k − 1 ) (5) \begin{aligned} P(w_{1:n}) &= P(w_1)P(w_2|w_1)P(w_3|w_{1:2}) \cdots P(w_n|w_{1:n-1}) \\ &= \prod_{k=1}^n P(w_k|w_{1:k-1}) \end{aligned} \tag 5 P(w1:n​)​=P(w1​)P(w2​∣w1​)P(w3​∣w1:2​)⋯P(wn​∣w1:n−1​)=k=1∏n​P(wk​∣w1:k−1​)​(5) 链式法则可以计算序列的联合概率和给定历史单词下计算下一个单词的条件概率之间的联系。

但是这里有一个问题,我们无法计算某个单词前面所有单词的准确概率 P ( w n ∣ w 1 : n − 1 ) P(w_n|w_{1:n-1}) P(wn​∣w1:n−1​)​。正如上面所说的,我们不能仅仅通过计算每个单词在每个长串之后出现的次数来估计,因为语言是创造性的,任何给定的上下文可能以前从未出现过,比如“鸡你太美”中的“鸡你太”可能之前都没出现过。

而N-gram模型解决了这个问题,它进行简化,只根据前面几个单词来估计历史单词。

比如Bi-gram模型,仅使用前一个单词产生下个单词的条件概率 P ( w n ∣ w n − 1 ) P(w_n|w_{n-1}) P(wn​∣wn−1​)来估计所有历史单词下产生下个单词的概率 P ( w n ∣ w 1 : n − 1 ) P(w_n|w_{1:n-1}) P(wn​∣w1:n−1​),即 P ( w n ∣ w n − 1 ) ≈ P ( w n ∣ w 1 : n − 1 ) (6) P(w_n|w_{n-1}) \approx P(w_n|w_{1:n-1}) \tag 6 P(wn​∣wn−1​)≈P(wn​∣w1:n−1​)(6)

这里的Bi是双的意思,还有后面会看到的Uni(单)、Tri(三)。

N-gram的这种简化实际上是一种假设,马尔科夫假设——一个单词的概率只取决于前面 N − 1 N-1 N−1个单词的假设。这里 N = 2 N=2 N=2为Bi-gram。类似地,可以有Unigram(与前面单词无关,都是独立的)或Trigram(只依赖于过去的两个单词)甚至n-gram( N > 2 N>2 N

标签: 撕裂传感器限位开关zwn

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台