aishell2 几点说明
数据的准备
1.语音数据文件的结构
1.三个文件夹 train dev test
2.每个文件下都含有trans.txt 与 wav.scp 以及音频文件(具体音频的上级路径至少是根基不同的录制者区分的)
3.tran.txt 是"filename" + tab + "标注的文本(不用分词)"
4.wav.scp 是"音频文件名(无后缀)" + tab + "音频相对路径"
2.字典的生成
1.克隆代码:https://github.com/aishell-foundation/DaCiDian.git
2.word_to_pinyin.txt pinyin_to_phone.txt 生成 word_to_phone(lexicon.txt) 就是词到音素的字典
3.分词
1. 安装jieba分词
2. 以lexicon.txt里的词生成jieba分词用的词典(vocab.txt)
语言模型
基于分好词的文本 就可以训练出来
gmm 训练
1.提取train dev test数据集的mfcc特征
2.会把train的数据分出两部分出来,100k(10万条语句)以及 300k(30万条语句)
1 mono train
1. 这里会用前面分出来的100k条语句训练
2. 训练出的mono会用来对齐300k的数据集
2 tri1 train
1. 这里用300k条语句的train集来训练
2. 训练出来的结果用来对齐所用的train数据集
3 tri2 train
在tri1对齐后的结果上调整参数训练
4 tri3 train
同tri2理
tdnn train
配置
1. num_jobs_initial num_jobs_final 根据 GPU的个数决定 都不能超过GPU的个数
2. GPU 个数不多的情况下steps/nnet3/chain/train.py 带上--use-gpu=wait的参数进行训练
3. conf下会缺个online_cmvn.conf文件要补充 即使没内容也可以
补充
1. 可以根据我前面的说格式添加训练的数据集
2. 如果训练的数据集条数小于300k时 需要修改local/run_gmm.sh
修改./local/word_segmentation.py
按字典的词来分词 不要生成新的词,这样训练出来的模型错误率可以减少0.5%
#words = jieba.cut(trans)
words = jieba.cut(trans, HMM=False)
初步分析:
对于未在字典里词 会处理成UNK,用不生成新词方式话,可以减少UNK的出现。训练的文本模型会更好些,同时转成音素时也会更加完整。
chain的识别
1.生成识别用的配置文件
./steps/online/nnet3/prepare_online_decoding.sh data/lang_chain exp/chain/extractor_all exp/chain/tdnn_1b_all_sp exp/chain/nnet_online
编辑exp/chain/nnet_online/conf/mfcc.conf 追加
--num-mel-bins=40 # similar to Google's setup.
--num-ceps=40 # there is no dimensionality reduction.
--low-freq=20 # low cutoff frequency for mel bins
--high-freq=-400 # high cutoff frequency, relative to Nyquist of 8000 (=7600)
编辑exp/chain/nnet_online/conf/online.conf 追加
--add-pitch=true
2.写个方便识别的脚本
#! /bin/sh
#
# test_online_decode.sh
# Copyright (C) 2018 xiaominfc <xiaominfc@xiaominfc-MBP.local>
#
# Distributed under terms of the MIT license.
#
. ./path.sh
. ./cmd.sh
exp_dir={tdnn_1b_all_sp path}
audio_dir=./audios
decode_dir="./work"
mkdir -p $decode_dir
> $decode_dir/input.scp_t
> $decode_dir/usp.scp_t
config_file=exp/chain/nnet_online/conf/online.conf
verbose=1
for f in $audio_dir/*.wav; do
bf=`basename $f`
bf=${bf%.wav}
echo $bf $f >> $decode_dir/input.scp_t
echo $bf $bf >> $decode_dir/usp.scp_t
done
cat $decode_dir/input.scp_t | sort -n > $decode_dir/input.scp
cat $decode_dir/usp.scp_t | sort -n > $decode_dir/usp.scp
#ivconfig=exp/nnet3/ivectors_train_sp/conf/ivector_extractor.conf
online2-wav-nnet3-latgen-faster --verbose=$verbose --config=$config_file --frames-per-chunk=20 --extra-left-context-initial=0 \
--min-active=1000 --frame-subsampling-factor=3 --do-endpointing=true --max-active=7000 --beam=15.0 --lattice-beam=8.0 \
--online=false --acoustic-scale=1.4 \
--word-symbol-table=$exp_dir/graph/words.txt \
$exp_dir/final.mdl $exp_dir/graph/HCLG.fst "ark:$decode_dir/usp.scp" "scp:$decode_dir/input.scp" "ark:/dev/null"
修改exp_dir成你的
mkdir audios
放入你的音频文件到audios里
执行脚本就可以识别了