LAS 开源框架实例

LAS 开源框架梳理 (kaldi+pytorch版本)

参考

开源框架github地址

W. Chan, N. Jaitly, Q. Le, and O. Vinyals, “Listen, attend and spell: A
neural network for large vocabulary conversational speech recognition,”
in ICASSP 2016.

aishell (15G) 数据下载地址

一、框架

二、工程详细流程

1、执行环境配置

  • 安装kaldi。并配置环境变量(~/.bash_profile)。
  • Python3 (Recommend Anaconda)
  • PyTorch 0.4.1+
  • Kaldi (Just for feature extraction)
  • pip install -r requirements.txt
  • cd tools; make KALDI=/path/to/kaldi
  • If you want to run egs/aishell/run.sh, download AISHELL dataset for free.

2、实验前准备(基于Aishell数据集)

本实验使用Aishell数据集进行模型训练。实验前的准备如下:

  • 将工程目录下的所有*.sh文件和*.py文件添加可执行权限。chmod -R +x *.sh(该指令不能递归给*.sh文件添加可执行权限)

  • cd /egs/aishell 修改该目录下run.sh脚本中的data="****"为aishell数据的绝对路径。

  • 执行run.sh即可对aishell数据集进行预测。bash ./run.sh

  • AISHELL数据集下载。执行命令nohup bash ./download_and_tar.sh > ./out.out 2>&1 &
    download_and_tar.sh脚本内容如下:

    #!/bin/bash
    wget -r -O resource_aishell.tgz "http://www.openslr.org/resources/33/resource_aishell.tgz"
    wget -r -O data_aishell.tgz "http://www.openslr.org/resources/33/data_aishell.tgz"
    tar -zxf resource_aishell.tgz
    tar -zxf data_aishell.tgz
    part=data_aishell
    data=`pwd`
    if [ $part == "data_aishell" ]; then
      cd $data/$part/wav
      for wav in ./*.tar.gz; do
        echo "Extracting wav from $wav"
        tar -zxf $wav && rm $wav
      done
    fi
    

    将数据下载到Listen-Attend-Spell-master/data下。
    并且解压至data目录下。最后data目录结构如下:

    └── Listen-Attend-Spell-master
        ├── egs
        │   └── aishell  # 项目实例主目录
        ├── data  # 源数据目录
        │   ├── data_aishell
        │   │   ├── transcript
        │   │   │   └── aishell_transcript_v0.8.txt # 发音编码与汉字映射关系,行例: [BAC009S0002W0131 显示 出 了 极 强 的 威力]
        │   │   └── wav # wav文件实体
        │   │       ├── dev
        │   │       ├── test
        │   │       └── train
        │   ├── download_and_tar.sh  # 下载和解压数据脚本
        │   ├── out.out  # 下载日志输出地址
        │   └── resource_aishell
        │       ├── lexicon.txt # 单词与因素的对应关系 行例: [报纸 b ao4 zh ix3] 
        │       └── speaker.info # 说话人是男性还是女性 行例: [0018 M]
    

    AISHELL数据集简介:

    训练集 验证集 测试集 ALL
    wav文件个数(发音编号数) 120418 14331 7176 141925
    speaker 数量 340 40 20 400

    数据收集部门邀请400个中国人参加录音,这些人来自中国口音不同的地区。
    录音是在安静的室内环境中使用高保真麦克风进行的, 采样率为16kHz。通过专业的语音注释和严格的质量检验,人工转录准确率达到95%以上。这些数据可供学术使用。语料库包含170小时的语音,分为training(85%), development(10%)和 testing(5%)集。开发集用于调整训练中的超参数。

三、实验

第一阶段 语音特征抽取

1、data目录结构准备

执行脚本 local/aishell_data_prep.sh脚本用法:

local/aishell_data_prep.sh <wav dir> <transcript dir>
#  是wav实体文件所在目录。
#  翻译文件所在目录。翻译文件行例:[音频编号 汉字词组lost]

该阶段结束后在aishell目录下创建如下若干目录:

./data/
├── dev  # 目录中的内容同本目录下train
│   ├── ...
├── local
│   ├── dev # 目录中的内容同本目录下train
│   │   ├── ...
│   ├── test # 目录中的内容同本目录下train
│   │   ├── ...
│   └── train  
│       ├── spk2utt
│       ├── text
│       ├── transcripts.txt
│       ├── utt2spk
│       ├── utt2spk_all
│       ├── utt.list
│       ├── wav.flist  # 整个样本集的wav绝对路径List
│       ├── wav.scp
│       └── wav.scp_all
├── test # 目录中的内容同本目录下train
│   ├── ...
└── train
    ├── spk2utt   # 行例: [说话人编号  音频编号List]
    ├── text      # 行例: [音频编号  中文词组List]
    ├── text.org  
    ├── utt2spk   # 行例: [音频编号 说话人编号]
    └── wav.scp   # 行例: [音频编号 wav文件绝对路径]

2、音频特征提取

核心代码。(from egs/aishell/run.sh)

if [ $stage -le 1 ]; then
    echo "Stage 1: Feature Generation"
    ### Task dependent. You have to make data the following preparation part by yourself.
    ### But you can utilize Kaldi recipes in most cases
    fbankdir=fbank
    for data in train test dev; do
        steps/make_fbank.sh --cmd "$train_cmd" --nj $nj --write_utt2num_frames true \
            data/$data exp/make_fbank/$data $fbankdir/$data || exit 1;
    done
    # compute global CMVN 基于说话人说话或句子的均值和方差归一化特征
    # compute-cmvn-stats.cc
    compute-cmvn-stats scp:data/train/feats.scp data/train/cmvn.ark
    # dump features for training. dump.sh 在src的utils包中
    # 将特征输出到dump文件夹下
    for data in train test dev; do
        feat_dir=`eval echo '$feat_'${data}'_dir'`
        dump.sh --cmd "$train_cmd" --nj ${nj} --do_delta ${do_delta} \
            data/$data/feats.scp data/train/cmvn.ark exp/dump_feats/$data $feat_dir
    done
fi
  • 执行脚本 steps/make_fbank.sh脚本用法:
    steps/make_fbank.sh <input data dir> <output logs dir> <feat output dir>
    
    • 目录需要必须包含4个重要文件,如:data/train目录。
    • 抽取日志存放目录,如: exp/make_fbank/train,test,dev。该目录下主要包含两类格式的文件: *.log; *.scp, 如: wav.20.scp(20为并行作业ID),行例: [音频编码 wav绝对路径]。
    • 特征实体二进制(ark)文件存放目录,如目录: fbank/train,test,dev。该目录下包含两类格式的文件: *.ark(二进制实体数据); *.scp,[音频编码 ark文件绝对路径]
  • 执行指令 compute-cmvn-stats用法实例如下:
    compute-cmvn-stats scp:data/train/feats.scp data/train/cmvn.ark
    
    该指令将在./data/train 目录下生成文件feats.scp和文件cmvn.ark
    • feats.scp 行例:[音频编码 对应特征二进制ark文件绝对路径]
    • cmvn.ark (维度为什么是240)
  • 执行指令dump.sh(Listen-Attend-Spell-master/src/utils/dump.sh,由于path.sh中已经配置该路径的PATH)分别处理train,test和dev,在dump目录中生成各二进制(ark)特征文件。
    dump.sh <feats.scp dir> <cmvn.ark dir> <log dir> <dump dir>
    
    • data/$data/feats.scp
    • 该工程中固定路径 data/train/cmvn.ark
    • 特征提取日志存放目录。例: exp/dump_feats/…
    • 特征文件(feats.20.ark)和映射文件存放目录。例:dump/train/deltatrue。
该阶段最终在工作空间生成如下文件:
./dump/ 
├── dev # 目录中的内容同本目录下train
│   └── deltatrue
│       ├── ...
├── test # 目录中的内容同本目录下train
│   └── deltatrue
│       ├── ...
└── train
    └── deltatrue
        ├── feats.10.ark # 特征实体文件
        ├── feats.10.scp # 行例 [发音编号 ark绝对路径:166413]
        ├── ...
        ├── feats.scp # 行例 [发音编号 ark绝对路径:frame编号]
        └── utt2num_frames # 行例[发音编号 frame编号] 映射关系

第二阶段 元数据准备

1、创建词汇表

创建data/lang_1char/train_chars.txt文件,目的是存放char到idx的映射关系。
将三个字符写入映射文件。文本补齐时padding的数值为-1(该值在src/utils/utils.py中(IGNORE_ID)设置)。

echo " 0" >  ${dict}
echo " 1" >> ${dict}
echo " 2" >> ${dict}

执行src/utils/text2token.py脚本,作用是整理所有语聊中使用到的中文汉字,填充train_chars.txt文件。该脚本最终产物是在data/lang_1char目录下创建train_chars.txt文件,包含所有char到索引的映射。

train_chars.txt文件样式如下:

 0
 1
 2
一 3
丁 4
七 5
万 6
丈 7
三 8
上 9

2、创建训练阶段的元数据(json格式文件)

执行src/utils/data2json.sh脚本,作用在dump/train,test,dev目录下创建data.json文件。
data.json形式如下:

{
     "utts": {
     
    "BAC009S0002W0122": {
     
      "input": [
        {
     
          "feat": "/data/youdao/LAS/Listen-Attend-Spell-master/egs/aishell/dump/train/deltatrue/feats.1.ark:17",
          "name": "input1",
          "shape": [
            598,  # 该段frame语音总帧数
            240   # fbank+cmvn特征维度
          ]
        }
      ],
      "output": [
        {
     
          "name": "target1",
          "shape": [
            15,    # char长度
            4233   # 字典总长度
          ],
          "text": "而对楼市成交抑制作用最大的限购",
          "token": "而 对 楼 市 成 交 抑 制 作 用 最 大 的 限 购",
          "tokenid": "2996 1012 1892 1122 1380 83 1427 357 168 2479 1741 815 2554 3968 3555"
        }
      ],
      "utt2spk": "S0002"
    },
    "BAC009S0002W0123": {
     ...}
    ...
}

第三阶段 LAS模型训练 seq2seq(Encoder, Decoder(Att))

1、数据预处理

为了方便训练LSTM结构,需要将每个batch中的样本进行长度对齐处理。
下图是对齐操作简易图:

2、Encoder

Encoder模块需要输入两种数据:每个样本的对齐前的长度List;对齐后的特征矩阵。
Encoder模块结构如下图所示:

3、Decoder(Att)

Dncoder模块需要输入两种数据:每个样本对应的target(该Aishell数据集对应的是Char)序列索引值;Encoder每个时刻的隐层输出List。
Decoder模块结构如下图所示:

第四阶段 模型评估阶段(输出预测结果,并使用CER评估模型)

1、Beam Search

Beam Search 就是模型预测输出中挑选最优的若干条路径(sentence)。
假设 beam size = 3(输出最优的3条路径)。
算法中,3条最优路径维护若干指标,其中一个重要指标是sum_score
假设sum_score(i,t)表示第i条最优路径,搜索至时刻t时经过各节点的权重和。那么sum_score(i,t)迭代维护的公式如下:

sum_score(i,t)=top(3,\{sum\_score(j,t-1) + top(k,score)\}) \\

其中 j,k \in {1,2,3} \\

集合 \{sum\_score(j,t-1) + top(k,score)\} 共包含9个元素

Beam Search的简易流程图如下:

2、模型最终评估结果

Aishell数据集共7176个句子。总字数为104765。包含20个speaker。
模型最终评估结果如下:

                     SYSTEM SUMMARY PERCENTAGES by SPEAKER
      ,-----------------------------------------------------------------.
      |/data/youdao/LAS/Listen-Attend-Spell-master/src/bin/logs/hyp.trn |
      |-----------------------------------------------------------------|
      | SPKR   | # Snt  # Wrd | Corr    Sub    Del    Ins    Err  S.Err |
      |--------+--------------+-----------------------------------------|
      | s0764  |  370    5417 | 90.6    9.3    0.1    0.1    9.5   57.6 |
      |--------+--------------+-----------------------------------------|
      | s0765  |  361    5318 | 90.1    9.9    0.1    0.0   10.0   54.6 |
      |--------+--------------+-----------------------------------------|
      | s0766  |  340    4904 | 86.3   13.5    0.1    0.1   13.8   66.2 |
      |--------+--------------+-----------------------------------------|
      | s0767  |  353    5146 | 89.5   10.1    0.4    0.2   10.7   58.6 |
      |--------+--------------+-----------------------------------------|
      | s0768  |  367    5251 | 81.4   18.2    0.4    0.4   19.0   79.8 |
      |--------+--------------+-----------------------------------------|
      | s0769  |  361    5216 | 87.0   12.9    0.2    0.2   13.2   62.6 |
      |--------+--------------+-----------------------------------------|
      | s0770  |  353    5096 | 91.3    8.4    0.3    0.1    8.8   51.6 |
      |--------+--------------+-----------------------------------------|
      | s0901  |  368    5278 | 85.9   13.1    1.0    0.6   14.8   70.9 |
      |--------+--------------+-----------------------------------------|
      | s0902  |  363    5259 | 88.4   11.4    0.3    0.2   11.9   60.9 |
      |--------+--------------+-----------------------------------------|
      | s0903  |  373    5499 | 85.4   14.1    0.5    0.2   14.7   70.8 |
      |--------+--------------+-----------------------------------------|
      | s0904  |  368    5474 | 79.1   19.7    1.2    0.1   21.0   81.3 |
      |--------+--------------+-----------------------------------------|
      | s0905  |  360    5342 | 90.5    9.4    0.1    0.1    9.6   56.1 |
      |--------+--------------+-----------------------------------------|
      | s0906  |  353    5125 | 82.1   17.5    0.4    0.4   18.3   71.4 |
      |--------+--------------+-----------------------------------------|
      | s0907  |  350    5041 | 90.7    9.2    0.1    0.2    9.5   50.9 |
      |--------+--------------+-----------------------------------------|
      | s0908  |  353    5083 | 90.9    8.8    0.3    0.2    9.3   55.5 |
      |--------+--------------+-----------------------------------------|
      | s0912  |  335    4919 | 89.6   10.3    0.1    0.3   10.7   59.4 |
      |--------+--------------+-----------------------------------------|
      | s0913  |  363    5413 | 84.2   15.2    0.6    1.1   16.9   68.3 |
      |--------+--------------+-----------------------------------------|
      | s0914  |  361    5344 | 76.9   22.3    0.8    0.6   23.7   83.1 |
      |--------+--------------+-----------------------------------------|
      | s0915  |  363    5338 | 88.5   11.1    0.3    0.5   12.0   60.3 |
      |--------+--------------+-----------------------------------------|
      | s0916  |  361    5302 | 90.0    9.8    0.2    0.1   10.1   58.4 |
      |=================================================================|
      | Sum/Avg| 7176  104765 | 86.9   12.8    0.4    0.3   13.4   64.0 |
      |=================================================================|
      |  Mean  |358.8  5238.3 | 86.9   12.7    0.4    0.3   13.4   63.9 |
      |  S.D.  |  9.6  170.0  |  4.2    4.0    0.3    0.3    4.4    9.7 |
      | Median |361.0  5268.5 | 88.4   11.2    0.3    0.2   11.9   60.6 |
      `-----------------------------------------------------------------'

其中:

# Snt # Wrd Corr Sub Del Ins Err S.Err
sentence words 正确 替换 遗漏 插入 错误 句错误率

S.D.(Standard Deviation) 表示标准差,其公式如下:

\bar{x}=\frac{1}{n}\sum{x_i}
标准差 s = \sqrt{\frac{1}{n-1}\sum(x_i-\bar{x})^2}

你可能感兴趣的:(LAS 开源框架实例)