利用Kaldi和自己的语料库构建中文解码器(二)

接上,这里记录下如何构建L.fst并将其和G.fst进行合并。

1.构建L.fst

L就是lexicon,也就是字典,更准确的说是发声字典。这个字典记录了每个单词或词组对应的音素,显然这个对应关系是需要我们自己建立的。准备一个<some dir>/data/local/dict的路径,在这个路径下准备以下几个文件:

extra_questions.txt,lexicon.txt[lexiconp.txt], nonsilence_phones.txt , optional_silence.txt, silence_phones.txt

其中每个文件的用途可以参考https://blog.csdn.net/dearwind153/article/details/78563108。这里直接说下每个文件里放什么。

1.1 extra_questions.txt

里面记录了相同音素的不同语调。但是考虑到我们没有阴平阳仄,所以直接放各种拼音就行了。我这里把整体认读音节分开来了。如下:

1.2 lexicon.txt

这里面记录了每个词的发音。为了简便这里就不考虑多音字了。我们需要一个程序将之前的dict.txt加注拼音生成lexicon.txt。这里写了一个Python程序来实习。这个程序需要使用到汉字转拼音的模块xpinyin,直接pip安装即可。代码如下:

# _*_ coding=utf-8 _*_
# Sentence2Pinyin.py
from xpinyin import Pinyin

zhengtirendu = ['zhi', 'chi', 'shi', 'ri', 'zi', 'ci', 'si', 'yi', 'wu', 'yu', 'ye', 'yue',
                'yuan', 'yin', 'yun', 'ying']
danyunmu = ['a', 'o', 'e', 'ai', 'ang', 'ao', 'an', 'ou', 'ei', 'en', 'eng', 'er']
one_letter_shengmu = list('bpmfdtnlgkhjqxzcsryw')
two_letter_shengmu = ['zh', 'ch', 'sh']

with open("dict.txt", 'r') as input_file:
    with open("lexicon.txt", 'w') as output_file:
        for line in input_file.readlines():
            py = Pinyin()
            pinyin_line = py.get_pinyin(line)
            pinyin_line = pinyin_line.replace('\n', "")
            words = pinyin_line.split("-")

            word_splited = ""
            for word in words:
                if zhengtirendu.count(word) or danyunmu.count(word):
                    word_splited += word + ' '
                else:
                    scan_flag = False
                    for s in two_letter_shengmu:
                        if word.find(s, 0, 2) != -1:
                            word_splited += (s + ' ' + word[2:] + ' ')
                            scan_flag = True
                            break
                    if not scan_flag:
                        for s in one_letter_shengmu:
                            if word.find(s, 0, 1) != -1:
                                word_splited += (s + ' ' + word[1:] + ' ')
                                break

            word_splited = line[:-1] + ' ' + word_splited[:-1] + '\n'
            output_file.write(word_splited)

print("finish")

因为有lexicon.txt就不需要lexiconp.txt了,而且我也不知道怎么建立这个lexiconp.txt。记得把程序生成的lexicon.txt拷到之前的路径下。

1.3 nonsilence_phones.txt

就是把全部音素列一遍。就像这个样:

1.4 optional_silence.txt

放置特殊发音符号的,比如只放一个sil就可以

1.5 silence_phones.txt

同上,只放一个sil

到此为止构建L.fst所需的准备工作就做好了,下面开始构建。其实就是调用一个脚本叫prepare_lang.sh。将目录切换一下:

$cd <kaldia安装目录>/egs/wsj/s5

然后运行脚本:

$utils/prepare_lang.sh <some dir>/data/local/dict "<UNK>" <some dir>/data/local/lang <some dir>/data/lang

记得运行前将这几个路径建立一下。

如果像上图这样没什么报错应该就算建立好了。结束之后可以在<some dir>/data/local/lang下看到L.fst。

2.看看L.fst是什么

几乎所有的fst直接用cat都是打不开的,需要使用到fstprint 或者 fstdraw 等命令。为此可能需要将其添加进环境变量方便使用

export PATH=<kaldi 安装目录>/tools/openfst-1.6.7/src/bin:$PATH

然后就可以愉快的用fstprint看看fst张什么样了: 

 

3. 合并L.fst 和 G.fst 生成 LG.fst

首先添加环境变量:

$export PATH=<kaldi 安装位置>/src/fstbin:$PATH

 然后

$fsttablecompose L.fst G.fst | fstdeterminizestar --use-log=true | fstminimizeencoded| fstpushspecial | fstarcsort --sort_type=ilabel > LG.fst

就可以了,会在当前目录下看到生成的LG.fst。

4.后记

按理说再加上H.fst和C.fst就可以完成整个HCLG的建立,但是我卡在了C.fst的生成上,目前还没有搞明白,暂时也没有时间处理这个了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值