音訊課程文件
CTC 架構
並獲得增強的文件體驗
開始使用
CTC 架構
CTC,即連線主義時間分類(Connectionist Temporal Classification),是一種與僅編碼器 Transformer 模型結合用於自動語音識別的技術。此類模型的例子有 Wav2Vec2、HuBERT 和 M-CTC-T。
僅編碼器 Transformer 是最簡單的 Transformer 型別,因為它只使用模型的編碼器部分。編碼器讀取輸入序列(音訊波形)並將其對映為隱藏狀態序列,也稱為輸出嵌入。
對於 CTC 模型,我們在隱藏狀態序列上應用額外的線性對映,以獲得類別標籤預測。類別標籤是**字母表中的字元**(a、b、c 等)。這樣,我們就可以透過一個小型分類頭預測目標語言中的任何單詞,因為詞彙表只需包含 26 個字元加上一些特殊標記。

到目前為止,這與我們在 NLP 中使用 BERT 等模型所做的事情非常相似:僅編碼器 Transformer 模型將我們的文字標記對映到編碼器隱藏狀態序列,然後我們應用線性對映為每個隱藏狀態獲取一個類別標籤預測。
問題在於:在語音中,我們不知道音訊輸入和文字輸出的**對齊方式**。我們知道語音的順序與文字轉錄的順序相同(對齊方式是所謂的單調對齊),但我們不知道轉錄中的字元如何與音訊對齊。這就是 CTC 演算法發揮作用的地方。
哥們,我的對齊呢?
自動語音識別(ASR)涉及將音訊作為輸入並生成文字作為輸出。我們有幾種選擇來預測文字:
- 作為單個字元
- 作為音素
- 作為單詞標記
ASR 模型在包含 `(音訊, 文字)` 對的資料集上進行訓練,其中文字是音訊檔案的人工轉錄。通常,資料集不包含任何時序資訊,即哪個單詞或音節在音訊檔案的哪個位置出現。由於我們不能在訓練期間依賴時序資訊,因此我們不知道輸入和輸出序列應該如何對齊。
假設我們的輸入是一個一秒的音訊檔案。在 **Wav2Vec2** 中,模型首先使用 CNN 特徵編碼器對音訊輸入進行下采樣,得到一個較短的隱藏狀態序列,其中每 20 毫秒的音訊對應一個隱藏狀態向量。對於一秒的音訊,我們然後將 50 個隱藏狀態的序列轉發到 Transformer 編碼器。(從輸入序列中提取的音訊片段部分重疊,因此即使每 20 毫秒發出一個隱藏狀態向量,每個隱藏狀態實際上代表 25 毫秒的音訊。)
Transformer 編碼器為每個隱藏狀態預測一個特徵表示,這意味著我們從 Transformer 接收到 50 個輸出的序列。這些輸出中的每一個維度都是 768。因此,本例中 Transformer 編碼器的輸出序列形狀為 `(768, 50)`。由於這些預測中的每一個都覆蓋 25 毫秒的時間,這比音素的持續時間短,因此預測單個音素或字元而不是整個單詞是有意義的。CTC 最適合小詞彙表,所以我們將預測字元。

