大概学习了语言模型一个星期,只对语言模型停留在了刚刚开始了解的阶段,所以有什么问题还请大家多多指出,多多包涵。
本文会对各个语言模型的作用,缺点,主要内容进行讲解,若要对语言模型有深刻的认识,csdn也会有很多很好的博客,本文也会附加一些博客的网址,我也是通过这些博客来学习语言模型的,然后总结出来这个博客。那我们就开始吧!
(加粗括号里的知识点属于插入的知识点,因为怕学习的时候弄混脑子里的对主干语言模型的逻辑,也可选择先看主干,再看插入)
语言模型的作用:通过计算一句话概率来判断一句话是否在语法上通顺。
语言模型分为统计语言模型和神经网络语言模型,在我学习的过程来看,统计语言模型较容易理解,而神经网络语言模型相对于复杂些,和我一起学习的伙伴也有同样的感觉,一星期可以基本了解统计语言模型的知识点,但是神经网络语言模型在脑子里会混乱些。
我们首先对统计语言模型进行讲解。
统计语言模型是不断发展的,分为了四个阶段:基本语言模型,Unigram,Bigram,N-gram语言模型
基本语言模型公式:
P(w1,w2,w3…,wi)=P(w1)P(w2|w1)P(w3|w1,w2)…P(wm|w1,w2,…wi−1)
P为概率,w1为一个句子的各个单词,等式左边为一个句子在训练数据集的概率,等式右边为当前词与前面所有词都有关的概率相乘。
缺点:1:基本语言模型是当前词与前面所有词都有关,但是当句子过于长的时候,就会出现参数过多的问题。
2:因为概率的计算是P(BA)/P(B),当B过多的时候,会出现数据稀疏问题。因为统计类语言模型是用one—hot编码,维度表示大部分都为0,导致了大量的空间浪费。
(贝叶斯公式这时候可能就会有同学要问了,那我怎么知道等式右边每个的概率怎么求呢?这个时候,就需要牵扯到一些公式:
联合条件概率:P(A,B) = P(A|B)P(B) = P(B|A)P(A)
贝叶斯公式:P(A|B)=P(B|A)*P(A)/P(B)= C(BA)/C(B)(C为单词在训练数据集里出现的频次)
贝叶斯公式就是基本语言模型公式的计算方法,也很出名,若想要深入了解贝叶斯公式,也可以自行百度,会有一些了解的。)
Unigram语言模型公式:
P(w1,w2,w3,…wi)= P(w1)P(w2)P(w3)…P(wi)
当前词是独立的,仅与自己有关
Bigram语言模型公式:
P(w1,w2,w3,…wi)= P(w1)P(w2|w1)P(w3|w1)…P(wi|wi-1)
当前词仅与前一个词有关
然而最常用的统计类语言模型还是N-gram语言模型
N-gram语言模型公式:
P(w1,w2,w3,…wi)= P(w1)P(w2|w1)P(w3|w1,w2)…P(wi|wi-1,wi-2),n=3
当前词与前面n-1个词有关,一般情况下n都是取3的。
缺点:1:没有考虑词与词之间的联系性
2:数据稀疏
以上三种语言模型Unigram语言模型,Bigram语言模型,N-gram语言模型都解决了参数过多难以训练的问题。
( 在求概率的时候,会出现分子或者分母为零的情况,这是因为训练数据集里没有的没有的单词,但是现实生活中是存在的,我们将采用让分子和分母同时加上一个数,使其不等于零,但是也会让它的概率很小,接近于零。这种方法被称为平滑
平滑的方法分为好多种,这里我们只讲解其中比较常见的三种:add_one,add K, interpolation。
add_one:使分子+1,分母加V( V:语料库里不同词的的个数,语料库=训练数据集,不同文章里可能叫法不一样)
add K:分子+k,分母+kv。也可以使分子分母不为0(add one和add k都是为了解决分子为0的情况)
interpolation:n-gram = r1n-gram+r2unigram+r3bigram
(r1+r2+r3 = 1)
n-gram求出的概率由n-gram,unigram,bigram三者决定,r1,r2,r3为三者的权重,哪个的语言模型好,哪个语言模型的权重就高。最后要让r1+r2+r3 = 1。interpolation是为了解决分母为0的情况,一个词比另一个词在现实生活中出现的概率高,但是计算得到两个的概率都为0,是相等的,这样是不合理的,所以就会有interpolation的出现。)
至此,统计类语言模型已经讲解完毕,接下来的神经网络语言模型才会是重点和难点。
神经网络语言模型的发展过程大概是这样的:神经网络—循环神经网络—双向循环神经网络—长短式记忆神经网络—双向长短时记忆循环神经网络。
由上文我们可以知道因为N-gram有着数据稀疏,造成大量浪费的缺点,在这种情况下,出现了神经网络语言模型(NNLM)。
神经网络语言模型与统计类语言模型不同的是,它是通过一个神经网络对其建模求解,而统计类语言模型是通过计数的方式对其求解,但是作用是一样的,都是对词典中的word在输入context下的条件概率做出预估。懂了神经网络语言模型,以后的循环式语言模型也就会好理解很多,所以我们会对神经网络语言模型讲解的很详细。
神经网络语言模型分为了四个层(可能其它文章说的不会太一样,但是大概内容和作用是一样的,我习惯于分为四个层):输入层,embedding词嵌入层,tanh隐含层,softmax输出层。
输入层的作用是把输入句子里的各个单词用one-hot编码,把单词映射成词向量。
embedding词嵌入层是把one-hot编码乘以一个D×V的矩阵C(D指embedding的维度,V指的是语料库里不同词的个数),映射成一个分布式的词向量,(C矩阵里储存了word vector)本质上指的是将高维稀疏的向量变成低维稠密的连续向量。在这里解决了N-gram维度灾难的问题。
tanh隐含层是一个非线性激活函数tanh,隐藏层的意义就是把输入数据的特征,抽象到另一个维度空间,来展现其更抽象化的特征,这些特征能更好的进行线性划分。可以逼近任意函数。
softmax输出层是一个归一化函数,输出一个词典一样的大小V的概率分布向量,其基本思想是将复杂的归一化概率分解成一系列条件概率乘积的形式。
把以上层串起来的过程便是: NNLM首先通过输入层对单词用one-hot编码转化为词向量 ,然后通过word Embedding乘以D×V的矩阵C将高维稀疏的向量映射成稠密的低维向量 ,把得到的向量拼接起来,经过隐藏层,通过softmax隐藏层输出去预测后面的单词,最终输出的是这段序列的联合概率。
缺点:神经网络语言模型当前词仍是只和前n-1个词有关,与更前面的词无关,这样仍会丢失一部分信息。
循环式神经网络语言模型(RNN):把神经网络中的隐藏层换成了神经元,与神经网络不同的是:神经元接受两个值,一个是此刻输入的单词,另一个是前一个神经元的输出,迭送输入,也就是把前一时刻的运算结果加入到当前的运算里,从而实现了与前面所有的词都有关。
运算过程:新数据和以前的数据叠加然后乘以权重W后的向量经过tanh激活函数后输出。
缺点:不能很好的处理输入中的长期依赖的信息
双向循环式神经网络(BiRNN):由上文得知RNN可以使当前词的预测与上文所有词都有关,那我们怎么能让当前词和下文的单词也有关系呢,这就是双向循环式神经网络要做的事,它在RNN的基础上添加了反向的运算,最终的结果为正向RNN和反向RNN结果的简单叠加。
长短时记忆(LSTM):长短式记忆可以很好的处理输入中的长期依赖的信息,也就是RNN的问题。长短式记忆在神经元里加入了三个门:输入门,遗忘门,输出门,用来决定让多少信息通过这些门,在这里我们插入一个长短式记忆神经元的运行图:
Xt为该时刻新加入的信息,at-1和Ct-1是上文信息的表示,Ot是输出的隐层状态,Ct,at是遗忘了某些旧信息,加入了新信息的表示,橙色圆圈是做加法和乘法运算,棕色方格是tanh,σ激活函数,σ函数的作用是把值映射到(0,1)上,而且,绝大部分的值都是十分接近0和1的。
运行过程:遗忘门:由图我们可以得知,上文的信息表示和此刻加入的信息叠加在一起(下文中就称为new),首先乘以遗忘门的权重Wf然后通过σ函数激活,遗忘了一些旧的信息,然后与Ct-1相乘,得到的Ct-1表示是一个已经遗忘了某些旧信息的上文表示。
输入门:new乘以输入门Wi的权重,然后通过σ函数激活,加入了输入Xt后的新信息,先与RNN中的运算结果相乘,再与Ct-1相加,此时的Ct-1就成为了已经遗忘了某些旧信息,又加入了此刻输入新信息的表示。此刻Ct-1已经生成了此刻的信息Ct
第三份new是进行了RNN中的运算。
输出门:new乘以输出门Wo的权重,然后通过σ函数激活,对输出内容进行限制。
若要输出内容,将Ct乘以一个tanh激活函数之后,与输出权重逐元素相乘,就得到了当前神经元的输出和at,输出的内容将会含有更多此时刻的信息,所以是具有短时记忆。
因为at与Ot相比是具有短时记忆的,而Ot是具有长期记忆的,还记忆着一些上文的剩余表示,因此这种方法被称为长短式记忆。
缺点:无法得到下文的信息
最终结果得到的是一个与句子长度相同的隐含状态序列。
双向长短式记忆(BiLSTM):前向的LSTM与后向的LSTM结合成BiLSTM,可以得到上下文的信息。最终得到的是正向隐含状态序列和反向隐含状态序列的简单叠加。
(大概可能也许是为了凑够4000字,嘿嘿,所以在这里插入一个Perplexity,用来评估一个已经训练好的语言模型的好坏,Perplexity = 2的(-x)次方(x等于每个单词概率的对数相加在除以V, V:语料库里不同词的的个数))
至此,语言模型大致讲解完毕,其实,我们自2019.10.14—2019.10.20这一周我们不仅学了语言模型,还了解了一些crf,crf++,马尔可夫模型和假设,word2vector,在以后的文章里再来解释吧,那我们就下期再见吧。