Language Modeling(语言模型)

语言模型要做的事情就是估测一个word sequence(也就是一句话的概率),也就是说给你一个句子(由一串词汇word构成的),这个就代表的是word,例子中有个word,这个合起来就是一个句子。language model要做的事情就是,你要找一个function告诉我们说这个句子出现的概率有多大。
举例来说:
   recognize speech和wreck a beach,他们的发音其实是一样的(破坏一个海滩和语音辨识的英文发音是一样的)。所以光听语音你是没有办法去判断,是破坏一个海滩还是语音辨识,所以你要通过概率来发现说语音辨识句子出现的概率比破坏海滩句子出现的概率还要大(因为我们不该常常破坏海滩),最后的output就是语音辨识。
  在翻译有时候也需要language model。
  他其实还有一个很好的应用,就是sentence generation(句子的生成),如果有一个app是要让你的machine说一句话,这个时候你就需要用到language model,machine有很多个句子是可以进行选择的,通过language model来选择哪个句子是最有可能的。
  
这样的好处就是,有两个词汇,他们是相近的,有两个history他们是很相近的。比如说"dog"和"cat",他们其实是很相近的,他们的 和 是很接近的。如果 是很大的,那 也会跟着值很大,就算是你在training data里面从来没有看到过"dog"后面接"jumped",但是凭着"dog"的vector和"cat"vector很像这件事情,你就可以估测出既然"cat"和"jumped"相接的概率很大,"dog"与"jumped"相接的概率也会很大。

原文链接:https://www.jianshu.com/p/9ffa57c9a136

什么是语言模型?

  语言模型要做的事情就是估测一个word sequence(也就是一句话的概率),也就是说给你一个句子(由一串词汇word构成的),这个w就代表的是word,例子中有n个word,这nw合起来就是一个句子。language model要做的事情就是,你要找一个function告诉我们说这个句子出现的概率有多大。

  那这件事情有什么用呢?比如你可以用在语音辨识上面,在语音辨识上你一定需要language model,因为在做语音辨识的时候,有时候不同的word sequence,他可能有同样的发音。



举例来说:
   recognize speech和wreck a beach,他们的发音其实是一样的(破坏一个海滩和语音辨识的英文发音是一样的)。所以光听语音你是没有办法去判断,是破坏一个海滩还是语音辨识,所以你要通过概率来发现说语音辨识句子出现的概率比破坏海滩句子出现的概率还要大(因为我们不该常常破坏海滩),最后的output就是语音辨识。

  在翻译有时候也需要language model。
  他其实还有一个很好的应用,就是sentence generation(句子的生成),如果有一个app是要让你的machine说一句话,这个时候你就需要用到language model,machine有很多个句子是可以进行选择的,通过language model来选择哪个句子是最有可能的。
如果不用neural network,那传统上language model是怎么做的呢?

N-gram

N-gram

就用N-gram,那怎么去估计一句话的概率呢?概率这个东西,我们可以收集一个很大的data base[数据库],去统计w_1-w_n出现的次数。然后我们就可以知道如果说一句话的话,w_1-w_n的概率是多少,但是麻烦的就是,w_1-w_n这个句子,在我们的语料库中,可能一次都没有出现过,那要怎么办呢?我们要把p(w_1-w_n)的概率拆成比较小的component(成分),而每一个component的概率使我们可以从data base里面估测出来的,在把每一个conponent的概率乘起来,就变成这一整个sequence的概率。

所以说N-gram的概念就是说,我们把w_1-w_n的概率拆成条件概率,而这里面的每一个概率都是可以从训练数据中估测出来的,假设我们要估测p("beach|nice")的概率是多大(nice后面接beach的概率有多大的话),我们只需要计算nice beach这两个词汇在整个训练数据里面出现的次数再除去nice这个词汇出现的次数,你就可以得到在nice后面接beach的概率。上面那个例子叫做2-gram model,如果你每一个component只考虑前一个word的话,这个叫做2-gram(bi-gram也就是binary gram的缩写),如果考虑前两个word就是3-gram...

NN-based Language Model


首先要收集training data,接下来学习一个neural network,这个neural network的作用就是预测下一个词汇,我们学习一个neural network,他的input是 潮水退了 ,他的目标就是 ,然后你就用cross entropy去minimize你的network output还有他的target。input是 退了,他的output就是 知道,input是 知道,output就是 。NN-base language model就是这个样子。有了neural network以后要怎么算句子的概率呢?


