目錄
摘要:
語音情感分析就是將音頻數據通過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。對該模型的優化可以參考自然語言處理中常用的模型,因爲彼此相同的嘛,不管是音頻信息還是文本都需要模型提取語義信息(長文本或者音頻),唯一不同的可能音頻需要提取音調信息等,以保障情感分析的準確性。
相關鏈接:
此文數據集鏈接:https://download.csdn.net/download/weixin_40651515/12393368
MFCC相關知識鏈接:https://blog.csdn.net/weixin_40651515/article/details/105948675
原始數據集官網:http://www.chineseldc.org/