目录
摘要:
数据集描述:
模型构建
结果分析
结束
相关链接:
摘要:
语音情感分析就是将音频数据通过MFCC(中文名是梅尔倒谱系数(Mel-scaleFrequency Cepstral Coefficients))加载为特征向量形式,然后将其输入进入LSTM神经网络进行抽取语音特征。最后采用softmax分类函数实现情感标签的分类任务。其下游任务是人机交互智能化的一个关键部分。
数据集描述:
一共四种中文情感的数据集。共200条,数据质量不是很好,不是很长的语音文本,但是从这种4s短时的语音中也能听出其情感极性。其数据存储格式为:***.wav ,为wav文件。这个小的demo数据集来源于CASIA汉语情感语料库。但是原始语料库收费的,网上下载的质量也是参差不齐。如果做认真研究的同学,谨慎下载该此样本数据集。还是选择CASIA购买下吧。
模型构建
加载数据集,因为数据集较少,使用了train_test_split函数进行自动分割测试集和训练集。所有代码内都包含注释:
def create_datasets():
num_class = 0 # 加载的语音文件有几种类别
wavs=[] # 训练wav文件集
labels=[] # labels 和 testlabels 这里面存的值都是对应标签的下标,下标对应的名字在labsInd中
testwavs=[] # 测试wav文件集
testlabels=[] # 测试集标签
path="yuyin//"
dirs = os.listdir(path) # 获取的是目录列表
for i in dirs:
print("开始加载:",i)
labsIndName.append(i) # 当前分类进入到标签的名字集
wavs_path=path+"\\"+i
testNum=0 # 当前分类进入了测试集的有几个 ,这里暂定每个分类进100个到测试集
files = os.listdir(wavs_path) # 某个目录下文件的列表
for j in files:
waveData = get_wav_mfcc(wavs_path + "\\" + j)
wavs.append(waveData)
labels.append(labsIndName.index(i))
wavs, testwavs, labels, testlabels = train_test_split(wavs, labels, test_size=0.3, random_state=0)
num_class = len(labsIndName)
print("**********")
print(num_class)
wavs=np.array(wavs)
labels=np.array(labels)
testwavs=np.array(testwavs)
testlabels=np.array(testlabels)
return (wavs,labels),(testwavs,testlabels),num_class
get_wav_mfcc函数代码:
def get_wav_mfcc(wav_path):
f = wave.open(wav_path,'rb')
params = f.getparams()
# print("params:",params)
nchannels, sampwidth, framerate, nframes = params[:4]
strData = f.readframes(nframes)#读取音频,字符串格式
waveData = np.fromstring(strData,dtype=np.int16)#将字符串转化为int
waveData = waveData*1.0/(max(abs(waveData)))#wave幅值归一化
waveData = np.reshape(waveData,[nframes,nchannels]).T
f.close()
### 对音频数据进行长度大小的切割,保证每一个的长度都是一样的【因为训练文件全部是4秒钟长度,16000帧的,所以这里需要把每个语音文件的长度处理成一样的】
data = list(np.array(waveData[0]))
while len(data)>64000:
del data[len(waveData[0])-1]
del data[0]
# print(len(data))
while len(data)<64000:
data.append(0)
# print(len(data))
data=np.array(data)
# 平方之后,开平方,取正数,值的范围在 0-1 之间
data = data ** 2
data = data ** 0.5
return data
模型构建代码:
inputs = Input(shape=(1, feature)) # 输入特征接收维度
drop = Dense(64, activation='relu')(inputs) # 先进行全连接网络承接输入特征
lstm_out = LSTM(64, return_sequences=True)(drop) # 作为LSTM网络的输入
attention_flatten = Flatten()(lstm_out) # 展评特征向量维度
drop2 = Dense(32, activation='relu')(attention_flatten) # 全连接
drop3 = Dense(50, activation='sigmoid')(drop2)
# model.add(Dense(64, activation='relu'))
output = Dense(cell , activation='softmax')(drop3) # 输出类别概率
model = Model(inputs=inputs, outputs=output) # 初始命名训练的模型为model
# [编译模型] 配置模型,损失函数采用交叉熵,优化采用Adadelta,将识别准确率作为模型评估
model.compile(loss='categorical_crossentropy', optimizer='adam',metrics=['accuracy'])#optimizer='adam', loss='binary_crossentropy', metrics=['accuracy']
# validation_data为验证集
history=model.fit(wavs, labels, batch_size=10, epochs=10, verbose=1, validation_data=(testwavs, testlabels))
结果分析
在200个数据集上,train_test_split函数设置的分割比为0.3,测试集准确率可达到70%-80%左右。随便写了个test函数,加载一段中文音频,基本可以做到正确的分类。但是,由于数据样本少,该模型明显出现过拟合了。
结束
对音频特征的提取可以尝试其他深度学习方法。以上全部源码可联系Q525894654。对该模型的优化可以参考自然语言处理中常用的模型,因为彼此相同的嘛,不管是音频信息还是文本都需要模型提取语义信息(长文本或者音频),唯一不同的可能音频需要提取音调信息等,以保障情感分析的准确性。
相关链接:
此文数据集链接:
MFCC相关知识链接:
原始数据集官网:http://www.chineseldc.org/