Kaldi语音识别技术(二) ----- 完成数据的准备

本章节主要完成数据的准备部分

一、环境准备

在之前章节我们已经基于CentOS7编译好了Kaldi 具体可见 http://t.csdn.cn/dnmkF ✔如果你不想自己编译,可以点击 下载克隆文件 (基于VMware16.2.x 的虚拟机磁盘)

实践主要基于 kaldi里面的 aishell1 示例,所以需要准备以下数据

AISHELL-1_sample 数据集: https://yxn4065.lanzouv.com/b027veq2d 密码:7dvolexicon.txt 词典 :https://yxn4065.lanzouv.com/b027veq2d 密码:7dvo

Xshell7 安装配置好,pycharm可根据自身情况选择

二、完成训练数据准备

我的kaldi根目录为/root/kaldi/kaldi/,而/root/kaldi/是我后面进行各种操作的目录,不要搞混了.

在/root/kaldi/ 目录下 新建文件夹 如下图 本机启动cmd窗口 使用scp命令上传文件,命令示例如下(自己ip地址不同)

scp ./AISHELL-1_sample root@192.168.242.129:/root/kaldi/data/

scp ./lexicon.txt root@192.168.242.129:/root/kaldi/data/dict

合并文件并重命名

cd ~/kaldi/data

mv AISHELL-1_sample S0

cd S0

