RNNoise – 基於深度學習的降噪方案

更多RNNoise相關文章請查看 RNNoise學習和翻譯系列

 

上圖顯示了噪聲抑制前後(上圖爲原語音, 下圖爲處理後)音頻的聲譜圖。

這是RNNoise

該演示演示了RNNoise項目,展示瞭如何將深度學習應用於噪聲抑制。主要思想是將經典信號處理與深度學習相結合,以創建一種小型且快速的實時噪聲抑制算法。無需昂貴的GPU, 它可以在樹莓派(Raspberry Pi)上輕鬆運行。它比傳統的噪聲抑制系統更簡單(更容易調音),並且聽起來更好。

噪聲抑制

噪聲抑制是語音處理中的一個相當老的話題 ,至少可以追溯到70年代。顧名思義,該想法是獲取噪聲信號並消除儘可能多的噪聲,同時使目標語音的失真最小。

這是常規噪聲抑制算法的概念圖。語音活動檢測(VAD)模塊可以檢測信號何時包含語音以及何時只是噪音。噪聲頻譜評估模塊(NSE) 使用它來計算噪聲的頻譜特性(每個頻率多少功率)。然後,知道了噪聲的樣子,就可以譜減模塊(SS)從輸入音頻中減去噪聲(聽起來並不簡單)。

從上圖可以看出,噪聲抑制看起來很簡單:只有三個概念上簡單的任務就完成了,對吧?對錯參半吧!隨便一個電子工程專業的本科生都可以編寫一種有效的噪聲抑制算法,有時……。有難度的是要在各種噪音條件下始終保持良好的性能。這就需要對許多特殊情況和奇怪信號, 非常仔細地調整算法中的每個旋鈕,並進行大量測試。總會有一些奇怪的信號會引起問題並需要更多的調整,而且總是這種修復總是沒完沒了。這是50%的科學,50%的藝術。我以前曾在speexdsp庫中也使用過噪聲抑制器。它也能用,但是效果不是很好。

深度學習和遞歸神經網絡

深度學習是人工神經網絡的新版本。儘管這些技術自60年代就已經存在,但近年來發生了一些新變化:

  1. 現在我們知道如何超過兩個隱藏層的深度網絡
  2. 我們知道如何讓遞歸網絡記住過去的模式
  3. 我們有計算資源來實際訓練他們

遞歸神經網絡(RNN)在這裏非常重要,因爲它們使建模時間序列成爲可能,而不僅僅是獨立考慮輸入和輸出幀。這對於抑制噪聲尤爲重要,因爲我們需要時間來很好地估計噪聲。長期以來,RNN的能力受到嚴重限制,因爲它們無法長時間保存信息,並且由於在時間上反向傳播時涉及的梯度下降過程效率非常低(梯度消失問題)。門控單元的發明解決了這兩個問題,它有許多變體, 例如長短期記憶(LSTM),門控循環單元(GRU)等。

RNNoise使用門控循環單元(GRU),因爲它在此任務上的性能比LSTM稍好,並且需要較少的資源(包括CPU和保存權重的內存)。與簡單的循環單元相比,GRU具有兩個額外的門。重置門(reset gate) 控制是否使用歷史狀態(state)來計算新狀態,而更新門(update gate)控制新輸入將在多大程度上改變存儲的狀態值(state)。這個更新門(關閉時)使GRU可以(很容易)長時間記住某個信息,這就是GRU(和LSTM)的性能比簡單循環單元好得多的原因。

將簡單的循環單元與GRU進行比較。區別在於GRUrz 門,這使得學習長期模式成爲可能。兩者都是基於整個層的歷史狀態和輸入計算出來的軟開關(介於01之間的值),具有S型激活函數。當更新門Z在左側時,狀態可以在很長一段時間內保持恆定-直到某種情況導致z切換到右側

混合方案

得益於深度學習的成功,現在流行將深度神經網絡來解決整個問題上。這些方法稱爲端到端 –只有神經元 (沒有其他處理模塊) 。端到端方法已應用於語音識別語音合成方面,這些端到端系統已經證明了深度神經網絡的強大功能。另一方面,這些系統有時可能不夠理想,而且浪費資源。例如,某些噪聲抑制方法使用具有數千個神經元的層以及數以千萬計的權重來執行噪聲抑制。缺點不僅是運行網絡的計算成本,還在於規模, 因爲現在是一千行代碼以及數十兆字節的神經元權重值(搞不好還更多)。

