- 人工智能
- 语音
- 音频
- 深度学习
- NLP
【免费下载链接】espnet
End-to-End Speech Processing Toolkit
导读
本文围绕 ESPnet2 仓库中的egs2/swbd_sentiment/asr1语音情感分析(Speech Sentiment)配方展开,讲解如何利用 Switchboard Sentiment 语料(LDC2020T14)将「情感分类」作为 ASR 多任务输出进行联合建模:模型在识别转写文本的同时,预测每句话的 Positive / Neutral / Negative 情感标签。读完本文,你将掌握该配方的数据准备流程(含多数投票标签消歧)、两套可复现的训练配置(纯 Conformer 与 wav2vec2.0 前端)、F1 评测脚本的调用方式,以及官方实验的基线结果与预训练模型资源。
一、任务背景与数据集
1.1 什么是语音情感分析
语音情感分析(Speech Sentiment Analysis)的目标是从一句话语音中判定说话人的情感倾向。与传统的"意图分类"(Intent Classification)不同,本配方将情感分类与 ASR 结合在一起:同一个模型既输出转写文本,又输出情感标签,属于 ESPnet2 ASR 多任务学习(multi-task)的典型应用。
该配方的核心数据是Speech Sentiment Annotations(Switchboard Sentiment),语料来自 LDC(编号 LDC2020T14),配套论文为 LREC 2020 的《Switchboard Sentiment》相关工作。它基于经典的 Switchboard 电话对话语料(LDC97S62)人工标注了每句话的情感倾向。
1.2 标签体系与多数投票
每个话语的情感标注可能包含多个子标签(例如Neutral-{Questioning}#Neutral-{No emotion}#Neutral-{No emotion},其中#分隔多个标注者的意见)。egs2/swbd_sentiment/asr1/local/prepare_sentiment.py中的majorityvote()函数实现了论文所述的多数投票(majority voting)消歧策略:
- 统计一句话中 Positive / Neutral / Negative 三类标签的出现次数;
- 取出现次数最多的类别作为最终标签;
- 若最高票出现并列(
len(keys) != 1),则丢弃该样本(返回-1)。
def majorityvote(line): count_pos = line.count("Positive") count_neu = line.count("Neutral") count_neg = line.count("Negative") dic = {"Positive": count_pos, "Neutral": count_neu, "Negative": count_neg} max_value = max(dic.values()) keys = [key for key, value in dic.items() if value == max_value] label = keys[0] if len(keys) == 1 else -1 return label最终文本行的格式为utt_id <情感标签> <转写文本>,即标签被拼接在转写文本之前,作为序列的第一个 token,与 ASR 输出共用同一个 Transformer 解码器——这就是"预测转写的同时预测情感"的实现方式。
二、数据准备与配方运行
2.1 前置数据与目录配置
运行前需在egs2/swbd_sentiment/asr1/db.sh中设置SWBD变量,指向存放 LDC 语料的根目录。egs2/swbd_sentiment/asr1/local/data.sh假设:
- Switchboard 原始语料位于
${SWBD}/LDC97S62; - 情感标注文件位于
${SWBD}/speech_sentiment_annotations/data/sentiment_labels.tsv。
2.2 数据准备流水线
local/data.sh分为三个阶段:
Stage 1:数据准备——调用swbd1_data_download.sh、swbd1_prepare_dict.sh、swbd1_data_prep.sh完成 Switchboard 标准数据准备;随后用sed给data/train/wav.scp追加sox管道,将 8k 采样率上采样到 16k,使配方与其他 ESPnet2 配方保持一致。
Stage 2:文本清洗——备份原文后通过sed移除._、.等符号,并修正them_1等特殊词:
sed -i 's/\._/ /g; s/\.//g; s/them_1/them/g' data/train/textStage 3:情感标注与转写拼接——调用prepare_sentiment.py,将情感标签与转写文本对齐并拼接,同时按行号范围切分 train / dev / test:
python3 local/prepare_sentiment.py \ --train_dir data/train/ \ --dev_dir data/dev/ \ --test_dir data/test/ \ --sentiment_file ${swbd_sentiment} \ --text_file data/local/tmp/text \ --wavscp_file data/local/tmp/wav.scp该脚本内部会:
- 以
sentiment_labels.tsv为基准逐行读取(utt_id、起止时间、情感标签); - 在文本文件中按相近时间戳(允许
eps = 0.05秒的误差)匹配对应转写,见prepare_sentiment.py中start_time_id >= float2str(float(start) - eps)的判断逻辑; - 调用
normalize_transcript()清洗转写:去除标点(保留撇号)、去除[LAUGHTER]等标签、拆开撇号缩写、合并多余空格; - 写出
utt2spk、segments、text、wav.scp、reco2file_and_channel等 Kaldi 风格数据文件。
训练 / 验证 / 测试划分:官方没有提供标准切分,配方参照论文(arXiv 1911.09762)采用train 90%、dev 5%、test 5%的比例,对应情感标注文件的行区间为0-47056、47056-49673、49673-52293。
2.3 一键运行入口
egs2/swbd_sentiment/asr1/run.sh是配方的主入口,关键参数如下:
train_set="train" valid_set="dev" test_sets="test dev" ./asr.sh \ --lang en \ --ngpu 1 \ --use_lm false \ --nbpe 5000 \ --token_type word \ --feats_type raw \ --max_wav_duration 30 \ --inference_nj 8 \ --inference_asr_model valid.acc.ave_10best.pth \ --asr_config "${asr_config}" \ --inference_config "${inference_config}" \ --feats_normalize "utterance_mvn" \ --train_set "${train_set}" \ --valid_set "${valid_set}" \ --test_sets "${test_sets}" "$@"要点说明:
--token_type word:词级 token 化。情感标签作为独立词 token 进入词表;--use_lm false:不训练语言模型,解码时不使用 LM;--feats_type raw:直接使用原始波形(配合--feats_normalize utterance_mvn),特征在前端/预处理器中即时计算;--inference_asr_model valid.acc.ave_10best.pth:解码时选用验证集准确率最优的 10 个模型平均权重;asr.sh会依据--skip_stages等机制跳过 LM、ngram、packing、上传等无关阶段(详见egs2/swbd_sentiment/asr1/asr.sh中的 skip 逻辑)。
说明:当前仓库
run.sh默认引用conf/train_asr.yaml,而文档中的两组实验结果分别使用conf/tuning/下的两个 Conformer 配置;复现实验时应将--asr_config指向对应的 tuning 配置。
三、实验一:Conformer + Transformer 解码器 + 频谱增强
3.1 核心配置
完整配置见 train_asr_conformer.yaml,关键参数如下:
# encoder related encoder: conformer encoder_conf: output_size: 512 attention_heads: 4 linear_units: 2048 num_blocks: 12 dropout_rate: 0.1 positional_dropout_rate: 0.1 attention_dropout_rate: 0.1 input_layer: conv2d normalize_before: true macaron_style: true pos_enc_layer_type: "rel_pos" selfattention_layer_type: "rel_selfattn" activation_type: "swish" use_cnn_module: true cnn_module_kernel: 31 # decoder related decoder: transformer decoder_conf: attention_heads: 4 linear_units: 2048 num_blocks: 6 dropout_rate: 0.1 positional_dropout_rate: 0.1 self_attention_dropout_rate: 0.1 src_attention_dropout_rate: 0.1 optim: adam optim_conf: lr: 0.0025 scheduler: warmuplr scheduler_conf: warmup_steps: 40000 batch_type: numel batch_bins: 40000000 accum_grad: 3 max_epoch: 50该配置的技术要点:
- Conformer 编码器:12 层、输出维度 512、4 头注意力、前馈隐藏层 2048;启用
macaron_style(Macaron 结构)、相对位置编码(rel_pos)与相对自注意力(rel_selfattn)、swish激活、卷积模块内核尺寸 31,input_layer: conv2d表示用二维卷积对输入特征做下采样; - Transformer 解码器:6 层、4 头注意力、线性单元 2048,各 dropout 均为 0.1;
- 训练策略:Adam 优化器(lr=0.0025)+ WarmupLR 调度器(40000 步预热);
batch_type: numel按总元素数动态组批(4000 万 bins),accum_grad: 3累积梯度,最多 50 个 epoch; - 频谱增强(SpecAugment):时域 warping(窗口 5、bicubic 插值)、2 个频带掩码(宽度 0~30)、2 个时间掩码(宽度 0~40);
- 模型选择:
best_model_criterion以验证集acc最大化为目标,keep_nbest_models: 10保留 Top-10 权重用于平均。
3.2 实验结果
该配置的官方结果如下(labels 为 Positive / Neutral / Negative,token_type 为 word):
| dataset | Snt | Macro F1 (%) | Weighted F1 (%) | Micro F1 (%) |
|---|---|---|---|---|
| decode_asr_asr_model_valid.acc.ave_10best/valid | 2415 | 61.0 | 65.0 | 65.6 |
| decode_asr_asr_model_valid.acc.ave_10best/test | 2438 | 64.4 | 64.4 | 64.6 |
对应的预训练模型:YushiUeda_swbd_sentiment_asr_train_asr_conformer(可在 HuggingFace 的 espnet 组织下查找,配合asr.sh --download_model参数直接用于解码)。
四、实验二:wav2vec2.0 自监督前端 + Conformer
4.1 核心配置
第二组实验引入s3prl 自监督前端(wav2vec2.0),完整配置见 train_asr_conformer_wav2vec2.yaml。与实验一的差异集中在前端部分:
encoder: conformer encoder_conf: output_size: 512 attention_heads: 8 linear_units: 2048 num_blocks: 12 ... use_cnn_module: true cnn_module_kernel: 31 decoder: transformer decoder_conf: attention_heads: 8 linear_units: 2048 num_blocks: 6 ... freeze_param: [ "frontend.upstream" ] frontend: s3prl frontend_conf: frontend_conf: upstream: wav2vec2_large_ll60k # If the upstream is changed, please change the input_size in the preencoder. # If using hubert, change the above line to "upstream: hubert_large_ll60k" download_dir: ./hub multilayer_feature: True preencoder: linear preencoder_conf: input_size: 1024 # If the upstream is changed, please change this value accordingly. output_size: 80 model_conf: ctc_weight: 0.3 lsm_weight: 0.1 length_normalized_loss: false extract_feats_in_collect_stats: false关键差异解读:
frontend: s3prl:使用 s3prl 工具箱加载预训练自监督模型wav2vec2_large_ll60k(如需 hubert 可改为hubert_large_ll60k),权重下载到./hub;freeze_param: ["frontend.upstream"]:冻结 wav2vec2 上游网络参数,只训练下游部分,避免大规模微调导致显存与训练开销过高;preencoder: linear:线性降维层将 wav2vec2 的 1024 维表征压缩到 80 维,再送入 Conformer 编码器——注释明确提示更换 upstream 时需同步修改input_size;multilayer_feature: True:取 wav2vec2 多层特征的组合(s3prl 的加权层融合机制);ctc_weight: 0.3:训练损失按 0.3 权重引入 CTC 分支,与注意力机制联合训练;lsm_weight: 0.1:标签平滑权重 0.1;extract_feats_in_collect_stats: false:在 collect stats 阶段(asr.sh stage 10)生成伪统计文件而非真正前向前端提取特征,显著降低预训练特征提取开销;- 其余训练策略与实验一基本一致,仅
warmup_steps调整为 25000。
4.2 实验结果
| dataset | Snt | Macro F1 (%) | Weighted F1 (%) | Micro F1 (%) |
|---|---|---|---|---|
| decode_asr_asr_model_valid.acc.ave_10best/valid | 2415 | 64.5 | 67.5 | 67.4 |
| decode_asr_asr_model_valid.acc.ave_10best/test | 2438 | 64.1 | 66.5 | 66.3 |
对比可见,引入 wav2vec2.0 自监督特征后,情感分类 F1 全面提升(测试集 Macro F1 从 61.4 提升到 64.1,Weighted F1 从 64.4 提升到 66.5),验证了自监督语音表征对情感这类韵律/语义相关任务的增益。对应预训练模型:YushiUeda_swbd_sentiment_asr_train_asr_conformer_wav2vec2。
五、评测脚本:如何计算 F1 分数
5.1 统一评测入口
egs2/swbd_sentiment/asr1/local/score.sh是评测入口,默认针对inference_asr_model_valid.acc.ave_10best的 devel / test 解码结果,依次调用三个 Python 脚本:
python local/score.py --exp_root ${asr_expdir} python local/generate_asr_files.py --exp_root ${asr_expdir} python local/f1_score.py --exp_root ${asr_expdir}随后用sclite对剥离情感标签后的纯转写计算 WER,将结果写入score_wer/result_asr.txt:
sclite -r "${asr_expdir}/${valid_inference_folder}/score_wer/ref_asr.trn" trn \ -h "${asr_expdir}/${valid_inference_folder}/score_wer/hyp_asr.trn" trn \ -i rm -o all stdout > "${asr_expdir}/${valid_inference_folder}/score_wer/result_asr.txt"5.2 F1 计算细节
egs2/swbd_sentiment/asr1/local/score_f1.py使用sklearn.metrics.f1_score分别计算三种 F1:
- Macro F1:三个类别各自 F1 的算术平均(
average="macro"),对类别不平衡不敏感; - Weighted F1:按各类样本数加权的 F1(
average="weighted"); - Micro F1:全局混淆矩阵上计算的 F1(
average="micro")。
macro_f1 = f1_score(ref_list, hyp_list, average="macro", labels=["Positive", "Neutral", "Negative"]) weighted_f1 = f1_score(ref_list, hyp_list, average="weighted", labels=["Positive", "Neutral", "Negative"]) micro_f1 = f1_score(ref_list, hyp_list, average="micro", labels=["Positive", "Neutral", "Negative"])而local/score.py则输出按首 token 逐句比对的意图分类准确率,并负责从假设/参考文本中剥离情感标签生成纯 ASR 转写文件(hyp_asr.trn/ref_asr.trn),供 sclite 计算 WER 使用。
六、复现与扩展建议
6.1 复现步骤速览
- 在
egs2/swbd_sentiment/asr1/db.sh中配置SWBD路径(需具备 LDC 语料访问权限); - 运行
run.sh默认流程完成数据准备(stage 1-3); - 按实验目标选择 tuning 配置并执行训练:
./run.sh --asr_config conf/tuning/train_asr_conformer_wav2vec2.yaml(实验二); - 训练完成后自动解码并调用
local/score.sh输出 F1 与 WER; - 如需使用预训练模型直接推理,可用
asr.sh --download_model <HF 模型名> --skip_train true加载valid.acc.ave_10best权重。
6.2 环境信息参考
README 中记录的官方实验环境(2022 年 3 月):
- Python 3.7.11、PyTorch 1.9.0+cu102、ESPnet 0.10.7a1;
- Git commit:
3b53aedc654fd30a828689c2139a1e130adac077。
需要注意的是,当前仓库代码已演进,直接复现时建议以仓库当前安装要求为准;情感标注数据sentiment_labels.tsv需通过 LDC 渠道获取,仓库仅提供处理脚本。
6.3 扩展方向
- 更换自监督上游:将
upstream改为hubert_large_ll60k等模型时,务必同步调整preencoder_conf.input_size(参见配置内注释); - 调整多任务权重:修改
model_conf.ctc_weight、lsm_weight观察对情感分类与 ASR 的权衡; - 标签策略:
prepare_sentiment.py的多数投票与时间戳容差(eps=0.05)可根据标注特性调整,进而影响样本规模与标签质量。
七、总结
egs2/swbd_sentiment/asr1配方展示了 ESPnet2 如何以 ASR 多任务框架统一处理「转写 + 情感分类」:通过把情感标签拼接到文本序列头部,无需改动模型结构即可让 Transformer 解码器同时输出两者。两组官方基线证明:在 Conformer + SpecAugment 基础上叠加 wav2vec2.0 自监督前端(冻结上游 + 线性降维),可在测试集上将情感分类 Macro F1 从 61.4 提升至 64.1。配合仓库提供的 prepare_sentiment.py、score_f1.py 与两套 tuning 配置,该配方可完整复现并作为语音情感分析任务的起点。
- 人工智能
- 语音
- 音频
- 深度学习
- NLP
【免费下载链接】espnet
End-to-End Speech Processing Toolkit
相关推荐
ESPnet2 IEMOCAP ASR 实战:基于 HuBERT / Conformer 的语音情感识别与情绪标注联合建模
ESPnet2 IEMOCAP ASR 实战:基于 HuBERT / Conformer 的语音情感识别与情绪标注联合建模 导读 本文基于 ESPnet2 端到
人工智能语音音频深度学习NLPESPnet2 SLUE-VoxCeleb 情感语音识别配方实战:Conformer 联合预测转写文本与意图标签
ESPnet2 SLUE VoxCeleb 情感语音识别配方实战:Conformer 联合预测转写文本与意图标签 ESPnet2 为 SLUE 2022 Cha
人工智能语音音频深度学习NLP语音数据标注新方案:使用SenseVoice自动生成多语言情感标签
语音数据标注新方案:使用SenseVoice自动生成多语言情感标签 引言:语音数据标注的痛点与解决方案 在语音技术(Speech Technology)快速发展
人工智能大模型语音音频微调本地部署
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考