之前讲了结构化学习的概念,其实学习都可以看做是两个步骤,只要回答三个问题,就可以解决所有学习的task。
序列标注
现在函数input是一个sequence,output也是一个sequence(先假设两个sequence的长度一样)。如上图所示,input \(x\)是\(x_1,x_2,...,x_L\),output \(y\)是\(y_1,y_2,...,y_L\)。这个问题其实是可以用RNN解决的。
例子:词性标注(POS tagging)
POS tagging:标记一个句子中每个word的词性。
词性有很多的类别,名词下面就可以分成proper(专有名词 )、common(一般名词)。动词可以分成main(主动词),modals(情态动词)等等。
现在要做的事情就是,input 一个句子,比如“John saw the saw”,要自动标记说John是PN(专有名词 ),"saw"为V(动词),“the” 为D(限定词),“saw”为名词。
词性标注是自然语言处理中非常典型和重要的task,是许多文字理解的基石,比如要先有词性标注,后续才能比较方便地做句法分析和词义消歧,或者抽key word(一般是名词),自动检测出哪些词汇是名词的话,就可以先去掉一些不可能的词汇。
如果今天找到一个字典,告诉我们说每个词汇的词性是什么,那不就解决词性标注的问题了吗?写一个hash table,hash table告诉我们说“the”的output是“D",那词性标注的问题不就解决了吗?这里困难的点是,词性标注光靠查表是不够的,要知道一整个sequence的信息才有可能把每一个word的词性找出来。
比如“saw”这个word,可能有不同的词性。第一个“saw”是动词,第二个“saw”是名词。“saw”这个word大多数情况是动词,但是我们知道一个冠词("the")后面大概率是一个名词而不是动词,所以要把词性标注做好的话,必须考虑整个sequence的信息。
HMM
HMM的假设是,人用以下两个步骤产生一个句子:
step1:
当你想要说一句话的时候,你第一件在心里做的事情是先产生一个POS sequence,这个sequence是根据你脑中的grammar产生的(你大脑中对人类语言的理解)。
step2:
根据每一个tag(PN、V、D、N),去找一个符合tag的词汇,变成一个word sequence。文字和词性的关系可以从一个词典中得到。
脑中的grammar长什么样子呢?
HMM假设它是一个马尔科夫链,要开始说一句话的时候,
- 句首word的词性有0.5的概率是Det,0.4的概率是PN,0.1的概率是V,做一下sample(假设是PN)。
- PN word后面的word有0.1的概率是Det,0.8的概率是V,0.1的概率是end(这个词是句尾),再做一下sample(假设是V)。
- V word后继续下去......
这样就可以算出“PN V D N”的概率。
产生这个词性的sequence后,接下来就要进入第二个步骤,根据我手上的词典,根据词性看填入哪一个word。现在有一大堆word属于PN,一大堆word属于V......,那么从word 集合里面sample出一个word出来(上图箭头数字是概率)。
今天给一个sequence,就可以计算出概率。
HMM可以描述,一个词性sequence可以得到一个句子的概率。
\(x,y\)同时出现的概率是(\(y\)出现的概率)*(\(x\)出现的概率|\(y\))
step1会计算\(y\)的概率就是各个词性出现的条件概率积,这个条件概率称为转移概率。
step2会计算\(x|y\)的概率,是词性产生word的条件概率积,这个条件概率称为发射概率。
怎么算转移概率、发射概率?
这个就要从训练数据中得到,先收集一大堆的训练数据(sentence),每个sentence词汇都标注好词性了。
假如要算\(P(y_{l+1}=s'|y_l=s)\),就是(\(s\)后面接\(s'\)的次数)/(\(s\)的次数)。
要算\(P(x_l=t|y_t=s)\)(给一个词性,产生的一个词汇),就是(词性为\(s\)且输出为t的次数)/(词性是\(s\)的次数)。
有两个上面算出来的概率之后,要做什么呢?
回到原来的问题,给一个句子\(x\),要找\(y\),\(x\)是我们看得到的,而\(y\)是隐藏的,那找出\(y\)就要靠\(P(x,y)\)。
很自然的想法如上图右边所示,当已经知道\(x\)时,就是去找让\(P(y|x)\)最大的\(y\),\(P(y|x)\)可以写成\(\large \frac{P(x,y)}{P(x)}\),因为\(x\)是给定的,最后变成 \(arg \max \limits_{y\in Y}P(x,y)\)。
用HMM,要做的事情就是穷举所有的\(y\),找出让\(P(x,y)\)最大的\(\widetilde y\)。
你可能觉得穷举这件事情没办法做,假设现在有\(s\)个词性,sequnce长度是L,那有可能的\(y\)就是\(s^L\)个,这个是非常大的数量,这时候就要用维特比算法了,它的复杂度是\(O(LS^2)\)。
HMM也是结构化学习的一种方法,就要回答三个问题。
Q1:评估
- \(F(x,y)=P(x,y)=P(y)P(x|y)\)
Q2:推理
- \(\widetilde y=arg \max \limits_{y\in Y}P(x,y)\)
Q3:训练
- 找\(P(y)\)和\(P(x|y)\),从训练数据中统计
HMM会有什么问题?
在做Q2推理的时候,我们是把让\(P(x,y)\)最大的\(y\)作为output,如果我们要让HMM得到正确的结果,我们会希望正确的\(\hat y\)的\(P(x,\hat y)>P(x,y)\),但是HMM可以做到这件事情吗?HMM可能无法做到这件事情,在HMM训练中,你会发现它并没有保证可以让错误的\(y\)的\(P(x,y)\)一定是小的。
举个例子说明下:
假设从语料库统计出来,N后面接V的概率是9/10,N后面接D的概率是1/10。V词性是word a的概率是1/2,D词性是word a的概率是1,如上图右边所示。
假设有个问题是说,已经知道\(l-1\)时间点的词性是N,在\(l\)时间点word 是a,那\(y_l\)最有可能的词性是什么?
\(y_l=V\)的概率是0.9*0.5=0.45
\(y_l=D\)的概率是0.1*1=0.1
所以最有可能的词性是V
可是如果我们观察下训练数据(如上图右边所示),\(N\to V\to c\)出现9次,\(P\to V\to a\)出现9次,\(N\to D\to a\)出现1次,那么N后面接V的概率是0.9,N后面接D的概率是0.1。V产生a的概率是0.5,产生c的概率是0.5,D产生a的概率是1。
根据训练数据,告诉我们说是V,但是你不觉得有问题吗?
在训练数据里,已经告诉你\(N\to D\to a\),但是你还是预测为V,这不是很奇怪吗。
对HMM来说,它会给一些在训练数据里没出现过的sequence高的概率(例如上面例子的\(N\to V\to a)\),所以它有个特色,会脑补没有看过的东西。
就算一个\(x,y\)的pair在训练数据里没出现过,对HMM来说,也可能会给它一个高的概率。这件事情是有好有坏的,这个不一定是个缺点。
当你的训练数据很少的时候,也许实际真的概率就很高,只是你数据太少没有观察到,所以HMM在训练数据少的时候效果会好,在数据量够多的时候,效果增长没有其他方法快。
HMM为什么会产生这种脑补的现象?
因为对它来说,转移概率跟发射概率是分开的model,这两个概率是独立的,CRF可以解决这个问题,但是CRF的model和HMM是差不多的,也是假设转移概率跟发射概率是独立的,却可以克服HMM的问题。
CRF
CRF一样也要描述\(P(x,y)\),说\(P(x,y)\)正比于\(exp(w\cdot \phi(x,y))\)(一个权值向量 * 特征向量)。
- \(\phi(x,y)\)是一个特征向量
- \(w\)是从训练数据中学到的权值向量
- \(exp(w\cdot \phi(x,y))\)内积总是正的,但是没办法保证小于1,所以说是概率的话就不太对,只能说和概率是成正比的
那我们不就不知道真正的\(P(x,y)\)是什么了吗?
没关系,CRF不关心\(P(x,y)\),真正关心的是\(P(y|x)\),\(P(y|x)\)可以写成上图的式子。\(P(x,y)\)和\(exp(w\cdot \phi(x,y))\)是成正比的,相当于\(\Large \frac{exp(w\cdot \phi(x,y))}{R}\),然后代入\(P(y|x)\)式子里面去,如上图所示,消去\(R\)。
你可能会奇怪,为什么概率会正比于两个向量的内积,跟HMM完全不一样
其实CRF和HMM的model是一样的,只有在训练上是不一样的。在HMM里面,\(P(x,y)\)是一大堆概率乘积, 现在对它取log,原来相乘变为相加。
先看上图红色框框这一项,整个句子长度是\(L\)的话,就是\(log P(x_l|y_l)\) 的和,把这一项做下整理,写成上图下方的式子,summation over所有的tag s跟word t,如果有10个可能的词性和10000个词汇,那这里就是summation 10*10000项。每一项是(\(log P(t|s)\))\(\times\)(词汇\(t\)被标注为\(s\)这件事情在pair \(x,y\)总共出现的次数)。
举个例子:有一个sentence x “The dog ate the homework”,每一个word都有一个tag的label。
现在做一下计算如上图右边所示:
- “the”被标记为D(冠词),在这个(x,y) pair出现的次数为2次。
- “dog”被标记为N(名词)的次数为1次。
- “ate”被标记为V(动词)的次数为1次。
- “homework”被标记为N(名词)的次数为1次。
- 其他词汇和词性的次数为0次。
计算下所有的概率的乘积如上图下方所示。D产生“the”的概率出现过2次,值是一样的。随后整理下就变成\(log P()\times N()\)。
对其他项也可以做一样的转化,如上图最下方所示。
写成相乘以后会怎么样呢?
可以发现说,可以把\(log P(x,y)\)写成一大堆两项的相乘,四项分别是
- summation over所有的tag跟word
- summation over所有的tag
- summation over所有的tag和tag
- summation over所有的tag
然后就可以描述成两个向量的内积,如上图右边所示。红色向量里每个元素都跟\((x,y)\)有关,是\((x,y)\)所形成的feature,写成\(\phi(x,y)\),最后得到\(log P(x,y)=w\cdot \phi(x,y)\),也就是\(P(x,y)=exp(w\cdot \phi(x,y))\)。
这边有个地方要稍微注意下,\(w\)向量可以对应到HMM里的概率
-
也就是\(w_{s,t}\)对应到 \(log P(x_i=t|y_i=s)\) (词性s时为word t的概率)
-
或者是\(w_{start,s}\)对应到 \(log P(s|start)\) (句首是s概率)
-
或者是\(w_{s,s'}\)对应到 \(log(P(y_i=s'|y_{i-1}=s))\)(\(y_{i-1}=s\)后面接\(s'\)的概率)
-
......
也就是今天\(w\)里面,每一个weight都对应到HMM里的某个概率取 log,如果想转回概率的话,就把\(w\)取exp。
这边有一个问题,在训练的时候,\(w\)里面的值是可正可负的,值是负的话,取exp的值是小于1的,可以解释为一个概率,但是如果exp大于1的话,就不能解释为概率了。还有就是given s(tags)后对t(word) summation ,没有办法保证和是1 (因为\(P(x_i=t|y_i=s)\)取了log)。所以没办法说\(P(x,y)=exp(w\cdot \phi(x,y))\) ,于是就改成正比。
特征向量\(\phi(x,y)\)长什么样子呢?
\(\phi(x,y)\)包含两个部分
- 第一个部分是有关tag(词性)和word(词汇)的关系
- 第二个部分是有关tag(词性)和tag(词性)之间的关系
先看第一个部分,如上图右边的向量。意思是说,如果有\(S\)个tag,有\(L\)个可能的词汇,那向量维度就是\(S\times L\),例如有10种词性,10000个可能的词汇,那向量的长度就是100000维。
向量里面是所有词性跟所有词汇的pair,今天如果给一个(x,y)的pair,“the”标示为D出现2次的话,那向量维度D,the就对应2,没出现的pair都是0。可以想象这个向量的维度非常大,但有值的地方可能很少(稀疏)。
在第二个部分,做法是这样子的
定义\(\large N_{s,s'}(x,y)\)是tag s跟s'在(x,y)这个pair里面连续出现的次数。所以\(N_{D,D}(x,y)\)就是D后面接D在(x,y)这个pair里面出现的次数。在这个例子里,D和D没有接在一起过,所以次数为0,D后面接N出现过2次.......。
假设世界上tag的数目有S种,那向量维度就是\(S\times S+2S\),词性配词性+start和end。
然后把part1和part2的向量接在一起作为\(\phi(x,y)\),这个向量有它自己的含义,跟HMM想要model的东西是一样的。但是CRF把概率描述成\(w\)和\(\phi(x,y)\)的内积,所以CRF比HMM多了一个厉害的地方,就是你可以自己定义\(\phi(x,y)\) 。
怎么训练CRF?
收集训练数据\(\{(x,\hat y) \}\)
找一个权值向量\(w^*\)去最大化一个目标函数\(O(w)\),目标函数是说,给定\(x^n\)产生正确\(\hat y^n\)的概率取log再summation 。你会发现和交叉熵很像,交叉熵也是最大化正确维度的几率再取对数,只不过此时是针对整个序列而言的。给定一整个sequence x,我们要让正确的sequence的概率的log越大越好。
log这一项做下转化,如上图最下方所示,由\(\Large P(y|x)=\frac{P(x,y)}{\sum\limits_{y'}P(x,y')}\)进行考虑。那么最大化\(log P(\hat y^n|x^n)\)相当于:
- 最大化\(\large log P(x^n,\hat y^n)\),最大化在训练数据里看到的pair \(\large (x^n,\hat y^n)\) 的概率
- 同时最小化\(\large log \sum\limits_{y'}P(x^n,y')\),最小化训练数据没有看到的pair的概率
这边是最大化,而不是最下化,随意用梯度上升法。
梯度下降里,最小化代价函数\(C\),计算\(C\)的梯度,然后\(\theta\)减去 \(\eta \nabla C(\theta)\)(即往负梯度方向走)。
梯度上升了,是\(\theta\)加上\(\eta \nabla C(\theta)\)(即往梯度方向走)。
上图\(O(w)\)是我们要去最大化的函数,定义\(log P(\hat y^n|x^n)\)是\(O^n(w)\)。
我们\(w\)有很多很多,有的\(w\)对应到一个tag和一个word的pair,有的\(w\)是对应两个tag的pair。接下来会讲解\(\Large \frac{\partial O^n(w)}{\partial w_{s,t}}\),其他偏微分是类似的。
经过一顿数学运算后,最后对\(w_{s,t}\)求得的梯度有两项
- 第一项是word t被标识为tag s,在pair \((x^n,\hat y^n)\)中出现的次数
- 第二项是,summation over所有可能的\(y\) ,summation 中每个term是(word t被标识为tag s在\(x^n\)跟任意一个\(y\)的pair中出现的次数)乘上 (给定\(x^n\)后任意一个\(y\)的概率),\(y\)是所有可能出现的sequence,所以非常多。
算出来偏微分的结果,是要跟\(w_{s,t}\)做相加,绿色和黄色项是互相对抗的
-
看上图绿色线第一项,如果算出来是正的,参数就会增加,算出来是负的,参数就会减少。这个式子告诉我们,如果\(s,t\)这个pair在正确的训练数据\((x^n,\hat y^n)\)中出现的次数越多,那\(w_{s,t}\)就会越大。
-
黄色线第二项告诉我们,如果\(s,t\)这个pair在任意一个\((x^n,y)\)pair里出现的次数很多的话,那\(w_{s,t}\)应该变小
如果\(s,t\)在正确答案里出现的很多,那对应的\(w_{s,t}\)就会增加,但是如果不只是在正确答案里出现的次数多,在随便哪个\(y\)跟\(x^n\)pair里出现的次数也多的话,就应该减小\(w_{s,t}\)。
今天你要在第二项(黄色项)summation over所有可能的\(y\),可能会卡住,不知道怎么算。但没有关系,这个也可以用维特比算法算。
之前是算了某一个\(w\)的偏微分,现在对整个\(w\)的偏微分向量就是(正确的$\hat y \(形成的特征向量)\)-\((任意\)y'\(形成的特征向量*\)y'$的条件概率)。
如果我们把随机梯度上升的式子列出来的话
-
每次都取一笔数据\((x^n,\hat y^n)\)
-
把正确\(\hat y\)形成的向量加给\(w\),再减掉(任意一个\(y\)形成的向量*\(y\)的条件概率,每个\(y\)的条件概率都不一样)
把\(w\)向量算出来后,就可以做Q2:推理了。
我们知道现在要做的事情是,给一个\(x\),找一个\(y\)让\(P(y|x)\)最大,在HMM里已经知道,等同于最大化\(P(x,y)\) 。在CRF里又知道,\(P(x,y)\)是正比于\(exp(w\cdot \phi(x,y))\),代进去等同于是最大化\(w\cdot \phi(x,y)\),也可以用维特比算法做。
CRF VS HMM
CRF的训练过程中,不只会增加\(P(x,\hat y)\),还会减少任意一个\(y\)和\(x\)形成pair的概率,而HMM并没有减少概率这件事情。我们知道说,如果要得到正确的答案,会希望\(P(x,\hat y)>P(x,y)\) ,CRF是增加\(P(x,\hat y)\),减小\(P(x,y)\),所以CRF更有可能得到正确的结果。
举例来说,用之前HMM的例子,根据训练数据,HMM给了如上图左下方所示的结果(直接统计来的),HMM说\(y_i\)应该是V。但是CRF不关心概率,就是调整\(w\)参数使得正确的\((x,y)\)pair的分数比较大。所以CRF可能调来调去,使得\(P(a|V)\)到0.1,使得\(y_i\)可能是D。
以下是一个综合的实验,比较CRF和HMM有什么不一样。
在这个实验里面,input是小写的\(a\)到\(z\) ,output是大写的\(A\)到\(E\)。然后我们要生成一些人工数据,这些数据使用HMM生成的,但用的不是一般的HMM,用的是一个mixed-order HMM。
- 转移概率是:\(\alpha P(y_i|y_{i-1})+(1-\alpha)P(y_i|y_{i-1},y_{i-2})\),如果\(\alpha=1\),则后面一项是0,就是一般的HMM的转移概率。今天\(\alpha\)的值可以任意调整,考虑一个order的比率大,还是两个order的比率大。
- 发射概率是:\(\alpha P(x_i|y_i)+(1-\alpha)P(x_i|y_i,x_{i-1})\),如果\(\alpha=1\),也就是一般的HMM。
比较HMM和CRF(都是一般的HMM和CRF),HMM只考虑一个order(\(\alpha=1\)的状况) 。
一般而言,如果\(\alpha\)越小,那么跟一般的HMM和CRF差距越大,得到的performance越差。但是我们想要知道在这种情况下,到底是HMM坏得比较厉害,还是CRF坏得比较厉害。
上图是实验的结果,每个圈圈是不同的\(\alpha\)得到的结果。从左下到右上代表\(\alpha\)由大到小,每个点都做HMM和CRF的实验,横轴和纵轴代表HMM和CRF犯错的百分比。
可以想象如果一个点在45度角的右侧,代表说HMM犯得错多,CRF犯得错少。从实验结果可以发现,非实心的点是\(\alpha > \frac{1}{2}\),接近一般的HMM或者CRF,在这个状况下HMM是比CRF好的,也不用意外,因为数据是从HMM产生的,所以HMM的假设更贴近数据的产生方式。\(\alpha < \frac{1}{2}\)时,也就是数据的产生方式和HMM、CRF的假设都不合时,这时候CRF就会比HMM好。因此此时HMM只能按照概率,而CRF会调整参数去fit数据,就算有些假设没有被model在CRF里面,也可以借由调整参数考虑到这些假设,所以当你的模型和数据背后的假设不合时,CRF的表现就会比较好。
上图是CRF的总结。CRF也是一个结构化学习的方法,解决了3个问题。
Q1:评估
- \(F(x,y)\)是\(P(y|x)\),可以写成上图所示的式子
Q2:推理
- 找使\(w\cdot \phi(x,y)\)最大的\(\widetilde y\),利用维特比算法求解
Q3:训练
- 一般文献是写成相乘,但是也可以取log,变成相加。使用梯度上升求解\(w\)。
结构化感知机
Q1:评估
\(F(x,y)=w\cdot \phi(x,y)\)
你可以会说,如果\(x,y\)都是sequence的话,这个\(\phi()\)应该定成什么样子?
可以选择自己喜欢的方式,最简单的方式就是拿CRF的形式做就好了。
Q2:推理
一样使用维特比算法求解。
Q3:训练
对所有的训练数据\(n\),和所有不等于\(\hat y\)的\(y\),我们希望让\(w\cdot \phi(x^n,\hat y^n)\)大于\(w\cdot \phi(x^n,y)\)。这件事在结构化感知机里,我们会找一个\(\widetilde y\)(根据目前的\(w\),让式子最大)。接下来更新\(w\)(如上图最下方所示)。
你有没有觉得结构化感知机\(w\)更新很眼熟呢,和CRF的梯度上升很像?
在CRF梯度上升里,如果忽略掉\(\eta\)(学习率),那跟结构化感知机一样都有两项(绿色线项和紫色线项)。绿色项是一样的,紫色项虽然看起来不一样,但其实是很有关系的。CRF里是summation over所有的\(y\)的特征向量,再做weight sum,结构化感知机里则是某一个\(\widetilde y\)的特征向量,而\(\widetilde y\)可以让\(w\cdot \phi(x^n,y)\)最大,\(\widetilde y\)其实就是让概率\(P(y|x^n)\)最大\(y\)。
- 在CRF里,减去所有\(y\)的特征向量的weight sum
- 在结构化感知机里,减去令weight (\(P(y|x^n)\) )最大的\(y\)的特征向量
所以结构化感知机是减去Hard(硬范畴),而CRF是Soft(软范畴)。可以想象说,如果所有\(y\)里面,只有一个\(y\)是概率为1的,其他\(y\)概率都是0,那么结构化感知机和CRF就是等价的。
结构化SVM
结构化SVM的Q1和Q2都跟结构化感知机的一样的,唯一不同的地方是训练的方式。在SVM里面,我们会加上margin和error的概念,有两个方法求解,一个是梯度下降,另一个是切割平面算法。
结构化SVM里面有个特别的地方,是要考虑error这件事情。我们把误差函数写成\(\Delta(\hat y^n,y)\),
-
计算\(y\)和正确的\(\hat y\)之间不一样的程度(\(y,\hat y\)之间的差异性)。
-
结构化SVM的成本函数是\(\Delta(\hat y^n,y)\)的上界,所以最小化成本函数相当于最小化\(\Delta(\hat y^n,y)\)
-
理论上,\(\Delta(\hat y^n,y)\)可以是任何函数
-
但是,必须考虑,今天再使用结构化SVM的时候,不管是使用梯度下降,还是使用切割平面算法,都要面对一个问题2.1(穷举所以\(y\)让\(\Delta(\hat y^n,y)+w\cdot \phi(x^n,y)\)最大),这个不一定解得出来,如果\(\Delta\)定得比较复杂的话。上图最下方是一个可以解的例子,如果把两个sequence之间的\(\Delta\)定义成错误率的话(不一样label个数/sequence长度),这样就可以解。
不同方法的比较
上图是不同方法在POS Tagging上实验的比较。发现HMM的表现是最差的,CRF是橙色的线,感知机是灰色的线,CRF和感知机区别就是一个是硬范畴,一个是软范畴,谁好谁坏不好定义,但是CRF有个问题是要summation over所有\(y'\),这件事情你不一定知道要怎么解,不知道怎么解就用感知机好了,图中SVM是最好的。
上图下方是另外一个实验,(命名实体识别),发现SVM是表现最好的。
为什么不用RNN
刚才讲的这种序列标注的问题,你可以用RNN,LSTM来解,也可以用HMM、CRF、结构化感知机和SVM来解。那到底哪一个比较好呢?
RNN,LSTM
- 有个缺点是,如果你用的是单向RNN或者LSTM的话,并没有看过整个sequence。也就是在单向RNN里,产生第\(t\)个时间点的output时,你只考虑了时间1到时间t的input,没有考虑时间t+1到时间T的input。那用双向RNN会怎么样呢?还没有在文献上看到过,双向RNN跟用维特比算法算出来的结果,有什么差异。
- RNN、LSTM有足够的的训练数据,或许可以把label依赖关系学习出来。
- 还有个问题是cost和你要的error不见得是有关系的。比如我们希望错误率最低,训练RNN的时候是最小化cost函数,最小化cost函数不一定能降低错误率。
- 有个传统方法无法比拟的优点,就是可以deep(叠很多层)
HMM、CRF、结构化感知机/SVM
- 在产生结果的时候,都是做维特比算法(穷举所有的sequence,看哪个最可能),在计算分数的时候是看过整个sequence的,这个和单向RNN不同。
- 可以明确地考虑output的sequence,label跟label之间的关系。假设你今天知道output的sequence里面,a跟b这两个元素不可能同时出现,你可以轻易的把这件事情塞到维特比算法中去。比如语音识别里面,中文都是声母接韵母,声母后面不能再接声母,那你可以把这种约束塞到维特比算法中去。在做维特比算法时,一边穷举所有的sequence,一边过滤掉不可能的sequence。比如只穷举声母接韵母的sequence,丢掉声母接声母的sequence。 这样就可以把sequence里面的label的依赖关系明确地描述在我们的model里面。
- 如果使用结构化SVM,那你最小化的cost函数就是要的错误函数的上界,让你觉得训练的时候比较安心,当你的cost函数逐渐减小的时候,你的error很有可能也是逐渐减小的。
虽然传统方法有很多有点,但还是RNN、LSTM表现好。
把传统方法和深度学习整合在一起
可以把深度学习方法和传统方法加起来。
model的底层是RNN、LSTM,可以deep。model的浅层可以使HMM、CRF、结构化感知机/SVM,可以发挥它们的优势(可以明确描述依赖关系,使用结构化SVM的话,cost函数还是error的上界。现在基本上好的方法就是底层架构是deep的方法。
以语音识别举例,如上图所示。
根据HMM的model,\(P(x,y)\)如上图所示的公式。把HMM的\(P(x_l|y_l)\)用DNN、RNN、LSTM得到的结果替换。RNN或DNN可以把一个input \(x_l\)变成一个概率的分布(\(P(a|x_l),P(b|x_l),P(c|x_l)...\)),可以把这个概率分布替换掉HMM的\(P(x_l|y_l)\)。
可能你会觉得HMM是给定\(y\),而RNN里是给定\(x\),方向不一致,但可以做一下改变,如上图右下方所示。\(P(y_l|x_l)\)就是RNN的output,\(P(y_l)\)是label出现的概率(直接从训练数据统计),还有\(P(x_l)\),训练数据每个特征都只有一个啊,怎么计算概率呢?就不要管它,真正在用HMM做Q2推理的时候,是给定\(x\),看哪个\(y\)最有可能,不管\(x\)的值是多少,都不会影响最后得到的\(y\)。
或者你可以把单向RNN/LSTM加上CRF/结构化SVM,这种方法在序列标注、语义标注这种task里面是非常常见的。
可以把input的特征通过deep的RNN,得到一组新的特征,在新的特征上抽\(\phi(x,y)\)(\(x\)是RNN的output),然后把\(w\cdot \phi(x,y)\)作为评估函数。在训练的时候可以把\(w\)跟RNN的参数一起训练。
最后是今天的结论,讲了好几种不同的可以处理序列标注的方法,它们都解了三个问题。