這就是爲什麼我們在這裏採用了不同的方法的原因:始終保留所有必需的基本信號處理(沒有神經網絡嘗試對其進行仿真),但是讓神經網絡學習所有需要在信號處理旁邊進行無休止調整的棘手部分。和那些現有的噪聲抑制的深度學習實現不同, 我們的目標是實時通信, 而不是語音識別, 我們不能預讀太多的數據(這次是10毫秒)

定義問題

爲了避免產生大量輸出,以及避免使用大量神經元,我們決定不直接使用採樣數據或頻譜。相反,我們使用基於巴克刻度(Bark scale)劃分的頻率帶(frequency bands),這種頻率刻度符合我們感知聲音的方式。我們總共使用22個頻段,而不是480個頻譜值(複雜)。

Opus頻帶 (bands) 的分佈v.s.巴克刻度。對於RNNoise,我們使用與Opus相同的基本佈局。由於頻帶間存在重疊,因此Opus頻帶之間的邊界成爲重疊的RNNoise頻帶的中心。在較高頻率下, 由於耳朵對頻率的分辨精度較差,因此頻帶劃分的比較寬。在低頻下,頻帶較窄,但比巴克刻度所給定的寬,否則我們將沒有足夠的數據來進行良好的估算。

當然,我們不能僅從22個頻帶的能量中重建音頻。但是,我們可以爲每個頻帶計算一個增益,並用在信號之上。您可以將他視作一個22段的EQ (均衡器) 並快速更改每個頻帶的電平以衰減噪聲,同時讓信號通過。

計算頻帶增益有幾個優點。首先,由於要計算的頻帶較少,因此模型更簡單。其次,它不可能產生所謂的音樂噪音僞像musical noise artifacts),因爲其相鄰聲音會被衰減, 只有單音會通過。這些僞像在噪聲抑制中很常見,而且很難處理。頻帶足夠寬時,我們要麼讓整個頻帶通過,要麼都剪掉。第三個優勢來自我們如何優化模型。由於增益總是限制在01之間,只需使用S(sigmoid)激活函數(其輸出也在01之間)來計算它們,就可以確保計算正確,首先是不引入噪聲。

對於輸出,我們還可以選擇ReLU(整流線性激活函數, rectified linear activation function)來表示0到無窮大之間的衰減(dB)。爲了在訓練過程中更好地優化增益,損失函數(loss function)採用pow(增益, α)的均方誤差(MSE)。到目前爲止,我們發現α=0.5時產生的結果在感知上是最佳的。使用α→0等效於最小化對數譜間距 (LSD, Log Spectral Distance),這是有問題的,因爲最佳增益可能非常接近零

分頻帶計算的主要缺點是, 在分辨率太低時, 不能有效地抑制音高諧波之間的噪聲。還在這並不是那麼重要,有一個簡單的技巧可以處理(請參見下面的音高濾波部分)。

由於我們計算輸出是基於22個頻帶的,因此在輸入上使用更高的頻率分辨率沒什麼意義,因此我們使用相同的22個頻帶將頻譜信息輸入神經網絡。因爲音頻具有很大的動態範圍,所以計算能量的對數值要好於直接提供能量值。然後, 對該數值執行DCT (離散餘弦變換) 對特徵進行去相關 (Decorrelate) 。所得數據是基於巴克刻度的倒譜(BFCC),它與語音識別中常用的梅爾倒譜系數(MFCC)密切相關。

除倒譜系數外,我們還使用了以下數據作爲神經網絡的輸入特徵(22+6x2+1+6+1 = 42):

  • 前6個BFCC係數的一階和二階導數
  • 基音週期(1 /基頻)
  • 6個頻段的基音增益(發聲強度)
  • 一個特殊的非平穩值,可用於檢測語音(超出了本Demo的範圍)

深度學習架構

我們網絡架構靈感來自傳統的噪聲抑制方法。大部分工作由3GRU層完成。下圖顯示了我們用於計算頻帶增益的層,以及該體系結構如何映射到噪聲抑制的傳統步驟。當然,與其他神經網絡一樣,我們沒有實際的證據證明網絡正在按預期那樣運作,但是該結構比我們嘗試的其他結構都工作得更好, 這讓我們有理由認爲它符合我們設計預期。

