美文网首页
Ngram 语言模型

Ngram 语言模型

作者: 期望最大化 | 来源:发表于2019-07-08 15:21 被阅读0次

    参考资料

    http://52opencourse.com/111/%E6%96%AF%E5%9D%A6%E7%A6%8F%E5%A4%A7%E5%AD%A6%E8%87%AA%E7%84%B6%E8%AF%AD%E8%A8%80%E5%A4%84%E7%90%86%E7%AC%AC%E5%9B%9B%E8%AF%BE-%E8%AF%AD%E8%A8%80%E6%A8%A1%E5%9E%8B%EF%BC%88language-modeling%EF%BC%89
    吴军,《数学之美》第3章:统计语言模型
    http://www.speech.sri.com/projects/srilm/
    Stanley F. Chen and Joshua Goodman. An empirical study of smoothing techniques for language modeling. Computer Speech and Language, 13:359-394, October 1999.
    http://www.speech.sri.com/projects/srilm/manpages/ngram-discount.7.html

    目标

    熟悉语言模型相关的知识、训练流程
    能够完成和语言模型相关的工作。

    前置问题

    什么是语言模型,语言模型可以用来做什么

    语言模型刻画词序列概率大小。任何需要词汇序列概率大小的地方都可以用到语言模型,比如:
    机器翻译:P(high winds tonite) > P(large winds tonite)
    拼写纠错:P(about fifteen minutes from) > P(about fifteen minuets from)
    语音识别:P(I saw a van) >> P(eyes awe of an)
    音字转换:P(你现在干什么|nixianzaiganshenme) > P(你西安在干什么|nixianzaiganshenme)
    自动文摘、问答系统、中文分词... ...

    语言模型如何训练和评估

    训练就是数数加平滑,评估主要用ppl和实际应用中的指标,如WER。主要工具是srilm中的ngram-count和ngram

    语言模型如何用于语音识别

    声学模型出来是一系列词汇序列。语言模型就是对这些词汇序列再加上语言模型得分,选出最合理的一句话。实际kaldi中:

    • arpa语言模型利用arpa2fst转换成G.fst,
    • 然后与L_disambig.fst(词典转换得到)、ilabels_${N}_${P}(三音素上下文)、Ha.fst 构图得到HCLG.fst。
    • 解码过程中,来了一帧语音计算各个pdf-id(有限的,HCLG网格图能够到达的)概率,然后根据HCLG.fst,得到下一帧pdf-id集合。也就是说HCLG.fst起到了一个网格限制的作用,限制了从一个pdf-id只能到有限的pdf-id。

    什么是语言模型,语言模型可以用来做什么

    语言模型刻画词序列概率大小,假如一个词序列用S表示,那么如何确定该词序列概率呢,用链式法则:
    p(S) = p(w_1,w_2,w_3,w_4,w_5,…,w_n)
    p(S) = p(w_1)p(w_2|w_1)p(w_3|w_1,w_2)...p(w_n|w_1,w_2,...,w_{n-1}) //链式法则
    p(S) = p(w_1)p(w_2|w_1)p(w_3|w_1,w_2)...p(w_n|w_{n-2},w_{n-1}) //只看前两个,也就是3gram
    取其中任意一个为例:
    p(w_n|w_{n-2},w_{n-1}) = \frac {p(w_{n-2},w_{n-1},w_{n})}{p(w_{n-2},w_{n-1})} //条件概率
    = \frac {count(w_{n-2},w_{n-1},w_{n})}{count(w_{n-2},w_{n-1})} //大数定理
    也就是说,要想得到一个ngram条件概率,只需要统计count数目,然后相除就可以了。
    问题:这种极大似然统计,会导致训练集中没有出现的ngram概率为0。实际中,很多测试集中ngram在训练集中都没有出现过。
    解决办法:数据平滑。看见事件概率分一部分出来,给将来的未看见的事件。

    数据平滑
    设计到两个问题:
    • 一个是如何"切蛋糕",哪些ngram概率需要减少,具体减少多少?
    • 一个是"分配切出来的蛋糕",这些概率分配给哪些没出现的ngram,分配多少?
      常用的数据平滑策略是Good-Turing discount + Katz backoff
      Good-Turing discount

    各种discount方法公式计算见:
    Ngram discount计算

    语言模型如何训练和评估

    srilm中训练lm的工具是ngram-count,评估lm的工具是ngram,常用命令包括训练、ppl计算、插值、裁剪,分别为:

    • ngram-count -order 3 -vocab momo.dic -text train.txt -lm lm.3gram
    • ngram -lm lm.3gram -order 3 -ppl test.txt -debug 2 >ppl.txt
    • ngram -order 3 -lm lm.3gram.base -mix-lm lm.3gram -lambda 0.7 -write-lm lm.mix7v3.150M
    • ngram-prune -order 3 -lm lm.mix7v3.150M -write-lm lm.mix7v3.70M -size 7e+07 (仿照ngram prune实现的工具,size参数后面是最终语言模型ngram数目)

    除此之外,常用的语言模型开源工具还有kenLM,kaldi中也有训练lm的工具。

    评估主要有两个指标:

    • 困惑度(PerPLexity,PPL)
      ppl = p(S)^{-\frac{1}{N}} 实际计算中通常得到的是logp(S)值,转换后如下
      ppl = 10^{-\frac{1}{N} logp(S)}
      N: 句子中词的个数。ppl计算中包括</s>,ppl1中计算不包括</s>,所有N要少1,ppl1比ppl要大不少
    • 实际应用中的指标,如语言模型用于语音识别,就可以用语音识别中词错误率来评估(Word Error Rate,WER)
      WER = \frac{错误词的个数}{标注中词的个数}
      错误词类型包括替换错误Sub,删除错误Del,插入错误Ins。由于插入错误的存在,WER有可能大于100%。除了WER,还有句子错误率SER。

    FAQ

    srilm工具中如何编写自己的程序?

    • 进入lm/src 目录,cp ngram-count.cc ngram-count-example.cc, 修改 ngram-count-example.cc;
    • 修改Makefile文件,REAL_PROGRAM_NAMES 部分增加ngram-count-example
    • 返回srilm目录,make 得到srilm/lm/bin/i686-m64/count-example 可执行程序。

    实际make过程包括:

    • g++ -march=athlon64 -m64 -Wall -Wno-unused-variable -Wno-uninitialized -DINSTANTIATE_TEMPLATES -fopenmp -I. -I../../include -c -g -O0 -o ../obj/i686-m64/LM.o LM.cc

    • ar ruv ../obj/i686-m64/liboolm.a ../obj/i686-m64/matherr.o ../obj/i686-m64/Prob.o ../obj/i686-m64/Counts.o ../obj/i686-m64/XCount.o ../obj/i686-m64/Vocab.o ../obj/i686-m64/VocabMap.o ../obj/i686-m64/VocabMultiMap.o ../obj/i686-m64/VocabDistance.o ../obj/i686-m64/SubVocab.o ../obj/i686-m64/MultiwordVocab.o ../obj/i686-m64/TextStats.o ../obj/i686-m64/LM.o ../obj/i686-m64/LMClient.o ../obj/i686-m64/LMStats.o ../obj/i686-m64/RefList.o ../obj/i686-m64/Bleu.o ../obj/i686-m64/NBest.o ../obj/i686-m64/NBestSet.o ../obj/i686-m64/NgramLM.o ../obj/i686-m64/NgramStatsInt.o ../obj/i686-m64/NgramStatsShort.o ../obj/i686-m64/NgramStatsLong.o ../obj/i686-m64/NgramStatsLongLong.o ../obj/i686-m64/NgramStatsFloat.o ../obj/i686-m64/NgramStatsDouble.o ../obj/i686-m64/NgramStatsXCount.o ../obj/i686-m64/NgramProbArrayTrie.o ../obj/i686-m64/NgramCountLM.o ../obj/i686-m64/MSWebNgramLM.o ../obj/i686-m64/Discount.o ../obj/i686-m64/ClassNgram.o ../obj/i686-m64/SimpleClassNgram.o ../obj/i686-m64/DFNgram.o ../obj/i686-m64/SkipNgram.o ../obj/i686-m64/HiddenNgram.o ../obj/i686-m64/HiddenSNgram.o ../obj/i686-m64/VarNgram.o ../obj/i686-m64/DecipherNgram.o ../obj/i686-m64/TaggedVocab.o ../obj/i686-m64/TaggedNgram.o ../obj/i686-m64/TaggedNgramStats.o ../obj/i686-m64/StopNgram.o ../obj/i686-m64/StopNgramStats.o ../obj/i686-m64/MultiwordLM.o ../obj/i686-m64/NonzeroLM.o ../obj/i686-m64/BayesMix.o ../obj/i686-m64/LoglinearMix.o ../obj/i686-m64/AdaptiveMix.o ../obj/i686-m64/AdaptiveMarginals.o ../obj/i686-m64/CacheLM.o ../obj/i686-m64/DynamicLM.o ../obj/i686-m64/HMMofNgrams.o ../obj/i686-m64/WordAlign.o ../obj/i686-m64/WordLattice.o ../obj/i686-m64/WordMesh.o ../obj/i686-m64/simpleTrigram.o ../obj/i686-m64/LMThreads.o ../obj/i686-m64/MEModel.o ../obj/i686-m64/hmaxent.o ../obj/i686-m64/NgramStats.o ../obj/i686-m64/Trellis.o 2>&1 | c++filt

    • g++ -march=athlon64 -m64 -Wall -Wno-unused-variable -Wno-uninitialized -DINSTANTIATE_TEMPLATES -fopenmp -I. -I../../include -c -g -O0 -o ../obj/i686-m64/ngram-count-example.o ngram-count-example.cc

    • g++ -march=athlon64 -m64 -Wall -Wno-unused-variable -Wno-uninitialized -DINSTANTIATE_TEMPLATES -fopenmp -I. -I../../include -u matherr -L../../lib/i686-m64 - g -O0 -o ../bin/i686-m64/ngram-count-example ../obj/i686-m64/ngram-count-example.o ../obj/i686-m64/liboolm.a ../../lib/i686-m64/libflm.a ../../lib/i686-m64/libdstruct.a ../../lib/i686-m64/libmisc.a ../../lib/i686-m64/libz.a -lm -lpthread 2>&1 | c++filt

    简单来说就是:
    重新编译LM.o;
    重新生成liboolm.a静态库;
    编译生成ngram-count-example.o;
    链接生成ngram-count-example

    训练语料很大时如何训练语言模型

    语料分片统计ngram-count,然后混合训练语言模型
    直接用并行方式训练。自己写一个MapReduce hadoop程序;

    srilm源码解读

    如何对解码出来的lattice重新打分

    相关文章

      网友评论

          本文标题:Ngram 语言模型

          本文链接:https://www.haomeiwen.com/subject/zqnnhctx.html