# RNNoise
###### tags: `embedded_master`
###### <Contributed by [`huang-me`](https://github.com/huang-me)>
## Noise suppression
以下是論文中提及的常見的 Noise supperssion 分析方式,主要是先利用 VAD 模組區分有無人講話的部分。之後再將結果傳遞給 Noise Spectral Estimation 模組計算噪音的頻譜特徵。最後把前面兩個模組的結果結合,利用音訊的特徵減去噪音的特徵以得到抑制雜訊的效果。

不過,看似簡單的結構卻因為每個模組都需要很仔細的調整演算法中的參數,否則很容易使得整個系統出現問題,也開始使用深度學習讓幫助測試參數的設定。
## Digital signal processing
**IIR:**
- Define: $y[k] = \sum_{p=0}^N{a_p}x[k-p] + \sum_{p=1}^M{b_p}y[k-p]$
> 遞迴使用前面N個狀態以及M個結果以預測本次的結果,預測 $y[k]$ 需要用到 $y[k-1]$ 而計算 $y[k-1]$ 又需要 $y[k-2]$ ,以此類推,因此需要無限多項來表示,也是其名 Infinite 由來。[color=skyblue]
**FIR:**
- Define: $y[k] = \sum_{i=0}^{N-1}{h[i]}{x[k-i]}$
> 利用輸入延時 n 次,並且加權 $h[i]$ 之後總和得到的結果即為此時刻的輸出值。
FIR & IIR 特性:
FIR 有線性相位之特性,也比較穩定,不過相對的也需要比較複雜的計算(需要比較高的階層數以滿足濾波條件)
IIR 則有計算效率比較高的優點,不過需要整個序列的輸入以及輸出當作 input 以計算目前狀態的輸出,除此之外還有非線性變化的缺點且有可能不穩定。
**FFT:**
- 因為 DFT 所需要的計算量過大($N^2$ 次乘法運算),因此利用將序列切一半計算完之後再合併為原序列的 DFT,如此可以大幅減低乘法的計算量,如果再將已經切過的序列再做一次對切又可以再減少計算量,因而只需要 $\frac{N}{2}\times\log_2{N}$ 次乘法計算即可。
> 當 $N^2/2 \gg N$ 可以減少約一半的計算時間。
## Neural Networks
- RNN
輸入目前狀態以及 feature,基於目前的 state 以及輸入直接計算新的 hidden state (${h_t} = {W_x}\times{x_t} + {W_h} \times {h_{t-1}} + b$),再基於新的 state 推算新的 output (${y_t}=W_y \times h_t + b_y$)。
- Problems: 因為==矩陣不停相乘==使得後面的節點無法參與更新,造成RNN 無法順利學習。
- LSTM
==Input gate== 判斷輸入的 feature 是否值得保留到 LSTM 中。
==Forget gate== 決定是否刪除之前記憶的狀態。
==Output gate== 決定本次 input 的權重,因為並不是所有的 input 都重要到需要放進 hidden state 中。
$i_t=\sigma(W^{(i)}x_t+U^{(i)}h_{t-1})$
$f_t=\sigma(W^{(t)}x_t+U^{(t)}h_{t-1})$
$o_t=\sigma(W^{(o)}x_t+U^{(o)}h_{t-1})$
==new memory cell== 計算本次 input 的狀態
$\widetilde{c_t}=\tanh(W^{(c)}x_t+U^{(c)}h_{t-1})$
利用 input gate & forget gate 計算真正的 memory cell
$c_t=f_t\circ c_{t-1}+i_t \circ\widetilde{c_t}$
最後更新新的 hidden state
$h_t=o_t\circ\tanh(c_t)$
- GRU
將 input gate 以及 forget gate 合併為 update gate,並且把 cell state 以及 hidden state 進行合併以減少記憶體用量,同時也加快了收斂的速度。
==update gate== 決定哪些部分保留為舊的 state 而剩餘的部分則更新為新的 state。
==reset gate== 決定是否利用之前的 state 參與計算新的 state。
## 名詞
- bark scale:\
在 bark scale 之下,實際相同距離與感知相同距離一致,也是人類聽覺擅於感知的24個頻帶。人耳對高頻的解析能力比較差,因此我們可以將高頻的部分切割的比較寬,低頻部分則較為緊密。\
不過論文中提到因為資料量不夠所以在 RNNoise 中使用的 band 低頻的部分沒有切割的如 bark scale 細。(RNNoise 中把所有頻段切割為 22 個 band)\

- cepstral mean normalization\
利用傅裡葉轉換、log以及傅裡葉逆變換將音頻的頻譜做平滑處理,藉此過濾掉一些雜音。(RNNoise 中沒有使用)
## 方法
RNNoise 利用的是一個 hybrid approach,並不是將所有的訊號處理都讓機器學習做主(利用機器學習模擬訊號處理的結果),而是先做了一般常用的數位訊號處理再將截取出的資訊交付給機器學習,這樣的做法不止可以節省記憶體的使用,同時也加快了執行的速度。
### 系統架構
整個 RNNoise 的架構如下圖:

主要的流程:先將訊號進行取樣後,套用 FFT 將訊號從時域轉換為頻域,以便後面做噪音、人聲特徵截取,再將截取到的特徵傳遞給 RNN 進行訓練,得到消除雜訊的音頻之後再利用 IFFT(inverse FFT) 將訊號轉回時域。
### 深度學習架構
RNNoise 的深度學習部分架構如下圖:

利用沒有噪音的 clean speech 與噪音混合後做特徵提取,並且把 clean speech 當作 ground truth,以訓練 RNN 模型。