You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 05:07:07