採用LSTM方法進行語音情感分析-代碼詳解

目錄

摘要:

數據集描述:

模型構建

結果分析

結束

相關鏈接:

摘要:

語音情感分析就是將音頻數據通過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/

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章