我们同样把一个句子拆成2-gram概率的相乘。但是我们现在用 NN-base language model的话,这些概率就不是从统计来,就不是从count data base里面那些词汇出现的次数来得到这个概率,这个概率就是 network的output,也就是说,假设现在我们想要知道
wreck
放在句首的概率的话,我们需要有一个
token(标记)
代表说句子的起始,我们把句子的起始这件事情也当做是一个词汇来看待,我们的neural network就input句子的起始的这一个
token
,然后让他去预测
wreck
这个word是下一个word的概率,你把这个概率拿出来就放在上面拆分的那个地方。然后你把
wreck
这个词汇,用1-of-N encoding来表示,然后把它丢到network里面,然后让他predict下一个词汇是什么,假设世界上有十万个词汇,那么他的output就有十万维,那每一维都会有一个数字,你把
wreck
丢进去的话,每一个词汇都会有一个数字代表这个词汇是
wreck
这个词汇下一个词汇的概率,如果
a
的概率是多少,那么
wreck
后面就是接
a
的概率,然后就反复下去。把所有的词的概率统统乘起来,就是得到这个句子的概率了。

RNN-base Language Model

如果今天是RNN-base language model,他的training也是一个样子的:


RNN-base language model

也就是说我收集了很多数据,这个RNN的input begin的时候,他就要output潮水,input潮水他就output退了,input的退了他就output,input就output知道...那和NN不一样的地方就是他在output为"知道"的时候,他是看了"潮水","退了","就"...这么多的词汇,才能决定说接下来的output会是"知道",如果是NN的话,他现在的input就predict output,如果是RNN的话,他会看这个句子之前所有的词汇,再决定他的output。

那要怎么使用RNN-based language model呢?

如何去估测这个p(w_1,w_2,w_3....w_n)这个概率呢?
你把RNN learn出来以后,你就丢一个begin进去,看他在w_1这个词汇的分数也就是p(w_1),接下来把w_1丢进去,就得到p(w_2|w_1)...依次类推。然后把所有的概率统统的乘起来,你就得到一个句子的概率
那做RNN的好处就是可以建模long-term的信息,也可以用多层的RNN或者LSTM。

接下来,解释一下,为什么需要NN-based language model,用NN-based language model相较于传统的model有什么好处?

那我们先看一下传统的N-gram的language model,传统的最大的问题就是,那个概率你很难估测的准,因为我们永远没有足够的data(语料库),让我们把概率真的估计的很准,尤其是当我们的N很大的时候,我们会遇到data sparsity[数据稀疏],因为我们的data不够,所以我们没有办法把所有的n-gram在data base上都观察的到。所以有一些n-gram概率,我们是估计不准的。

举例来说:假设我的training data里面有一个句子是"the dog ran",另一个句子是"the cat jumped"。那如果你在估计一个3-gram language model的概率的时候,"the dog"后面接"jumped"的概率就会变成是0,"the dog"后面接"ran"的概率是有值的,同理"the cat"后面接"ran"的概率就会是0,但是这件事情并不是正确的,因为"dog"不只会"jump"也会"ran","cat"不止会"jumped"还会"ran"。只是因为我们的database太小了,如果你把全世界中所有时间的句子统统的收集起来的话,你就可以正确的用N-gram language mode估测出概率来。但是我们没有办法来做这件事情,所以我们估测的概率是不准的,有一些N-gram,比如"the dog"后面接"jumped",这样的概率是0,但是实际上他并不一定是0,他其实还是有可能会出现的,但是data base不够大,所以我们没有办法观察到这件事情。所以传统的一个解法叫做smoothing(平滑处理),smoothing意思就是说不要真正给一个N-gram概率为0,你给他一个小小的概率。怎样使用smoothing其实也是一个很大的学问,这个就不在讨论。

那今天用NN的话,用deep learning有什么好处呢?


Matrix Factorization(矩阵因子分解)

