語音識別-TDNN


近來在了解卷積神經網絡(CNN),后來查到CNN是受語音信號處理中時延神經網絡(TDNN)影響而發明的。本篇的大部分內容都來自關於TDNN原始文獻【1】的理解和整理。該文寫與1989年,在識別"B", "D", "G"三個濁音中得到98.5%的准確率,高於HMM的93.7%。是CNN的先驅。

 

普通神經網絡識別音素

在講TDNN之前先說說一般的神經網絡的是怎樣識別音素的吧。假設要識別三個輔音"B", "D", "G",那么我們可以設計這樣的神經網絡:

圖1

其中輸入0-12代表每一幀的特征向量(如13維MFCC特征)。那么有人可能會問了,即使在同一個因素"B"中,比如"B"包含20幀,那么第1幀與第15幀的MFCC特征也可能不一樣。這個模型合理嗎?事實上,"B"包含的20幀MFCC特征雖然有可能不一樣,但變化不會太大,對於因素還是有一定區分度的,也就是說這個模型湊合湊合還能用,但效果不會非常好。GMM模型可以用這種模型來解釋。

 

時延神經網絡(TDNN)

考慮到上述模型只用了一幀特征,那么如果我們考慮更多幀,那么效果會不會好呢?

好,那么我們設計一個包含多幀的神經網絡,如圖2我們考慮延時為2,則連續的3幀都會被考慮。其中隱含層起到特征抽取的作用,輸入層每一個矩形內共有13個小黑點,代表該幀的13維MFCC特征。假設有10個隱含層,那么連接的權重數目為3*13*10=390。

圖2

為了結構緊湊顯示,我們將其重繪為圖3

圖3

圖3與圖2是等價的。其中每條彩色線代表13*10=130個權重值。三條彩色線390個權重。也有資料稱之為濾波器。

好,如果時間滾滾向前,我們不斷地對語音幀使用濾波器,我們可以得到圖4

圖4

 

這就是延時神經網絡的精髓了!其中綠色的線權值相同,紅色的線權值相同,藍色的線權值相同。相當於把濾波器延時。輸入與隱層共390個權值變量待確定。

每個隱層矩形內包含10個節點,那么每條棕色的線包含10個權值,假設輸出層與隱層的延時為4,則接收5個隱層矩形內的數據,那么隱層與輸出層合計權值為10*5*3=150。權值非常少!所以便於訓練。

 

下面就不難理解文獻【1】上的圖了。思想與上文一樣,不過文章多用了一層隱層(多隱層有更強的特征提取和抽象能力)

圖5

介紹一下他的做法。Input Layer為語譜圖,黑塊為大值,灰塊為小值。輸入層縱向為經過mel濾波器的16個特征(沒用MFCC),橫向為幀。Input Layer 的延時為2,映射到Hidden Layer 1的關系為16*3 -> 8,權值個數為384。Hidden Layer 1 的延時為4,映射到Hidden Layer 2的關系為8*5 -> 3,權值個數為120。Hidden Layer 2 的延時為8,映射到輸出層的關系為3*9 -> 3,權值個數為81。合計權值為384+120+81=585。輸出的三個單元分別代表"B", "D", "G"的得分。

 

訓練方法

(1)和傳統的反向傳播算法一樣。

(2)TDNN有快速算法,有興趣的讀者可以搜索。

 

小結

總結TDNN的優點有以下:

(1)網絡是多層的,每層對特征有較強的抽象能力。

(2)有能力表達語音特征在時間上的關系。

(3)具有時間不變性。

(4)學習過程中不要求對所學的標記進行精確的時間定為。

(5)通過共享權值,方便學習。

 

參考資料

【1】Waibel A, Hanazawa T, Hinton G, et al. Phoneme recognition using time-delay neural networks[J] (TDNN的原始論文,想了解的同學請細看)

 【2】趙力 《語音信號處理》 chap 6.3. 6 (也是對上文的一些解釋和補充說明)

 【3】https://blog.csdn.net/richard2357/article/details/16896837

接下來讀者可以看卷積神經網絡了(CNN),相信對CNN的理解會有所幫助。

 

tensorflow的實現

 

import tensorflow as tf

import numpy as np

tf.set_random_seed( 922)
np.random.seed( 0)

def tdnn(inp, n_class):
    h1_kernel_size = 3
    h1_filters = 8
    h1 = tf.layers.conv1d(inp, h1_filters, h1_kernel_size)# 1,15(nframes),16(features)
    #核的大小,其實就是上下文的總長度;
    #因為valid,所以輸入時15,核大小為3,所以丟失2個,因此為13
    #又因為有8個核,所以輸出的第三個參數為8
    #核的大小為3,實際上權重參數大小為(3,16)
    #1個上下文的輸人為(3,16)
    #做一次卷積,輸出為1;隨着滑動窗口處理13次,所以第二個參數為13,最后核的個數有8個,所以第三個參數為8
#一次的輸入大小的1,3,16 #輸出的節點數等於核個數8; 所以總的權重連接數為16*8*3
權值共享體現在哪里?在滑動窗口的時候,16*3*8的權重矩陣參數是相同的
print(h1.shape)#1, 13(因為核為3,valid), 8(filter number) h2_kernel_size = 5 h2_filters = n_class h2 = tf.layers.conv1d(h1, h2_filters, h2_kernel_size) print(h2.shape) h2 = tf.transpose(h2, [ 0, 2, 1]) print(h2.shape) output = tf.squeeze(tf.layers.dense(h2, 1, tf.sigmoid))#3個節點 sigmoid激活函數,輸出類似概率值 return output if __name__ == '__main__': bs = 1 n_frame = 15 n_feature = 16 n_class = 3 inp=tf.placeholder(tf.float32, shape=[bs, n_frame, n_feature])#1*15*16 output = tdnn(inp, n_class)#輸入, 3個類別 with tf.Session() as sess: i = np.random.normal(size=(bs, n_frame, n_feature))#1 15 16 sess.run(tf.global_variables_initializer()) o = sess.run(output, feed_dict={inp: i}) print('input:', i.shape) print('o:',o)#3個不同類別的概率值 print(np.array(o).shape) # (3,)printnp.array(o) # [ 0.64834243 0.91836888 0.50499392]

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM