/Speech-Emotion-Recognition

Speech emotion recognition using LSTM, SVM and MLP | 语音情感识别

Primary LanguagePython

Speech Emotion Recognition

用 SVM、MLP、LSTM 进行语音情感识别。

改进了特征提取方式,识别准确率提高到了 80% 左右。原来的版本的存档在 First-Version 分支

English Document

 

Environment

Python 3.6.7

 

Structure

├── Common_Model.py        // 所有模型的通用部分(即所有模型都会继承这个类)
├── ML_Model.py            // SVM & MLP 模型
├── DNN_Model.py           // LSTM 模型
├── Utils.py               // 加载模型、绘图(雷达图、频谱图、波形图)
├── Opensmile_Feature.py   // Opensmile 提取特征
├── Librosa_Feature.py     // librosa 提取特征
├── SER.py                 // 调用不同模型进行语音情感识别
├── File.py                // 用于整理数据集(分类、批量重命名)
├── Config.py              // 配置参数
├── cmd.py                 // 使用 argparse 从命令行读入参数
├── cmd_example.sh         // 命令行输入样例
├── Models                 // 存储训练好的模型
└── Feature                // 存储提取好的特征

 

Requirments

Python

Tools

 

Datasets

  1. RAVDESS

    英文,24 个人(12 名男性,12 名女性)的大约 1500 个音频,表达了 8 种不同的情绪(第三位数字表示情绪类别):01 = neutral,02 = calm,03 = happy,04 = sad,05 = angry,06 = fearful,07 = disgust,08 = surprised。

  2. SAVEE

    英文,4 个人(男性)的大约 500 个音频,表达了 7 种不同的情绪(第一个字母表示情绪类别):a = anger,d = disgust,f = fear,h = happiness,n = neutral,sa = sadness,su = surprise。

  3. EMO-DB

    德语,10 个人(5 名男性,5 名女性)的大约 500 个音频,表达了 7 种不同的情绪(倒数第二个字母表示情绪类别):N = neutral,W = angry,A = fear,F = happy,T = sad,E = disgust,L = boredom。

  4. CASIA

    汉语,4 个人(2 名男性,2 名女性)的大约 1200 个音频,表达了 6 种不同的情绪:neutral,happy,sad,angry,fearful,surprised。

 

Usage

Prepare

安装依赖:

pip install -r requirements.txt

安装 Opensmile

 

Configuration

Config.py 中配置参数。

其中 Opensmile 标准特征集目前只支持:

如果需要用其他特征集,可以自行修改 FEATURE_NUM 参数。

 

Command Line Arguments

Long option Option Description
--option -o 操作 [ p:预测音频情感 / t:训练模型 ] [ 必需 ]
--model_type -mt 模型种类 [ svm / mlp / lstm ] [ 默认:svm ]
--model_name -mn 要保存或加载的模型文件名 [ 默认:default ]
--load -l 是否加载已有特征 [ 0:不加载 / 1:加载 ] [ 默认:1 ]
--feature -f 提取特征的方式 [ o:Opensmile / l:librosa ] [ 默认:o ]
--audio -a 要预测的音频的路径 [ 默认:default.wav ]

例子:

  • 训练:

    python3 cmd.py -o t -mt 'svm' -mn 'SVM' -l 1 -f 'o'
  • 预测:

    python3 cmd.py -o p -mt 'svm' -mn 'SVM' -f 'o' -a [audio path]

cmd_example.sh 中有更多的例子。

 

Train

数据集路径可以在 Config.py 中配置,相同情感的音频放在同一个文件夹里(可以考虑使用 File.py 整理数据),如:

└── Datasets
    ├── Angry
    ├── Happy
    ├── Sad
    ...
from SER import Train

'''
输入:
	model_name: 模型名称(SVM / MLP / LSTM)
	save_model_name: 保存模型的文件名
	if_load: 是否加载已有特征(True / False)
	feature_method: 提取特征的方法('o': Opensmile / 'l': librosa)
输出:
	model: 训练好的模型
'''
model = Train(model_name, save_model_name, if_load, feature_method)

 

Load Model

from Utils import load_model

'''
输入:
	load_model_name: 要加载的模型的文件名
	model_name: 模型名称(SVM / MLP / LSTM)
输出:
	model: 训练好的模型
'''
model = load_model(load_model_name, model_name)

 

Predict

from SER import Predict
'''
输入:
	model: 已加载或训练的模型
	model_name: 模型名称(SVM / MLP / LSTM)
	file_path: 要预测的文件路径
	feature_method: 提取特征的方法('o': Opensmile / 'l': librosa)
输出:
	预测结果和概率
'''
Predict(model, model_name, file_path, feature_method)

 

Extract Feature

Opensmile 提取的特征保存在 .csv 文件中,librosa 提取的特征保存在 .p 文件中。

import Librosa_Feature as of
import Opensmile_Feature as of

'''
输入:
    data_path: 数据集文件夹路径或要预测的音频路径
    feature_path: 保存特征的路径
    train: 是否为训练数据
'''

'''
训练数据:
    输出: 训练数据、测试数据特征和对应的标签
'''
# Opensmile
x_train, x_test, y_train, y_test = of.get_data(data_path, feature_path, train = False)
# librosa
x_train, x_test, y_train, y_test = lf.get_data(data_path, feature_path, train = False)

'''
预测数据:
    输出: 预测数据特征
'''
# Opensmile
test_feature = of.get_data(data_path, feature_path, train = True)
# librosa
test_feature = lf.get_data(data_path, feature_path, train = True)

 

Load Feature

import Librosa_Feature as lf
import Opensmile_Feature as of

'''
输入:
    feature_path: 特征文件路径
    train: 是否为训练数据
'''

'''
训练数据:
    输出: 训练数据、测试数据和对应的标签
'''
# Opensmile
x_train, x_test, y_train, y_test = of.load_feature(feature_path, train = True)
# librosa
x_train, x_test, y_train, y_test = lf.load_feature(feature_path, train = True)

'''
预测数据:
    输出: 预测数据特征
'''
# Opensmile
test_feature = of.load_feature(feature_path, train = False)
# librosa
test_feature = lf.load_feature(feature_path, train = False)

 

Radar Chart

画出预测概率的雷达图。

来源:Radar

from Utils import Radar
'''
输入:
    data_prob: 概率数组
'''
Radar(result_prob)

 

Play Audio

播放一段音频

from Utils import playAudio
playAudio(file_path)

 

Plot Curve

画训练过程的准确率曲线和损失曲线。

from Utils import plotCurve
'''
输入:
    train(list): 训练集损失值或准确率数组
    val(list): 测试集损失值或准确率数组
    title(str): 图像标题
    y_label(str): y 轴标签
'''
plotCurve(train, val, title, y_label)

 

Waveform

画出音频的波形图。

from Utils import Waveform
Waveform(file_path)

 

Spectrogram

画出音频的频谱图。

from Utils import Spectrogram
Spectrogram(file_path)

 

Acknowledgements

@Zhaofan-Su@Guo Hui