本項目中使用的神經網絡結構。每個方框代表一層神經元,括號中標出單位數。緻密層(Dense) 是完全連接的非循環層。網絡的輸出之一是一組應用於不同頻率的增益。另一項輸出是VAD概率,該輸出雖未用於噪聲抑制,也非常有用的。

關於數據

深度神經網絡有時也可能很笨。他們擅長於已學的知識,但是在面對差別很大的新知識時, 容易犯下非常嚴重的錯誤。更糟糕的是,他們真的是懶惰的學生。如果他們可以在訓練過程中使用任何漏洞來偷懶,他們一定會那麼做。這就是爲什麼訓練數據的質量至關重要的原因。

一個廣爲流傳的故事是,很久以前,一些軍隊研究人員正試圖訓練一個神經網絡來識別樹木僞裝的坦克。他們爲有和沒有坦克的樹木拍照,然後訓練了神經網絡來識別有坦克的樹木。網絡成功超出預期!只有一個問題。由於帶有坦克的照片是在陰天拍攝的,而沒有坦克的照片是在晴天拍攝的,因此網絡真正學到的是晴天和陰天有何不同。儘管研究人員現在已經意識到了這個問題並避免了此類明顯的錯誤,但它仍然可以以更難察覺的方式存在(並且過去確實發生在您的身上)。

在噪聲抑制的情況下,我們不能僅僅收集可用於監督學習的輸入/輸出數據,因爲我們很少同時獲得乾淨的語音嘈雜的語音。我們必須根據清晰的語音和噪音錄音來人爲地創建該數據。棘手的部分是獲取各種各樣的噪聲數據以添加到語音中。我們還必須確保覆蓋所有錄音條件。例如,當音頻以8 kHz進行低通濾波時,僅接受全頻帶音頻(0-20 kHz)訓練的早期版本就會失敗。

與語音識別不同,我們選擇不對特徵進行倒譜平均歸一化,並且保留表示能量的第一個倒譜系數。因爲我們必須確保數據包括所有現實音量的音頻。我們還對音頻使用隨機濾波器,使系統對各種麥克風頻率響應具有魯棒性(通常由倒譜均值歸一化處理)。

基音(pitch)濾波

由於我們頻帶的頻率分辨率太粗糙,無法濾掉基音諧波之間的噪聲,因此我們使用基本信號處理來做到這一點。這是混合方案的另一部分。當對同一變量進行多次測量時,提高準確性(降低噪聲)的最簡單方法就是計算平均值。顯然,只計算相鄰音頻樣本的平均值是不合適的,因爲這相當於低通濾波。但是,當信號是週期性的(例如濁音)時,我們可以計算出偏離基音週期的樣本平均值(we can compute the average of samples offset by the pitch period)。這樣就得到一個梳狀濾波器, 使諧波可以通過,同時衰減它們之間的頻率成分 (噪聲) 。爲避免信號失真,梳狀濾波器將獨立應用於每個頻帶,其濾波器強度既取決於基音相關性,也和神經網絡計算出的頻帶增益有關。

目前,我們使用FIR濾波器進行基音濾波,但也可以(在TODO列表中)使用IIR濾波器,如果強度過高,則會導致更大的噪聲衰減,因爲有更大失真的風險。

從Python到C

本神經網絡的所有設計和訓練都是用強大的Keras深度學習庫和python完成的。由於Python通常不是實時系統的首選語言,因此我們必須以C語言實現運行時代碼。幸運的是,運行神經網絡遠比訓練一個神經網絡容易,我們所要做的就是實前向傳播和GRU層。爲了將精簡模型,我們在訓練過程中將權重的大小限制爲+/-0.5,以便可以用8bit值來存儲它們。生成的模型精簡到了85kB(如果用32位浮點數存儲則是340kB)。

C代碼可以在BSD許可下可用。儘管在編寫本演示時,代碼尚未優化,但在x86 CPU上,它的運行速度比實時運行快60倍。它甚至比Raspberry Pi 3上的實時運行速度快7倍左右。藉助良好的矢量化(SSE / AVX),應該可以使其比當前速度快4倍。

給我看例子!

好的,這很好,但是實際上聽起來如何?原文網站上有一些實際的RNNoise示例,可消除三種不同類型的噪聲。這些噪音和乾淨的語音都沒有在訓練期間使用過。

