Kaldi特徵提取之-VAD
背景
VAD即 Voice Activity Detection, 用於檢測靜音和非靜音。通過使用VAD,我們可以找到有效語音段,剔除靜音段,在語音識別等過程中可以大大減少要處理的數據量。VAD通常有多種方法,簡單的如幀能量或者幀幅度,複雜的還可以用神經網絡。下圖是一段語音的波形圖,VAD可以將圖中紅色框內的地方剔除。
VAD檢測
注意:以下所有方法都以幀爲單位進行,幀長度爲N。
方法一: 幀幅度(絕對值和)
這種方法計算最爲簡單,但是如果背景聲音比較大,則效果會比較差,計算公式如下:
amplitudesi=∑j=1N|framei(j)|
對比上下兩幅圖可以看到一些規律,靜音區對應的幅度較低,通過設置low_thres和high_thres 可以過濾掉一部分靜音。方法二:幀能量(平方和)
這種計算方法也比較簡單,和方法一的性質基本一致,但是可以增大聲音強度的對比度。計算公式如下:
energyi=∑j=1Nframei(j)2
對比中間和最下邊的圖,可以發現方法二加強了聲音幅度的對比度。同樣的,還是通過設置合理的low_thres和high_thres過濾掉一部分靜音。方法三:短時過零率分析
短時過零率表示一幀語音中語音信號波形穿過橫軸(零電平)的次數。對於連續語音信號(模擬信號),過零意味着時域波形通過時間軸;對於離散信號(數字信號),相鄰採樣值改變符號即意味着過零,過零率就是樣本符號改變的次數。計算公式如下:
從圖中可以看出,過零率在沒有噪聲的位置表現良好,但是在有噪聲的地方表現並不好,坑干擾能力比較差。Zi=12∑j=2N|sgn(framei(j))−sgn(framei(j−1))|,其中sgn爲符號函數 方法四: 能量+滑動窗口(Kaldi)
首先,需要說明的是,這裏的能量是方法一或者方法二的計算結果,這裏我們假設使用的是方法二計算。代碼如下:
void ComputeVadEnergy(const VadEnergyOptions &opts, const MatrixBase<BaseFloat> &feats, Vector<BaseFloat> *output_voiced) { int32 T = feats.NumRows(); output_voiced->Resize(T); if (T == 0) { KALDI_WARN << "Empty features"; return; } Vector<BaseFloat> log_energy(T); log_energy.CopyColFromMat(feats, 0); // column zero is log-energy. BaseFloat energy_threshold = opts.vad_energy_threshold; if (opts.vad_energy_mean_scale != 0.0) { KALDI_ASSERT(opts.vad_energy_mean_scale > 0.0); energy_threshold += opts.vad_energy_mean_scale * log_energy.Sum() / T; } KALDI_ASSERT(opts.vad_frames_context >= 0); KALDI_ASSERT(opts.vad_proportion_threshold > 0.0 && opts.vad_proportion_threshold < 1.0); for (int32 t = 0; t < T; t++) { const BaseFloat *log_energy_data = log_energy.Data(); int32 num_count = 0, den_count = 0, context = opts.vad_frames_context; for (int32 t2 = t - context; t2 <= t + context; t2++) { if (t2 >= 0 && t2 < T) { den_count++; if (log_energy_data[t2] > energy_threshold) num_count++; } } if (num_count >= den_count * opts.vad_proportion_threshold) (*output_voiced)(t) = 1.0; else (*output_voiced)(t) = 0.0; } }
參數 意義 vad_energy_threshold 能量閾值 vad_energy_mean_scale 平均能量的放大(縮小)係數 vad_frames_context 窗口長度的一半 vad_proportion_threshold 窗口內超過閾值的幀數的比例 效果如下圖:
與其他方法不同之處在於,kaldi利用了前後幀的關係,而不是孤立的單獨考察每一幀。
方法五 : 神經網絡
- 隨着神經網絡的興起,也有些人開始用CNN、DNN做VAD。用神經網絡的優點是:神經網絡表達能力強大,具有良好的抗噪聲能力,而且我們可以把識別範圍外的所有其他都當做是Sil,當然這種情況下就不再是嚴格意義上的VAD;缺點是:計算量比較大,有點得不償失的感覺。
難點分析
- 上面幾種方法大都需要設置各種閾值,這是一個難點。閾值太小,過濾效果不明顯;閾值太大,可能會過濾掉有效語音。實際使用中,通常閾值會設置的比較鬆,避免過濾掉有用信息。合理的閾值設置,需要考慮實際使用情況,用一個較大的數據集進行統計,得到一個合理的閾值。