為了進行文字預測,我們使用線性層(“CTC 頭”)將每個 768 維的編碼器輸出對映到我們的字元標籤。然後模型預測一個 `(50, 32)` 的張量,其中包含 logits,32 是詞彙表中的標記數量。由於我們為序列中的每個特徵進行一個預測,因此每秒音訊總共得到 50 個字元預測。
然而,如果我們僅僅每 20 毫秒預測一個字元,我們的輸出序列可能看起來像這樣:
BRIIONSAWWSOMEETHINGCLOSETOPANICONHHISOPPONENT'SSFAACEWHENTHEMANNFINALLLYRREECOGGNNIIZEDHHISSERRRRORR ...
如果你仔細看,它有點像英語,但很多字元都被重複了。這是因為模型需要為輸入序列中每 20 毫秒的音訊輸出**一些東西**,如果一個字元的持續時間超過 20 毫秒,那麼它就會在輸出中出現多次。這是無法避免的,特別是我們不知道訓練期間轉錄的時序。CTC 是一種過濾這些重複項的方法。
(實際上,預測序列還包含許多填充標記,當模型不確定聲音代表什麼,或者字元之間的空白時。為了清晰起見,我們從示例中刪除了這些填充標記。音訊片段之間的部分重疊是字元在輸出中重複的另一個原因。)
CTC 演算法
CTC 演算法的關鍵是使用一個特殊標記,通常稱為**空白標記**。這只是模型將預測的另一個標記,它是詞彙表的一部分。在此示例中,空白標記顯示為 `_`。這個特殊標記充當字元組之間的硬邊界。
CTC 模型的完整輸出可能如下所示:
B_R_II_O_N_||_S_AWW_|||||_S_OMEE_TH_ING_||_C_L_O_S_E||TO|_P_A_N_I_C_||_ON||HHI_S||_OP_P_O_N_EN_T_'SS||_F_AA_C_E||_W_H_EN||THE||M_A_NN_||||_F_I_N_AL_LL_Y||||_RREE_C_O_GG_NN_II_Z_ED|||HHISS|||_ER_RRR_ORR||||
`|` 標記是單詞分隔符。在這個例子中,我們使用 `|` 而不是空格,這使得識別單詞邊界變得更容易,但它起著相同的作用。
CTC 空白字元使得過濾重複字元成為可能。例如,讓我們看看預測序列中的最後一個單詞,`_ER_RRR_ORR`。如果沒有 CTC 空白標記,這個單詞看起來是這樣的:
ERRRRORR
如果只是簡單地去除重複字元,它將變成 `EROR`。這顯然不是正確的拼寫。但是有了 CTC 空白標記,我們可以在每個組中去除重複字元,這樣:
_ER_RRR_ORR
變成
_ER_R_OR
現在我們移除 `_` 空白標記,得到最終的單詞
ERROR
如果我們將此邏輯應用於整個文字,包括 `|`,並將剩餘的 `|` 字元替換為空格,則最終的 CTC 解碼輸出是:
BRION SAW SOMETHING CLOSE TO PANIC ON HIS OPPONENT'S FACE WHEN THE MAN FINALLY RECOGNIZED HIS ERROR
總結一下,模型為輸入波形中每 20 毫秒(部分重疊)的音訊預測一個標記(字元)。這會產生很多重複項。由於 CTC 空白標記,我們可以輕鬆地刪除這些重複項,而不會破壞單詞的正確拼寫。這是一種非常簡單方便的方法來解決輸出文字與輸入音訊對齊的問題。
將 CTC 新增到 Transformer 編碼器模型很容易:編碼器的輸出序列進入一個線性層,將聲學特徵投射到詞彙表中。模型使用特殊的 CTC 損失進行訓練。
CTC 的一個缺點是它可能會輸出聽起來正確但拼寫不正確的單詞。畢竟,CTC 頭只考慮單個字元,而不是完整的單詞。提高音訊轉錄質量的一種方法是使用外部語言模型。這個語言模型本質上充當 CTC 輸出之上的拼寫檢查器。
Wav2Vec2、HuBERT、M-CTC-T 等之間有什麼區別?
所有基於 Transformer 的 CTC 模型都具有非常相似的架構:它們使用 Transformer 編碼器(但不是解碼器),並在其頂部帶有 CTC 頭。在架構上,它們相似多於不同。
Wav2Vec2 和 M-CTC-T 的一個區別是前者處理原始音訊波形,而後者使用梅爾頻譜圖作為輸入。這些模型也針對不同的目的進行了訓練。例如,M-CTC-T 訓練用於多語言語音識別,因此具有相對較大的 CTC 頭,除了其他字母表外,還包含漢字。
Wav2Vec2 和 HuBERT 使用完全相同的架構,但以非常不同的方式進行訓練。Wav2Vec2 像 BERT 的掩碼語言建模一樣進行預訓練,透過預測音訊掩碼部分的語音單元。HuBERT 更進一步地受到 BERT 的啟發,學習預測“離散語音單元”,這類似於文字句子中的標記,因此可以使用已建立的 NLP 技術處理語音。
需要澄清的是,這裡強調的模型並非唯一的基於 Transformer 的 CTC 模型。還有許多其他模型,但現在你知道它們的工作方式都類似。
< > 在 GitHub 上更新