如何基于HuggingFace音频情感模型子片段预测均值推断整段音频情感
基于子片段预测得分均值实现长音频情感分类(适配Ridzuan/Audio_Emotion_Classifier)
使用HuggingFace的Ridzuan/Audio_Emotion_Classifier模型进行音频情感分类时,模型仅支持输入8秒以内的音频。针对长音频,我们可以将其分割为多个8秒子片段,通过保留每个子片段的全类别预测得分、计算各类别得分均值的方式,得到原长音频的整体情感分类结果。
原代码仅记录了每个子片段的预测标签(如anger、happiness),没有保留各情感类别的具体得分,无法直接计算均值。以下是修改后的完整实现方案:
import os import pandas as pd from tqdm import tqdm from pathlib import Path from pydub import AudioSegment import librosa # 假设classifier和prepare_test已提前完成模型加载与定义 # 处理单个长音频的核心函数 def process_long_audio(file_path, save_split_dir="RESAMPLE/", segment_duration=8000): # 1. 分割长音频为指定时长的子片段(默认8000毫秒=8秒) audio = AudioSegment.from_file(file_path) length_audio = len(audio) print(f"原音频时长(毫秒):{length_audio}") start = 0 counter = 0 num_split = length_audio / segment_duration print(f"预计分割为{num_split:.1f}个子片段") # 确保子片段保存目录存在 os.makedirs(save_split_dir, exist_ok=True) while start < len(audio): end = start + segment_duration # 处理最后一段不足8秒的情况 if end > len(audio): end = len(audio) segment = audio[start:end] filename = f"{save_split_dir}/{counter}_{os.path.basename(file_path).split('.')[0]}.wav" segment.export(filename, format="wav") print(f"已导出子片段:{filename}") counter += 1 start = end # 2. 对当前音频的所有子片段进行预测,保存全类别得分 all_scores = [] emotion_labels = ['anger', 'happiness', 'neutral', 'sadness', 'surprised'] for seg_file in os.listdir(save_split_dir): # 仅处理当前音频分割出的子片段,避免目录中其他文件干扰 if seg_file.endswith(".wav") and seg_file.startswith(f"{counter-1}_"): seg_path = os.path.join(save_split_dir, seg_file) print(f"正在预测子片段:{seg_path}") # 音频预处理(与原逻辑保持一致) data_ori, sample_rate = librosa.load(seg_path) data, _ = librosa.effects.trim(data_ori) # 模型预测并保存全类别得分 test = prepare_test(seg_path) pred = classifier.predict(test) all_scores.append(pred[0].tolist()) # 3. 计算各类别得分均值,确定整体情感 if not all_scores: print("未找到有效子片段,无法计算整体情感") return None # 转换为DataFrame进行均值计算 scores_df = pd.DataFrame(all_scores, columns=emotion_labels) mean_scores = scores_df.mean().reset_index() mean_scores.columns = ['Emotion', 'Mean_Score'] # 提取得分最高的情感作为整体结果 overall_emotion = mean_scores.loc[mean_scores['Mean_Score'].idxmax(), 'Emotion'] print("\n原音频整体情感分类结果:") print(mean_scores) print(f"最终分类:{overall_emotion}") # 可选:清理临时子片段文件,释放磁盘空间 for seg_file in os.listdir(save_split_dir): if seg_file.endswith(".wav") and seg_file.startswith(f"{counter-1}_"): os.remove(os.path.join(save_split_dir, seg_file)) return overall_emotion, mean_scores # 批量处理目标目录下的所有WAV音频 for file in tqdm(Path("D:/program/SER_DATA_sample/exg/").glob("**/*.wav")): print(f"\n===== 处理音频:{file} =====") process_long_audio(file)
关键修改说明
- 保留全类别得分:不再仅提取单个预测标签,而是保存每个子片段的完整得分数组,为均值计算提供基础数据。
- 隔离子片段处理:预测阶段仅处理当前音频分割出的子片段,避免目录中其他遗留文件干扰结果。
- 均值计算逻辑:通过
pandas直接计算各类别得分的平均值,直观输出所有类别的平均得分,并选取最高得分对应的情感作为整体分类结果。 - 临时文件清理:添加可选的子片段清理逻辑,避免临时文件占用磁盘空间。
内容的提问来源于stack exchange,提问作者Sneha T S
相关产品推荐
相关产品推荐

