You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用原始RAVDESS数据集训练语音情感识别模型遇librosa参数错误求助

解决RAVDESS原始数据集训练及预测问题

一、错误根源分析

你遇到的librosa.util.exceptions.ParameterError: Invalid shape for monophonic audio: ndim=2, shape=(172972, 2)错误,核心原因很明确:

  • 教程使用的降采样RAVDESS子集已经将所有音频转为单声道(1通道)
  • 而Zenodo上的原始RAVDESS数据集是立体声(2通道),代码中X = sound_file.read(dtype="float32")读取后得到二维数组(shape为(采样点数, 2)),但librosa的音频处理函数(如stftmfcc)默认要求输入单声道的一维数组,因此触发参数错误。

二、修复训练代码(适配原始数据集)

修改extract_feature函数,添加立体声转单声道的核心逻辑,同时优化参数传递避免潜在问题,完整代码如下:

import librosa
import soundfile
import os
import glob
import pickle
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.neural_network import MLPClassifier
from sklearn.metrics import accuracy_score
from collections import Counter

# 情感映射保持不变
emotions = {
 '01': 'neutral',
 '02': 'calm',
 '03': 'happy',
 '04': 'sad',
 '05': 'angry',
 '06': 'fearful',
 '07': 'disgust',
 '08': 'surprised'
}
observed_emotions = ['calm', 'happy', 'fearful', 'disgust']

def extract_feature(file_name, mfcc, chroma, mel):
    with soundfile.SoundFile(file_name) as sound_file:
        X = sound_file.read(dtype="float32")
        sample_rate = sound_file.samplerate
        
        # 关键修复:将立体声转为单声道(取两个通道的均值,也可直接取第一个通道X[:, 0])
        if X.ndim > 1:
            X = np.mean(X, axis=1)
        
        # 可选但重要:统一采样率为RAVDESS原始的48kHz(避免预测时采样率不匹配)
        if sample_rate != 48000:
            X = librosa.resample(X, orig_sr=sample_rate, target_sr=48000)
            sample_rate = 48000
            
        stft = np.abs(librosa.stft(X)) if chroma else None
        result = np.array([])
        
        if mfcc:
            mfccs = np.mean(librosa.feature.mfcc(y=X, sr=sample_rate, n_mfcc=40).T, axis=0)
            result = np.hstack((result, mfccs))
        if chroma:
            chroma = np.mean(librosa.feature.chroma_stft(S=stft, sr=sample_rate).T, axis=0)
            result = np.hstack((result, chroma))
        if mel:
            # 显式指定y参数,避免librosa参数顺序歧义
            mel = np.mean(librosa.feature.melspectrogram(y=X, sr=sample_rate).T, axis=0)
            result = np.hstack((result, mel))
        return result

def load_data(test_size=0.2):
    x, y = [], []
    for file in glob.glob("C:\\Users\\raj.pandey\\Desktop\\speech-emotion-recognition\\Dataset\\Actor_*\\*.wav"):
        file_name = os.path.basename(file)
        emotion = emotions[file_name.split("-")[2]]
        if emotion not in observed_emotions:
            continue
        feature = extract_feature(file, mfcc=True, chroma=True, mel=True)
        x.append(feature)
        y.append(emotion)
    
    # 可选:打印训练集情感分布,检查是否均衡
    print("训练集情感分布:", Counter(y))
    
    return train_test_split(np.array(x), y, test_size=test_size, random_state=9)

# 后续训练逻辑保持不变
x_train, x_test, y_train, y_test = load_data(test_size=0.20)
# 添加class_weight='balanced'解决样本不均衡问题
model = MLPClassifier(alpha=0.01, batch_size=256, epsilon=1e-08, hidden_layer_sizes=(300,), learning_rate='adaptive', max_iter=500, class_weight='balanced')
model.fit(x_train, y_train)
y_pred = model.predict(x_test)
accuracy = accuracy_score(y_true=y_test, y_pred=y_pred)
print("Accuracy: {:.2f}%".format(accuracy * 100))

三、解决预测总是输出"fearful"的问题

这个问题通常由以下几个原因导致,对应解决方案:

1. 训练集情感分布不均衡

RAVDESS数据集的部分情感样本数可能偏少,导致模型偏向预测样本数量最多的类别(比如fearful)。

  • 解决方案:我们已经在MLP初始化时添加了class_weight='balanced'参数,让模型自动调整类别权重;也可以手动进行过采样/欠采样来平衡数据集。

2. 预测音频与训练数据格式不匹配

  • 确保预测音频的采样率为48kHz(和训练数据一致),上面的extract_feature函数已经添加了自动重采样逻辑;
  • 确保预测音频是单声道(函数也会自动处理);
  • 避免使用情感表达不明显的TTS音频测试,建议先用RAVDESS数据集中已知情感的文件验证模型是否准确。

3. 模型训练不充分

可以尝试调整MLP的参数优化效果:

  • 增加hidden_layer_sizes(比如改为(500, 200));
  • 提高max_iter(比如改为1000);
  • 调整alpha值(正则化参数)防止过拟合。

四、测试预测功能

修改后的代码可以直接处理.wav格式的预测文件,包括原始RAVDESS的立体声文件和转换后的音频:

# 测试预测
tar_file = "C:\\Users\\raj.pandey\\Desktop\\speech-emotion-recognition\\Dataset\\newactor\\pls-hold-while-try.wav"
new_feature = extract_feature(tar_file, mfcc=True, chroma=True, mel=True)
z_pred = model.predict(np.array([new_feature]))
print("预测结果: ", z_pred)

内容的提问来源于stack exchange,提问作者El_Dorado

火山引擎 最新活动