mode/models 中 DeepSpeech2 语音识别实战:从 LibriSpeech 预处理到 CTC 训练与 WER 评估的完整流水线
mode/models 中 DeepSpeech2 语音识别实战从 LibriSpeech 预处理到 CTC 训练与 WER 评估的完整流水线【免费下载链接】modelsModels and examples built with TensorFlow项目地址: https://gitcode.com/GitHub_Trending/mode/modelsDeepSpeech2 是 TensorFlow 生态中经典的端到端自动语音识别ASR模型当前仓库在 research/deep_speech 目录下给出了基于 TensorFlow 1.15.3 / 2.3 的完整实现。本篇以 research/deep_speech/README.md 为主线覆盖数据集下载与预处理、训练/评估命令、全部命令行参数并结合源码深入讲解模型结构2 层卷积 5 层双向 RNN 全连接、CTC 损失的时间步对齐机制、以及贪心解码器如何计算 WER/CER帮助读者在本地完整复现这一语音识别流水线。一、模型总览DeepSpeech2 是什么按 research/deep_speech/README.md 的说明DeepSpeech2 是一个端到端的深度神经网络 ASR 模型其网络由2 个卷积层、5 个双向 RNN 层和 1 个全连接层组成输入特征为从音频中提取的线性谱图linear spectrogram损失函数采用连接时序分类Connectionist Temporal Classification, CTC。当前实现参考了原作者的 DeepSpeech 代码与 MLPerf 仓库中的参考实现README 顶部注明该模块为 No Maintenance Intended且标注兼容 TensorFlow 1.15.3 与 2.3 两个版本。整个目录的文件职责如下文件职责deep_speech.py训练/评估主入口定义全部命令行参数与model_fndeep_speech_model.pyDeepSpeech2 网络结构定义data/download.py下载 LibriSpeech 语料并预处理为 CSVdata/dataset.py解析 CSV、构建tf.data.Dataset、实现批量洗牌data/featurizer.py谱图与文本标签特征提取data/vocabulary.txt词表a-z、、-共 28 个字符decoder.pyCTC 贪心解码器与 WER/CER 计算run_deep_speech.sh一键跑完整 benchmark 的脚本requirements.txtPython 依赖nltk3.3、pandas0.23.3、soundfile0.10.2、sox1.3.3二、运行环境与数据准备2.1 配置 Python 路径与安装依赖README 要求先将仓库顶层的/models目录加入 Python 路径因为deep_speech.py内部from official.utils.flags import core as flags_core依赖仓库顶层的official包export PYTHONPATH$PYTHONPATH:/path/to/models然后安装共享依赖pip3 install -r requirements.txt # 或 pip install -r requirements.txt依赖清单见 research/deep_speech/requirements.txt其中sox用于 FLAC 转 WAVsoundfile用于读取音频nltk用于计算编辑距离pandas用于生成 CSV。2.2 下载与预处理 LibriSpeechpython data/download.py # 参数 # --data_dir 数据下载与保存目录默认 /tmp/librispeech_data使用--help/-h可查看全部参数。从 download.py 源码可以看到脚本内置了 LibriSpeechOpenSLR 12全部 7 个分区的下载地址并额外提供--train_only只下 train-clean-100/360 与 train-other-500、--dev_onlydev-clean dev-other、--test_onlytest-clean test-other三个布尔开关不带任何开关时默认下载完整数据集。预处理的实质工作由convert_audio_and_split_transcript完成download.py用sox.Transformer把每个分区的 FLAC 音频逐个转成 WAV逐行解析.trans.txt转写文件把转写文本做 NFKD 归一化、ASCII 化、去首尾空白并转小写生成一个Tab 分隔的三列 CSVwav_filenamewav 绝对路径、wav_filesize字节数、transcript转写文本。这与 README Dataset 一节的描述完全一致训练数据为 train-clean-100 train-clean-360约 13 万条样本验证集为 dev-clean约 2.7K 行。CSV 中的wav_filesize并非冗余信息——后续训练流水线直接用它作为音频长短的代理指标来做排序见下文 4.1 节。2.3 数据加载DeepSpeechDataset 与 tf.data 流水线data/dataset.py 负责把 CSV 变成可训练的tf.data.DatasetAudioConfig(sample_rate, window_ms, stride_ms, normalize)承载谱图参数默认采样率 16000 Hz、窗长 20 ms、帧移 10 ms并对特征做均值/方差归一化DatasetConfig校验 CSV 与词表文件存在性并持有sortagrad开关DeepSpeechDataset初始化音频/文本两个 featurizer并固定num_feature_bins 161——即 16 kHz 采样率下 20 ms 汉宁窗对应 161 个线性频率 bins与 featurizer.py 中compute_spectrogram_feature的输出维度一致input_fndataset.py通过tf.data.Dataset.from_generator逐条产出{features, input_length, label_length}与标签张量再用padded_batch把 batch 内不等长的时序特征填充到最长样本、prefetch(AUTOTUNE)加速输入管道。三、模型结构源码剖析网络定义集中在 deep_speech_model.pyDeepSpeech2.__call__L143-L176按如下顺序搭建前向计算图Conv1kernel(41, 11)、stride(2, 2)、32 个 filter、relu6激活、无 bias输入前做(20, 5)对称 paddingConv2kernel(21, 11)、stride(2, 1)、32 个 filterpadding(10, 5)卷积输出 reshape 为[batch, T, feat_size * 32]送入 RNN5 层双向 RNN单元类型由SUPPORTED_RNNS决定支持gru默认、lstm、rnn除第一层外每层 RNN 前都插入 Batch NormalizationL164-L169 中is_batch_norm (layer_counter ! 0)FC 层最后再做一次 Batch Normalization接Dense(num_classes, activationsoftmax)use_bias可控默认 True。几个值得注意的实现细节_conv_bn_layer中的对称 padding 是为了保证卷积后序列不会比标签短源码注释明确写了 This step is required to avoid issues when RNN output sequence is shorter than the label lengthL77-L82——这正是 CTC 对输出时间步不少于标签长度的要求BatchNorm 采用momentum0.997、epsilon1e-5L30-L32docstring 特别解释了 momentum 偏大时验证精度收敛更慢可尝试调小到 0.1 以更快看到评估结果输出层的softmax激活意味着 logits 张量直接就是概率分布评估端可直接取argmax。四、训练与评估入口deep_speech.py 全参数解析训练命令README Run each step individually 一节python deep_speech.pydeep_speech.py 中的define_deep_speech_flagsL304-L405注册了 README 提到的四个核心参数及其余全部超参汇总如下参数默认值说明--model_dir/tmp/deep_speech_model/训练 checkpoint 保存目录--export_dir/tmp/deep_speech_saved_model/SavedModel 导出目录--train_data_dir指向 test-clean CSV 的路径训练集 CSV 文件路径--eval_data_dir同上评估集 CSV 文件路径--num_gpus—GPU 数量-1表示使用全部可用 GPU--batch_size128全局 batch size多卡时必须是 GPU 数整数倍--train_epochs10训练轮数--epochs_between_evals公共参数每多少 epoch 评估一次--seed1随机种子--sample_rate16000音频采样率--window_ms20谱图帧长ms--stride_ms10谱图帧移ms--vocabulary_filedata/vocabulary.txt词表文件路径--sortagradTrue首个 epoch 按音频长度排序、不洗牌--rnn_hidden_size800每层 RNN 隐状态维度--rnn_hidden_layers5RNN 层数--rnn_typegruRNN 单元类型gru/lstm/rnn--is_bidirectionalTrueRNN 是否双向--use_biasTrue最后一层 FC 是否使用 bias--learning_rate5e-4Adam 初始学习率--wer_thresholdNone达到该 WER 后停止训练LibriSpeech 上 MLPerf 参考实现的阈值为 0.234.1 sortagrad 与批量洗牌README Dataset 节提到除第一个 epoch 外训练数据按 batch 洗牌当 sortagrad 开启时首个 epoch 除外。对应源码是 batch_wise_dataset_shuffle当epoch_index 0且sortagradTrue时样本保持按wav_filesize由 _preprocess_data 解析 CSV 时排序得到升序排列使同一 mini-batch 内音频长短相近、减少 padding 浪费并加速早期收敛之后的每个周期则把样本切成若干桶每桶一个 batch整桶地随机重排——既打乱样本顺序又保持桶内长短一致从而与padded_batch的填充策略保持协同。训练主循环在 run_deep_speech 中每个训练周期都调用一次该函数。4.2 CTC 损失与卷积后的时间步对齐model_fndeep_speech.py中训练分支的核心是ctc_input_length compute_length_after_conv( tf.shape(features)[1], tf.shape(logits)[1], input_length) loss tf.reduce_mean(tf.keras.backend.ctc_batch_cost( labels, logits, ctc_input_length, label_length))由于 batch 内样本被 padding 到同一长度而卷积 stride(2,2)→(2,1)会把时间维度缩短CTC 需要知道每条样本真实特征在卷积后对应多少时间步。compute_length_after_convL43-L68用比例关系ctc_input_length input_length / max_time_steps * ctc_time_steps精确反推再连同label_length一起传给ctc_batch_cost。优化器为 Adam学习率--learning_rate训练 op 用tf.group(minimize_op, update_ops)把 BatchNorm 的移动统计量更新一并纳入L167-L172。4.3 评估贪心解码与 WER / CERevaluate_modeldeep_speech.py对评估集每条样本取probabilities即 softmax 后的概率交给 DeepSpeechDecoder 做标准 CTC 贪心解码对每个时间步取argmax→ 用itertools.groupby合并连续重复字符 → 剔除 blank 索引词表 28 个真实字符blank 默认索引 28见 decoder.py 与 vocabulary.txt 中 a-z、、-共 28 行。随后用nltk.metrics.distance.edit_distance分别计算字错率WER先按空格分词、把每个唯一词映射为单字符再求编辑距离和字素错率CER两者均除以对应参考长度后对全数据集取平均最终以{WER: ..., CER: ..., global_step: ...}返回并写入 benchmark 日志。若--wer_threshold达到阈值训练主循环立即 breakL298-L301。多 GPU 方面入口通过distribution_utils.get_distribution_strategy构建 DistributionStrategy并强制全局 batch size 必须是 GPU 数的整数倍per_device_batch_sizeL195-L223因为 Estimator 场景下需要手动除以卡数得到 per-replica batch。五、一键 Benchmarkrun_deep_speech.shREADME 指出 run_deep_speech.sh 以默认参数跑完整流水线sh run_deep_speech.sh脚本按 4 步执行且 README 特别提醒benchmark 的训练集包含 train-clean-100、train-clean-360、train-other-500评估集包含 dev-clean 与 dev-other。对照脚本源码可以看到各步细节Step 1python data/download.py下载并预处理数据集各分区 CSV 落在/tmp/librispeech_data/分区/LibriSpeech/分区.csvStep 2用head -1保留表头、sed 1d去头拼接合成train_dataset.csv三个训练分区与eval_dataset.csv两个 dev 分区Step 3用awk逐行调用soxi -D读取 wav 时长过滤掉超过MAX_AUDIO_LEN27.0秒的样本得到final_train_dataset.csv/final_eval_dataset.csv——超长样本被剔除是为了控制训练时序列长度与 padding 开销Step 4以 nohup 后台启动训练关键命令行参数为nohup python deep_speech.py \ --train_data_dir$final_train_file \ --eval_data_dir$final_eval_file \ --num_gpus-1 \ --wer_threshold0.23 \ --seed1 $log_file 21 即使用全部 GPU、以 WER ≤ 0.23 作为停止条件脚本注释标明这是 MLPerf 参考实现的目标运行日志落盘到log_日期文件。六、适用前提与注意事项环境前提该模块面向 TensorFlow 1.15.3 / 2.3README 顶部徽章标注 No Maintenance Intended意味着代码以历史参考实现为主新环境运行前建议按 requirements.txt 固定依赖版本磁盘空间完整下载 LibriSpeech 全部分区脚本默认行为体积较大可按需使用--train_only/--dev_only数据格式约定训练/评估 CSV 必须是 Tab 分隔三列wav_filename / wav_filesize / transcript且首行为表头wav_filesize会被用作排序键手工构造数据时须保证该列正确词表与解码器一致性--vocabulary_file默认指向 data/vocabulary.txt28 个字符decoder 的blank_index28与之严格对应更换词表时需同步调整 blank 索引超参调优切入点--rnn_type可在 gru/lstm/rnn 间切换、--sortagrad关闭后首 epoch 即随机洗牌、BatchNorm momentum 可按源码注释在 0.997 与更小值如 0.1之间权衡验证收敛速度这些都是源码已预留的调参接口。综上research/deep_speech 目录给出了从语料下载、谱图特征工程、CTC 训练到贪心解码评估的端到端 ASR 参考实现download.py产出三列 CSVdataset.py构建tf.data管道并实现 sortagrad 批量洗牌deep_speech_model.py定义卷积-双向 GRU-FC 主干deep_speech.py以 Estimator 组织训练/评估循环run_deep_speech.sh则提供一键复现 MLPerf WER0.23 目标的完整脚本。【免费下载链接】modelsModels and examples built with TensorFlow项目地址: https://gitcode.com/GitHub_Trending/mode/models创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考