Nnet3配置中的上下文和塊大小
簡介
本頁討論了nnet3配置中關於解碼和訓練的塊大小以及左右上下文的某些術語。這將有助於理解一些腳本。目前,從腳本角度來看,沒有任何關於nnet3的"概述"文檔,所以這是nnet3唯一的文檔。
基礎
如果您已閱讀了"nnet3"配置的以前的文檔,您會發現"nnet3"不僅支持簡單的前饋DNN,還可以實現在網絡內層進行時間拼接(幀拼接)的時延神經網絡(TDNN)並且還用於recurrent拓撲(RNN,LSTM,BLSTM等)。所以nnet3有時間軸的概念。下面我們確定一些術語。
左右上下文
假設我們想要一個網絡來計算特定時間索引的輸出;具體來說,假設時間t=154,在網絡內部進行幀拼接(或任何其他與"t"索引無關的內容),如果沒有給出當前幀的左右一定范圍的幀,則可能無法計算當前幀的輸出。例如,如果沒有看到t = 150到t = 157這個范圍內的幀,則可能無法計算輸出。在這種情況下(掩飾細節),我們會說網絡有一個左上下文4和右上下文3。上下文的實際計算有點復雜,因為它必須考慮到特殊情況,例如奇數和偶數"t"值的情況是不同的。
在有recurrent拓撲的情況下,除了"所需的"左右上下文外,訓練或解碼時,我們還要給予"額外的"上下文。對於這種拓撲,網絡可以利用超出所需上下文的上下文。在腳本中,通常會看到名為extra-left-context和extra-right-context的變量,這意味着"除了需要的內容之外,我們將提供的上下文的數量"。
在某些情況下,左上下文和右上下文意味着添加到塊(chunk)中的總的左上下文和總的右上下文,即
左上下文=模型左上下文+額外左上下文
右上下文=模型右上下文+額外右上下文
因此,在某些情況下,您需要搞清楚一個變量指的是模型的左右上下文還是數據塊的左右上下文。
在Kaldi5.0及更早版本中,數據塊中的左右上下文不受塊大小在開頭或結尾的影響;在最后我們用第一或最后一幀的副本填充輸入。這意味着對於recurrent拓撲,我們可能會用很多幀(最多40個左右)來填充語句的開始或結束。這沒有意義而且很奇怪。在版本5.1和更高版本中,您可以指定extra-left-context-initial和extra-right-context-final,允許話語的開始/結束具有不同的上下文量。如果您指定這些值,通常將它們都指定為0(即沒有額外的上下文)。但是,為了與舊版本的后台兼容,它們通常默認為-1(意思是復制默認的左上方和右上方)。
塊大小
塊大小是我們在訓練或解碼中每個數據塊的(輸出)幀的數量。在get_egs.sh腳本和train_dnn.py中,它也被稱為frames-per-eg(在某些上下文中,這與塊大小不同;見下文)。在解碼中,我們把它稱為frame-per-chunk。
非循環,非chain模型的例子
對於使用交叉熵目標函數訓練的前饋網絡或TDNN等非常簡單的網絡類型,我們在幀級別上打亂整個數據集,並且我們一次只訓練一幀。為了使大部分訓練做順序I/O,需要在幀級別上對數據進行隨機化。然而,當需要10幀的左右上下文時,我們必須給出左右上下文中具體是哪些幀,當我們生成訓練示例時,數據量會增加20倍左右。為了解決這個問題,我們包括一系列時間值的標簽,由frame-per-eg(通常為8)控制,並包括足夠的左/右上下文,我們可以在這8個幀中的任何一個上訓練。然后,當我們訓練模型時,任何給定的訓練工作將選擇其中一個8幀進行訓練。
經常性或連鎖案例
在RNN或LSTM模型或"Chain"模型中,我們總是訓練相當大的塊(通常在40到150幀的范圍內)。這被稱為塊大小。當我們解碼時,我們還通常在相當大的數據塊(如30,50或100幀)上評估神經網絡。這通常被稱為每幀的幀。對於經常性網絡,我們傾向於確保在訓練和解碼中大塊/每幀/左右上下文和右上下文大致相同,因為這通常給出最佳結果(盡管有時最好使解碼中的上下文值稍大一些)。人們可能會期望在解碼時間更長的情況下總是會更好,但是並不總是這樣(然而,請參見下面的循環解碼,我們在這里提到一個方法)。
塊大小與幀 - 子采樣因子的相互作用
在輸出處有幀子采樣的情況下(如鏈模型),塊大小仍然以"t"的倍數進行測量,我們確保(通過在代碼中舍入),它是幀抽樣因子。請記住,如果塊大小為90,幀子采樣因子為3,那么我們只對每個90幀的塊估計30個不同的輸出索引(例如t = 0,t = 3 ... t = 87)。