譯註:請訪問原文網站體驗算法效果, 其中包含了:

  • 無降噪/RNNoise/Speexdsp三種算法狀態
  • 0~10dB的SNR, 以及乾淨語音
  • 三種噪音類型: 嘈雜噪聲(Babble Noise), 汽車噪音(Car noise), 街道噪音(Street Noise)
  • 相關語音也可以從https://people.xiph.org/~jm/demo/rnnoise/samples/下載

與無抑制和與Speexdsp噪聲抑制器相比,評估RNNoise的效果。儘管提供的SNR低至0 dB,但我們針對的大多數應用(例如WebRTC呼叫)的SNR往往更接近20 dB,而不是0 dB

那麼,無論如何,您應該聽什麼?也許我的說法很奇怪,你應該期待聲音變得更清晰(intelligibility)。人類非常擅長於理解噪聲中的語音,而增強算法只能破壞信息(尤其是不能在降噪之前預讀語音的情況下)。那麼,爲什麼我們要還要這樣做呢?答案是爲了質量(Quality), 讓處理後的語音聽起來不那麼嘈雜,減少聽覺疲勞。

實際上,在有些場景下它可以提高清晰度。第一個是有多個揚聲器輸入混合在一起視頻會議。這時噪聲抑制可防止來自所有非活躍揚聲器的噪聲與活躍揚聲器混合在一起,從而提高質量和清晰度。第二種情況是語音需要通過低比特率編解碼器。與乾淨的語音相比,嘈雜的語音在此情況下會變得更差,因此消除噪聲可使編解碼器效果更好。

試一下您的聲音!

對以上樣本不滿意?實際上,(在原文網站上)您可以通過麥克風進行錄製,並(近乎)實時地對音頻進行降噪。如果單擊下面的按鈕,RNNoise將在瀏覽器中的Javascript中執行噪聲抑制。該算法是實時運行的,但我們故意將其延遲了幾秒鐘,以使其更容易聽到降噪後的輸出。 確保戴上耳機,否則您會聽到反饋循環。要開始演示,請選擇無抑制 RNNoise。您可以在兩者之間切換以查看抑制效果。如果您的輸入沒有足夠的噪聲,則可以通過單擊白噪聲按鈕來人爲添加一些噪聲。

 

將您的噪音捐贈給科學

如果您認爲這項工作有用,有一種簡單的方法可以使它變得更好!只需要一分鐘的時間。單擊下面的鏈接,讓我們記錄您所在位置的一分鐘噪音。該噪聲可用於改善神經網絡的訓練。作爲附帶的好處,這意味着網絡將知道您所擁有的噪聲類型,並且在將其用於視頻會議時(例如在WebRTC中)可能會做得更好。我們對您可能通過語音進行交流的任何環境中的噪音感興趣。可以是您的辦公室,汽車,街道,或可能使用手機或計算機的任何地方。

感謝所有捐贈他們的噪音的人。現在可以免費下載數據6.4 GB)。有關更多詳細信息,請參見隨附的自述文件。

從哪裏來?

如果您想進一步瞭解RNNoise的技術細節,請參閱本文(尚未提交)。該代碼仍在積極開發中(沒有凍結的API),但已在應用程序中使用。它當前針對VoIP/視頻會議應用程序,但是經過一些調整,它可能可以應用於許多其他任務。一個明顯的目標是自動語音識別(ASR),儘管我們可以對嘈雜的語音進行降噪並將輸出發送到ASR,但這不是最佳選擇,因爲它會丟棄有關過程固有不確定性的有用信息。當ASR不僅知道最可能的純淨語音,而且知道它可以在多大程度上依賴該估計時,它會有用得多。另一種可能的定位”是實現一個更智能化的電子樂器的噪音抑制器(noise gate)。它需要做的就是提供良好的訓練數據,並對代碼進行一些更改,以將Raspberry Pi變成真正的吉他噪聲抑制器。有沒有人想試試?可能還有許多我們還沒考慮到的潛在應用。

如果您想對此Demo發表評論,可以在此處進行評論

— Jean-Marc Valin[email protected]2017927

其他資源

  1. 代碼:RNNoise Git存儲庫 (Github鏡像
  2. J.-M. Valin,一種用於實時全頻帶語音增強的混合DSP /深度學習方法,國際多媒體信號處理研討會,2018年。(arXiv:1709.08243
  3. Jean-Marc的博客文章以發表評論

致謝

特別感謝Michael BebenitaThomas DaedeYury Delendik的幫助,幫助他們組織了這個Demo。感謝Reuben MoraisKeras的幫助。

 

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