我正在尝试使用wav2vec来训练我自己的自动语音识别系统:
https://github.com/pytorch/fairseq/tree/master/examples/wav2vec
import torchfrom fairseq.models.wav2vec import Wav2VecModelcp = torch.load('/path/to/wav2vec.pt')model = Wav2VecModel.build_model(cp['args'], task=None)model.load_state_dict(cp['model'])model.eval()
首先,如何使用加载的模型从一个wav文件返回预测结果?
其次,如何使用带有注释的数据进行预训练?我在清单脚本中没有看到任何关于文本的提及。
回答:
在尝试了各种方法后,我终于搞明白了,并从头开始训练了一个wav2vec模型。
一些背景知识:wav2vec使用半监督学习来学习预处理声音帧的向量表示。这类似于word2vec学习文本语料库中的词嵌入。在wav2vec的情况下,它会随机采样声音文件的部分,并学习预测给定部分是否在当前偏移位置的近期未来。这与用于训练变换器(如BERT)的掩码词任务有些相似。这种预测任务的优点在于它们是自监督的:算法可以使用未标记的数据进行训练,因为它利用数据的时间结构来生成标签,并使用随机抽样生成对比的负样本。这是一个二分类任务(提议的处理后声音帧是否在当前偏移的近期未来)。在训练这个二分类任务时,它学习了声音帧的向量表示(每10毫秒的声音对应一个512维的向量)。这些向量表示是有用的特征,因为它们集中了预测语音相关的信息。这些向量可以代替频谱图向量作为语音到文本算法(如wav2letter或deepSpeech)的输入。这是一个重要点:wav2vec不是一个完整的自动语音识别(ASR)系统。它是一个有用的组件,因为通过利用未标记数据(包含语音但没有文本转录的音频文件)的自监督学习,它大大减少了对标记数据(语音转录为文本)的需求。根据他们的文章,使用wav2vec在ASR管道中,似乎所需的标记数据量可以减少至少10倍(显然需要10到100倍较少的转录语音)。由于未转录的语音文件比转录的语音更容易获得,这是使用wav2vec作为ASR系统初始模块的一个巨大优势。
因此,wav2vec是用未标注的数据(没有使用文本进行训练)进行训练的。
让我感到困惑的是以下训练命令(这里):
python train.py /manifest/path --save-dir /model/path ...(etc.).........
事实证明,由于wav2vec是fairseq的一部分,应该使用以下fairseq命令行工具来训练它:
fairseq-train
由于这个命令的参数相当长,可以使用一个bash脚本来完成:
#!/bin/bashfairseq-train /home/user/4fairseq --save-dir /home/user/4fairseq --fp16 --max-update 400000 --save-interval 1 --no-epoch-checkpoints \--arch wav2vec --task audio_pretraining --lr 1e-06 --min-lr 1e-09 --optimizer adam --max-lr 0.005 --lr-scheduler cosine \--conv-feature-layers "[(512, 10, 5), (512, 8, 4), (512, 4, 2), (512, 4, 2), (512, 4, 2), (512, 1, 1), (512, 1, 1)]" \--conv-aggregator-layers "[(512, 2, 1), (512, 3, 1), (512, 4, 1), (512, 5, 1), (512, 6, 1), (512, 7, 1), (512, 8, 1), (512, 9, 1), (512, 10, 1), (512, 11, 1), (512, 12, 1), (512, 13, 1)]" \--skip-connections-agg --residual-scale 0.5 --log-compression --warmup-updates 500 --warmup-init-lr 1e-07 --criterion binary_cross_entropy --num-negatives 10 \--max-sample-size 150000 --max-tokens 1500000
大多数参数是这里建议的,仅需修改前两个参数(它们是文件系统路径)以适应您的系统。
由于我有的是mp3格式的音频语音文件,我使用以下bash脚本将它们转换为wav文件:
#!/bin/bashfor file in /home/user/data/soundFiles/*do echo "$file" echo "${file%.*}.wav" ffmpeg -i "$file" "${file%.*}.wav"done
他们建议音频文件应为短时长,长文件应分割成更小的文件。我的文件已经相当短,所以我没有进行分割。
在训练前,必须使用脚本wav2vec_manifest.py来创建训练数据清单。它将创建两个文件(train.tsv和valid.tsv),基本上是创建应该用于训练和验证的音频文件列表。这两个文件所在的路径是fairseq-train方法的第一个参数。
fairseq-train方法的第二个参数是保存模型的路径。训练后将有这两个模型文件:
checkpoint_best.pt
checkpoint_last.pt
这些文件会在每个epoch结束时更新,因此我能够提前终止训练过程并仍然保存这些模型文件