【复现日志】Clustering-Based Speech Emotion Recognition by Incorporating Learned Features and Deep BiLSTM

Clustering-Based Speech Emotion Recognition by Incorporating Learned Features and Deep BiLSTM

复现日志


2021/11/22

阅读文章后初步构思复现内容:

  1. 数据集的下载和管理(注意speaker dependent和speaker independent数据集处理方式是不同的,需要设置一个超参获取数据信息,并存储到numpy数组当中)
  • speaker dependent是将所有文件混合后,随机选取80%数据作为测试和20%数据作为验证和测试。
  • speaker dependent是按照speaker进行五折交叉验证,80%的人用来训练,20%的人用来验证和测试。
    初步考虑将所有文件按照speaker划分文件夹,但是经过观察之后发现对于IEMOCAP数据集来说,session中的男女数据是混杂在一起的,带有“M”和“F”字样,考虑后续获得原始数据后,在训练前转化为语谱图阶段再进行划分,划分后每个session文件夹包含两个speaker,命名为M和F,每个性别文件夹内是两个npy文件,命名为data和label,分别存放聚类后的片段和标签。
  1. 将数据分为片段,窗长为500ms,有25%交叠,每个句子分别处理,存储到numpy数组当中作为处理后的数据,数据的形状大致为(样本数,片段数目,每个片段的数据长度)。
  2. 将上面处理好的数据进行聚类,距离度量使用RBF而不是欧拉距离矩阵,首先确定K值,阈值threshold动态计算[32],具体操作方式看一下该文章,K值确定后,进行K-Means聚类,将每个语段中距离每类最近的一个片段作为key segment,将所有key segment按照speaker存储到npy文件当中备用(上述为特征提取部分,参数一旦改变需要重新运行上面的程序),聚类结果最好做一个可视化,只展示部分数据(考虑4*4窗格)【这里先不加,后面有需要的话,可以添加可视化功能】。
  3. 构建后面的训练模型,CNN与LSTM部分是在一起训练的,可以同时写在一个模型里,但是CNN部分是预训练的,而且是一部分网络,可以在训练之前初始化参数时把预训练参数赋值好,然后LSTM进行空的初始化。这里注意双向LSTM的写法,是两层LSTM,可参考网络资料。LSTM最后一个时间步长的输出加log softmax进行结果预测,这里不要忘记对阈值确定的系数 β \beta β进行寻优。
  4. 训练过程参数初步考虑:
  • epoch = 100
  • learning rate = 0.001
  • optimizer = Adam
  • loss = 对数交叉熵
  • equipment = RTX 3060 GPU
    五折交叉验证需要根据数据集不同进行调整,同样需要设置if选择超参数决定
  1. 最后的结果需要speaker dependent和speaker independent分别的准确率、召回率、F1分数共2 * 3 * 3 (18个)数据,有必要可以加上WA,还有二者对应的混淆矩阵3 * 2(6个),这里只用IEMOCAP的话,需要SD、SI的三个数据3*2共6个数据和两个混淆矩阵。

数据预处理 2021/11/24

首先采用IEMOCAP数据集作为搭建,后来的数据集还未下载,所以暂时先不考虑数据集接口的更换问题。
IEMOCAP数据集的结构如下所示:
在这里插入图片描述
共有5个session,其中共有10种情感,这里文中只用了4种:anger、hapiness、neutral和sadness,所以将其他没用的数据删掉,保留这四种情感即可。首先要进行的是分帧,即将所有的语音数据读取后分成窗长500ms,25%重叠的(0.25*500=125 overlapping)片段,供后续使用,片段不足500ms的部分进行补零。该数据集采样率为16000Hz,那么每个片段
这里考虑几个函数:

  • 音频读取函数:输入文件路径,输出音频读取的numpy数组,每个数是每个采样点的值;(经过查找可以直接使用scipy中的read函数读取到numpy数组当中)
  • 片段切割函数:输入为数据、采样率、窗长和overlap的百分比,输出每个数据的切割结果,放在一个数组当中;
  • 主函数:按文件夹读取音频,切割后将音频存入对应新的文件夹中,最后得到的numpy文件的文件夹组织要和上面一样。
import os  # 用于文件处理
import numpy as np
import math
from scipy.io.wavfile import read


def process(data, sp_r, win_len=500, overlap=0.25):
    """分割语段函数,输入为数据、采样率、窗长和overlap的百分比,输出每个数据的切割结果,放在一个数组当中"""
    num = len(data)  # 语句所有样本点数
    win_num = int(sp_r * (win_len / 1000))  # 计算每个窗中的样本点数目
    gap = math.floor(win_num * (1 - overlap))  # 非重叠部分的长度,需要跳过
    start = 0  # 窗口起始点
    result = []  # 结果列表
    while start < num:
        if start + win_num >= num:  # 如果最后一个窗长超过了原长度
            seg = np.zeros([win_num])  # 新建窗长大小全零数据
            seg[:len(data[start:])] = data[start:]  # 将尾部放入数组
        else:
            seg = data[start: start + win_num]  # 取出窗口内样本点
        result.append(seg)
        start += gap  # 后移gap大小
    return np.array(result)


if __name__ == '__main__':
    data_base = 'IEMOCAP'  # 设置数据库
    sample_rate = 16000  # 数据库对应采样率
    target_name = 'IEMOCAP-preprocess'  # 预处理好的npy文件存放位置

    for dir_path, dir_names, filenames in os.walk(data_base):  # walk是一个游走遍历器,用于遍历该路径下所有文件
        if not os.path.exists(target_name + dir_path[len(data_base):]):
            os.mkdir(target_name + dir_path[len(data_base):])  # 创建新的存放路径
        for name in filenames:  # 对于每一个文件(string类型)
            path = os.path.join(dir_path, name)  # 获得相对地址
            wave_data = read(path)[1]  # 读取音频到numpy数组当中
            processed = process(wave_data, sample_rate)  # 对当前语段进行切割处理并返回切割结果
            new_dir = target_name + path[len(data_base): - (len(name) + 1)]  # 新的保存路径
            if not os.path.exists(new_dir):
                os.mkdir(new_dir)  # 创建新的存放路径
            np.save(new_dir + '\\' + name[:-3] + 'npy', processed)

更改数据库只需要更改data_base、sample_rate和target_name三个参数即可。


聚类 2021/11/25

上面经过预处理后,每个语段被分为若干大小相同的片段,我们而后需要对每个语段进行聚类以找到key segements,并将结果的npy文件保存在另外结构同源数据相同的文件夹中。需要注意的是,聚类需要一个参数K,即每个语段聚类类数,这个参数是通过一个阈值动态确定的,在每个语段中是不同的。
其中文献[32]给出了文中所使用方法Shot boundary detection的具体细节,文章连接:镜头边界检测文中并没有具体说明是怎么计算距离的,所以这里暂时采用欧式距离矩阵计算两个片段间的距离。直接使用scipy中自带的cdist函数计算即可。根据文献[32]中的描述,阈值的设置公式如下,首先计算出所有相邻片段间的距离,对这些距离求均值,前面乘以一个权重作为阈值:

在这里插入图片描述
上面的权重自定义,一般 β \beta

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值