mv S0150/* ./ && mv S0252/* ./ && rm -rf S0150 S0252

data 文件结构 如下图所示 4. 使用path.sh 文件 准备环境

cp /root/kaldi/kaldi/egs/wsj/s5/utils/path.sh /root/kaldi/utils/

# 更改 path.sh 里面的kaldi路径

vim /root/kaldi/utils/path.sh # 打开文件更改第一行为kaldi根目录位置

export KALDI_ROOT=`pwd`../kaldi

:wq 保存退出

# 刷新变量

. /root/kaldi/utils/path.sh

输入fst 按2次 tab 看环境是否配置成功,配置成功如下

三、生成四个数据文件

这里使用python进行文件处理,具体内容不详细展开了,直接放代码,所有代码放在/root/kaldi/utils路径下面

生成 wav.scp

# -*- coding: utf-8 -*-

# @Author : yxn

# @Date : 2022/10/22 17:11

# @IDE : PyCharm(2022.2.3) Python3.9.13

"""

wav.scp wav_id --- wav_path 音频id对于音频路径

"""

import os

def sava_data(data, filename):

"""保存文件函数"""

with open(os.path.join(save_path, filename), 'w', encoding="utf-8") as f:

for i in data:

f.writelines(i[0] + " " + i[1] + "\n")

print("%s Saving succeeded!" % filename)

def get_wav_scp():

"""该函数用于生成wav.scp"""

wav_scp = [] # 存放wav_scp 的数据

# 遍历音频

for file_name in os.listdir(data_path):

# 判断后缀名是否为wav

if file_name[-3:] == "wav":

wav_scp.append([file_name.split(".")[0], os.path.join(data_path, file_name)])

# 保存到文件

sava_data(wav_scp, "wav.scp")

if __name__ == '__main__':

# 数据文件存放路径

data_path = "/root/kaldi/data/S0/"

# 保存的路径

save_path = "/root/kaldi/kaldi_file/"

# 生成wav.scp

get_wav_scp()

生成 utt2spk

# -*- coding: utf-8 -*-

# @Author : yxn

# @Date : 2022/10/22 17:11

# @IDE : PyCharm(2022.2.3) Python3.9.13

"""

wav_id --- speaker_id 音频文件名对应说话人id

"""

import os

def save_data(data, filename):

"""保存文件"""

with open(os.path.join(save_path, filename), "w", encoding="utf-8") as f:

for i in data:

f.writelines(i + "\n")

print("%s Saving succeeded!" % filename)

def get_utt2spk():

"""生成utt2spk"""

utt2spk = []

for filename in os.listdir(data_path):

if filename[-3:] == "wav":

utt = filename.split(".")[0] # 音频id

spk = utt[-10:-5] # 说话人id

utt2spk.append(utt + " " + spk)

# 保存文件

save_data(utt2spk, "utt2spk")

if __name__ == '__main__':

# 数据文件存放路径

data_path = "~/kaldi/data/S0/" # /root/kaldi/data/S0/

# 保存的路径

save_path = "~/kaldi/kaldi_file/" # /root/kaldi/data/kaldi_file/

# 生成utt2spk

get_utt2spk()

生成 spk2utt

# -*- coding: utf-8 -*-

# @Author : yxn

# @Date : 2022/10/22 17:11

# @IDE : PyCharm(2022.2.3) Python3.9.13

"""

speaker_id --- wav_id 说话人id对应音频文件名

"""

import os

def save_data(data, filename):

"""保存文件"""

with open(os.path.join(save_path, filename), "w", encoding="utf-8") as f:

for i in data:

f.writelines(i + "\n")

print("%s Saving succeeded!" % filename)

def get_spk2utt():

"""生成spk2utt"""

spk2utt = {}

for filename in os.listdir(data_path):

if filename[-3:] == "wav":

utt = filename.split(".")[0] # 音频id

spk = utt[-10:-5] # 说话人id

if spk in spk2utt:

spk2utt[spk].append(utt)

else:

spk2utt[spk] = []

# {'S0150': ['BAC009S0150W0002', 'BAC009S0150W0003',...'BAC009S0252W0500'],

# 'S0252': ['BAC009S0252W0002', 'BAC009S0252W0003',... 'BAC009S0252W0500'] }

write_spk2utt = []

for key in spk2utt.keys():

write_spk2utt.append(str(key) + " " + " ".join(spk2utt[key]))

# 保存到文件

save_data(write_spk2utt, "spk2utt")

if __name__ == '__main__':

# 数据文件存放路径

data_path = "~/kaldi/data/S0/" # /root/kaldi/data/S0/

# 保存的路径

save_path = "~/kaldi/kaldi_file/" # /root/kaldi/data/kaldi_file/

# 生成spk2utt

get_spk2utt()

生成 text

# -*- coding: utf-8 -*-

# @Author : yxn

# @Date : 2022/10/22 17:10

# @IDE : PyCharm(2022.2.3) Python3.9.13

"""

wav_id --- wav内容 语音id->语音的内容 eg:BAC009S0150W0001 设定 二十九 度

"""

import os

import re

import jieba

def jieba_segment(data):

"""对数据进行相关处理并分词"""

# 所有小写转大写

data.replace(".", "点")

data.replace("1", "一")

data.replace("2", "二")

data.replace("3", "三")

data.replace("4", "四")

data.replace("5", "五")

data.replace("6", "六")

data.replace("7", "七")

data.replace("8", "八")

data.replace("9", "九")

data.replace("10", "十")

# 纯数字不分词

if sum([True for i in data if

i in ["零", "一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "幺"]]) == len(data):

return " ".join(data)

else:

# 调用jieba库进行处理

return " ".join(jieba.lcut(data)).replace(" ", " ")

def data_processing(text):

"""对单行文本进行分词处理后返回"""

# 1.使用正则表达式进行处理 去掉括号等特殊字符

re_text = re.findall('[\u4e00-\u9fa5a-zA-Z0-9. ]+', text, re.S)

re_text = "".join(re_text) # 将正则后列表转为字符串

# 2.进行jieba分词后返回

return jieba_segment(re_text)

def get_text():

data = []

"""得到text"""

for file_name in os.listdir(data_path):

# 判断后缀名是否为txt

if file_name[-3:] == "txt":

# 打开对应的文本

with open(os.path.join(data_path, file_name), "r") as f:

for line in f.readlines(): # 读取文本内容

# 1.预处理去掉换行和前后空格

line = line.strip("\n").strip()

# 2.取出文本进行预处理

line2 = data_processing(str(line))

# 3.添加到待保存数组

data.append([file_name.split(".")[0], line2])

# 4.保存文件

save_data(data, "text")

def save_data(data: list, filename):

"""保存最终结果"""

with open(os.path.join(save_path, filename), "w", encoding="utf-8") as f:

for i in data:

f.writelines(i[0] + " " + i[1] + "\n")

print("%s Saving succeeded!" % filename)

if __name__ == '__main__':

# 数据文件存放路径

data_path = "~/kaldi/data/S0/" # /root/kaldi/data/S0/

# 保存的路径

save_path = "~/kaldi/kaldi_file/" # /root/kaldi/data/kaldi_file/

# 是否添加用户自定义词典

# jieba.load_userdict("./userdict.txt")

# 生成text主函数

get_text()

生成词典文件

这里我们用的弄好的词典,可以忽略这步

# -*- coding: utf-8 -*-

# @Author : yxn

# @Date : 2022/10/2 19:55

# @IDE : PyCharm(2022.2.1) Python3.9.13

def get_lexicon(data):

"""生成词典"""

lexicon = set()

with open(data, "r", encoding="utf-8") as f:

for i in f.readlines():

# 将原有词典首列去重添加到自定义词典中

[lexicon.add(x) for x in i.strip("\n").strip().split(" ")]

# print(lexicon)

# print(len(lexicon))

with open("../jieba/lexicon.text", "w", encoding="utf-8") as f:

for i in lexicon:

f.writelines(i + "\n")

print("lexicon.text生成成功! ")

if __name__ == '__main__':

data_path = "./text"

get_lexicon(data_path)

查看是否准备成功

先运行py文件生成数据 如下所示

再使用fix_data_dir.sh判断这四个文件是否符合标准

cd /root/kaldi/kaldi/egs/wsj/s5

utils/fix_data_dir.sh /root/kaldi/kaldi_file/

四个文件均准备成功输出如下:

推荐阅读

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。