想到data sparsity[数据稀疏]的问题,你就会想到matrix factorization[矩阵因子分解]。我们可以把n-gram的概率看成是一个table,这个table其中一个dimension代表的是history,另外一个dimension代表的是vocabulary[词汇],这个table上面的每一个element,代表的是给某一个history,他之后接下一个word的概率。比如0.2代表的是看见"cat"作为history,接下来接"jumped"的概率是0.2,所以我们可以估计一个2-gram language model,然后把2-gram language model的值写作是一个table。当然你也可以很轻易的概括到3-gram,你把table上的history上的词汇改成三个词汇,就可以泛化到3-gram...,那你会发现说,在这个表格里面,大部分的空格其实都是0。很多2-gram在你的data base里面一次都没有看到,所以他estimate出来的概率都是0。但是他的概率是0,不代表说他真的就是0,只是我们的database不够大,所以我们没有看到。

这种问题和推荐系统的问题是一样的。所以我们可以套用推荐系统的方法来解这个问题。那如何去解呢?

每一个history,我们都用一个vector来表示。每一个vocabulary我们也都用vector来描述,这个vh的dimension要是一样的,因为一会要做他们的inner product[内积],dimension一样的才能乘起来。这个vh是要被学出来的,那怎么去学他呢?你要去minimizing右下角的那个function。我们假设这个table里面的element都用n加上两个下标来表示,你希望minimizing的东西就是你希望让v^{i} \cdot h^{j}他的值和n_{ij}越接近越好。接下来你用gradient descent运算,你就可以把vh的vector统统都找出来,你就可以给每一个history一个vector,就可以给vocabulary每一个词汇一个vector。接下来你就可以根据找出来的vector,把这些是0的数值空格的分数算出来,也就是说n_{12}就变成了 h^{1}v^{2}。 你就可以把是0空格的哪些分数把他算出来,他们相乘的时候不会是0。

这样的好处就是,有两个词汇,他们是相近的,有两个history他们是很相近的。比如说"dog"和"cat",他们其实是很相近的,他们的 h^{dog}h^{cat}是很接近的。如果 v^{jump}\cdot h^{cat}是很大的,那 v^{jump}\cdot h^{dog}也会跟着值很大,就算是你在training data里面从来没有看到过"dog"后面接"jumped",但是凭着"dog"的vector和"cat"vector很像这件事情,你就可以估测出既然"cat"和"jumped"相接的概率很大,"dog"与"jumped"相接的概率也会很大。


这个和一般的smoothing不一样,用这个matrix factorization的方法你等于也是做了smoothing,但是和一般的smoothing的方法是不一样的,一般的smoothing方法,你是没办法真正的去考虑词汇的意思是什么,只是说这边0.2太大减一点分给其他的词,但是如果你今天用matrix factorization的方法,你可以真的把词汇的意思考虑进去,你会考虑说这个"dog"和"jumped"他们这个0可能是会有值的,但是"dog"和"cried"以及"dog"和"laughed"这些值通常是比较小的。

那这个东西和NN有什么关系呢?其实matrix factorization是可以写成NN的,他可以写成只有一个layer的neural network:


你可以这样想,因为我们这边需要考虑的是概率,所有每一个column的和都是1,他才能是概率。我们今天算的是,某一个history后面接某一个vocabulary的概率。每一个column的和必须要是1,他才是一个概率。

这边要做一个小小的更改,我么假设"dog"这个history他的vector就是h^{dog}。我们可以把 h^{dog}v^{ran}做内积,我们可以把 h^{dog}v^{cried}做内积,对每一个vocabulary的v做内积。每一个vocabulary就可以得到一个数值,但是这些数值的和,你没有办法当成概率来看,因为他的和不是1,甚至有可能是负数。那怎么办呢?你就做一个softmax,做一个softmax以后,你就可以把 h^{dog} \cdot v^{ran}的结果通过softmax结果看成是dog后面接ran的概率。你就可以把h^{dog} \cdot v^{caried} 的结果通过softmax的结果看成是"dog"后面接"cried"的概率。

接下来在training的时候,我们知道说根据training data,假设"dog"后面接"ran"的概率是0.2。"dog"后面接"cried"的概率是0,那这个vector就是你的target。那你再learn你的参数的时候,你就会希望说,这些做完inner product的结果和这个target的cross entropy是被minimizing的。

这件事情其实你就可以把想他想成就是一个NN,怎么说呢?我们的这个history就是这个NN的input。input的dimension就是看你的history有几个可能,假设我们今天考虑2-gram。那input每一个dimension与hidden layer相接的这些weight,就是哪一个history对应的vector,也就是对用到"cat"的哪个history,他跟hidden layer这些dimension相接的这些weight,就是 h^{cat},对应到"dog"哪个dimension,与之间hidden layer相接的这些value就是h^{dog}。那今天input就是用1-of-N encoding来表示,假设你今天看见的history是"dog"的话,用1-of-N encoding来表示的话,就是"dog"那一维度是1,其他的都是0。你把这个vector丢到network里面去,假设我们不考虑激活函数的话,得到的就是 h^{dog},接下来乘以v这件事情,你就可以把他想成是另外一个layer,那把hv做内积想成是做另外一个layer,然后在使用softmax得到一个layer的output,然后一直train下去。这就是为什么NN用来做language model的应用。那其实在这种n-gram language model,这种新的n-gram language model在2010年以后才比较流行。一开始用matrix factorization来做,后来发现使用NN的performance是比较好的,使用NN的话,你不仅可以迭一层,你还可以考虑RNN。

那使用NN到底会有什么好处呢?如果我们现在比较用NN和做N-gram language model所需要的参数量,你会发现,NN所需要的参数量是比较小的,如果今天我们做n-gram language model,你需要估计的参数,是history的数目乘上vocabulary的数目,但是在这个neural network里面,你需要估计的参数远小于history的数目乘以vocabulary的数目,你要估计的参数是每一个history要给他vector h,每一个vocabulary word都给他一个vector vhv的dimension不要设的太大,你neural network所需要的参数是远小于language model所需要的参数的。也就是说假设history的数目有h的绝对值 ,vocabulary的数目是v的绝对值个,如果你今天用n-gram language model的话,你需要估测的参数是h的绝对值乘上v的绝对值,很大。如果你今天使用NN-base language model,你需要的参数是你对每一个history都有一个vector,他这个vector的dimension是可以自己决定的,假设他是kk不要设的太大,你可以设k=100之类的,然后为每一个vocabulary都给他一个vector,这个vector的dimension也是k,这个东西其实他会远小于这个数值,所以你使用NN的好处并不是NN很大,NN有很多层,所以他可以暴力的去fit你的model,其实不是,你用n-gram才是暴力的方法,参数很多,你用neural network的时候,你用的参数是比较少的,他比较不容易overfitting,所以你会得到比较好的performance,NN的好处通常是因为你用的参数比较少,比较不会overfitting。

那为什么要用RNN?


使用RNN的好处就是可以更减少参数。如果今天考虑的history,非常的长,( w_{1}-w_{t} )个词那么长,前t个词汇所组成的history有多少个可能呢?有 v^{t} 那么多,如果你今天的word的size有10万个,那这个可能的history数目就变成了一个天文数字,你用**1-of-n encoding **描述他很显然是不行的;

这个时候,我们就可以使用RNN来描述他,RNN就是反复使用某一个function,所以把一个function f拿出来,每次把w_1丢到f里面得到h_1,依次类推,最后把w_t丢进f里面产生h_th_t就是这一整个history的representation[表示],这一整个history,我们就可以用RNN最后的output h_t来表示他,不管你的history有多长,RNN的参数都不会变多;

你再把h_t乘上一个vocabulary里面每一个word v,再通过softmax就可以算出每一个word的概率。那在training的时候呢?你就看说,这个history( w_{1}-w_{t} )后面 w_{t+1}是哪一个词汇。那你的learn target就是哪一个词汇是1,其他都是0,其实不需要统计说( w_{1}-w_{t} )后面接的w_{t+1}的distribution是什么,因为( w_{1}-w_{t} )这个词汇在training里面,可能就只出现一次而已,他可能不会出现两次以上可以让你统计出distribution,他可能就只出现一次而已,所以在实际操作上你的target,就只是一个1-hot的vector就是( w_{1}-w_{t} )后面接的 w_{t+1}的词汇1,其他就是0,就是一个1-hot vactor。

Class-based Language Modeling

该方法基于词类建立语言模型,以缓解数据稀疏问题,且可以方便融合部分语法信息。




Soft Word Class


RNN-based LM + Embedding Layer

Character-based LM

Long-term Information



CNN for LM


  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值