音訊課程文件
ASR 評估指標
並獲得增強的文件體驗
開始使用
ASR 評估指標
如果您熟悉 NLP 中的 Levenshtein 距離,那麼評估語音識別系統的指標將很熟悉!如果您不熟悉,請不要擔心,我們將從頭到尾進行解釋,以確保您瞭解不同的指標並理解它們的含義。
在評估語音識別系統時,我們將系統的預測與目標文字轉錄進行比較,並標註存在的任何錯誤。我們將這些錯誤分為以下三類:
- 替換 (S):預測中轉錄了**錯誤的詞**(“sit” 而不是 “sat”)
- 插入 (I):預測中添加了**多餘的詞**
- 刪除 (D):預測中**刪除了一個詞**
這些錯誤類別對於所有語音識別指標都是相同的。不同之處在於我們計算這些錯誤的級別:我們可以在*詞級別*或*字元級別*計算它們。
我們將為每個指標定義使用一個執行示例。這裡,我們有一個*地面真實*或*參考*文字序列
reference = "the cat sat on the mat"
以及我們正在評估的語音識別系統的預測序列
prediction = "the cat sit on the"
我們可以看到預測非常接近,但有些詞不太正確。我們將針對三種最流行的語音識別指標評估此預測與參考的對比,看看我們為每種指標獲得什麼樣的數字。
詞錯誤率
詞錯誤率 (WER) 指標是語音識別的“事實標準”指標。它計算*詞級別*的替換、插入和刪除。這意味著錯誤是逐詞標註的。以我們的例子為例:
參考 | the | cat | sat | on | the | mat |
---|---|---|---|---|---|---|
預測 | the | cat | sit | on | the | |
標籤 | ✅ | ✅ | S | ✅ | ✅ | D |
這裡,我們有
- 1 個替換(“sit” 而不是 “sat”)
- 0 個插入
- 1 個刪除(缺少“mat”)
這總共產生了 2 個錯誤。為了得到錯誤率,我們將錯誤數量除以參考中的總詞數 (N),本例中為 6。
好的!所以我們得到了 0.333 的 WER,或者說 33.3%。請注意,“sit”這個詞只有一個字元是錯誤的,但整個詞都被標記為不正確。這是 WER 的一個顯著特徵:拼寫錯誤會受到嚴厲懲罰,無論它們多麼微小。
WER 的定義是*越低越好*:較低的 WER 意味著我們的預測中錯誤較少,因此一個完美的語音識別系統將具有零 WER(無錯誤)。
讓我們看看如何使用 🤗 Evaluate 計算 WER。我們需要兩個包來計算我們的 WER 指標:🤗 Evaluate 用於 API 介面,JIWER 用於執行計算的繁重工作。
pip install --upgrade evaluate jiwer
太棒了!我們現在可以載入 WER 指標並計算我們示例的數字。
from evaluate import load
wer_metric = load("wer")
wer = wer_metric.compute(references=[reference], predictions=[prediction])
print(wer)
列印輸出
0.3333333333333333
0.33,或 33.3%,正如預期!我們現在知道了 WER 計算的內部原理。
現在,有些事情很令人困惑……您認為 WER 的上限是多少?您會期望它是 1 或 100% 對嗎?不!由於 WER 是錯誤與單詞數 (N) 的比率,因此 WER 沒有上限!讓我們舉一個例子,我們預測了 10 個單詞,而目標只有 2 個單詞。如果我們的所有預測都錯了(10 個錯誤),我們將得到 10 / 2 = 5 的 WER,即 500%!如果您訓練 ASR 系統並看到 WER 超過 100%,請記住這一點。不過如果您看到這種情況,很可能出了問題…… 😅
詞準確率
我們可以將 WER 反過來,得到一個*越高越好*的指標。我們可以衡量系統的*詞準確率 (WAcc)*,而不是衡量詞錯誤率。
WAcc 也以詞級別進行測量,它只是 WER 的一種重新表達,將其作為準確率指標而不是錯誤指標。WAcc 在語音文獻中很少被引用——我們通常以詞錯誤來考慮我們的系統預測,因此更喜歡與這些錯誤型別標註相關的錯誤率指標。
字元錯誤率
將“sit”這個詞完全標記為錯誤似乎有點不公平,因為實際上只有一個字母是錯誤的。那是因為我們是在詞級別評估系統,因此逐詞標註錯誤。*字元錯誤率 (CER)* 在*字元級別*評估系統。這意味著我們將單詞分解成單獨的字元,並逐個字元地標註錯誤。
參考 | t | h | e | c | a | t | s | a | t | o | n | t | h | e | m | a | t | |||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
預測 | t | h | e | c | a | t | s | i | t | o | n | t | h | e | ||||||||
標籤 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | S | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | D | D | D | D |
我們現在可以看到,對於單詞“sit”,字母“s”和“t”被標記為正確。只有“i”被標記為替換錯誤 (S)。因此,我們獎勵系統部分正確的預測🤝。
在我們的示例中,我們有 1 個字元替換,0 個插入,和 4 個刪除。總共有 22 個字元。因此,我們的 CER 是
沒錯!我們的 CER 為 0.227,即 22.7%。請注意,這比我們的 WER 低——我們對拼寫錯誤的懲罰要小得多。
我應該使用哪個指標?
一般來說,WER 在評估語音系統時比 CER 使用得更廣泛。這是因為 WER 要求系統更好地理解預測的上下文。在我們的例子中,“sit”是錯誤的語態。一個理解動詞和句子語態之間關係的系統會預測出正確的動詞語態“sat”。我們希望鼓勵我們的語音系統達到這種理解水平。因此,儘管 WER 比 CER 更不寬容,但它也更有利於我們開發出更智慧的系統。因此,我們通常使用 WER,也鼓勵您這樣做!然而,在某些情況下無法使用 WER。某些語言,如普通話和日語,沒有“詞”的概念,因此 WER 毫無意義。在這種情況下,我們轉而使用 CER。
在我們的例子中,我們在計算 WER 時只使用了一個句子。在評估真實系統時,我們通常會使用包含數千個句子的整個測試集。在評估多個句子時,我們會彙總所有句子的 S、I、D 和 N,然後根據上面定義的公式計算 WER。這能更好地估計未見資料的 WER。
標準化
如果我們在帶有標點符號和大小寫的資料上訓練 ASR 模型,它將學會預測轉錄中的大小寫和標點符號。當我們想將模型用於實際的語音識別應用程式時(例如會議轉錄或口述),這非常有用,因為預測的轉錄將完全格式化,帶有大小寫和標點符號,這種風格被稱為*正字法*。
然而,我們也可以選擇對資料集進行*規範化*,以去除任何大小寫和標點符號。規範化資料集使語音識別任務變得更容易:模型不再需要區分大小寫字元,也不必僅憑音訊資料預測標點符號(例如,分號發出什麼聲音?)。因此,詞錯誤率自然會更低(這意味著結果更好)。Whisper 論文展示了規範化轉錄對 WER 結果的巨大影響(*參見* Whisper 論文的 4.4 節)。雖然我們得到了更低的 WER,但模型對於生產來說不一定更好。缺少大小寫和標點符號使得模型預測的文字閱讀起來明顯更困難。以上一節的示例為例,我們在 LibriSpeech 資料集的相同音訊樣本上運行了 Wav2Vec2 和 Whisper 模型。Wav2Vec2 模型不預測標點符號和大小寫,而 Whisper 則兩者都預測。並排比較轉錄,我們發現 Whisper 的轉錄更容易閱讀。
Wav2Vec2: HE TELLS US THAT AT THIS FESTIVE SEASON OF THE YEAR WITH CHRISTMAUS AND ROSE BEEF LOOMING BEFORE US SIMALYIS DRAWN FROM EATING AND ITS RESULTS OCCUR MOST READILY TO THE MIND
Whisper: He tells us that at this festive season of the year, with Christmas and roast beef looming before us, similarly is drawn from eating and its results occur most readily to the mind.
Whisper 的轉錄是正字法的,因此可以直接使用——它按照我們期望的會議轉錄或口述指令碼格式化,包括標點符號和大小寫。相反,如果我們要將 Wav2Vec2 用於下游應用程式,則需要使用額外的後處理來恢復 Wav2Vec2 預測中的標點符號和大小寫。
在規範化和不規範化之間有一個折衷方案:我們可以在正字法轉錄本上訓練我們的系統,然後在計算 WER 之前規範化預測和目標。這樣,我們訓練我們的系統來預測完全格式化的文字,同時也能從規範化轉錄本所帶來的 WER 改進中受益。
Whisper 模型釋出時帶有一個規範化器,它能有效地處理大小寫、標點符號和數字格式等的規範化。讓我們將規範化器應用於 Whisper 轉錄本,以演示我們如何規範化它們。
from transformers.models.whisper.english_normalizer import BasicTextNormalizer
normalizer = BasicTextNormalizer()
prediction = " He tells us that at this festive season of the year, with Christmas and roast beef looming before us, similarly is drawn from eating and its results occur most readily to the mind."
normalized_prediction = normalizer(prediction)
normalized_prediction
輸出
' he tells us that at this festive season of the year with christmas and roast beef looming before us similarly is drawn from eating and its results occur most readily to the mind '
太好了!我們可以看到文字已經完全小寫,並且所有標點符號都已刪除。現在讓我們定義參考轉錄,然後計算參考和預測之間的標準化 WER。
reference = "HE TELLS US THAT AT THIS FESTIVE SEASON OF THE YEAR WITH CHRISTMAS AND ROAST BEEF LOOMING BEFORE US SIMILES DRAWN FROM EATING AND ITS RESULTS OCCUR MOST READILY TO THE MIND"
normalized_referece = normalizer(reference)
wer = wer_metric.compute(
references=[normalized_referece], predictions=[normalized_prediction]
)
wer
輸出
0.0625
6.25%——這大致是 Whisper 基礎模型在 LibriSpeech 驗證集上預期的結果。正如我們在這裡看到的,我們預測了一個正字法轉錄,但透過在計算 WER 之前對參考和預測進行標準化,獲得了 WER 的提升。
如何規範化轉錄的最終選擇取決於您的需求。我們建議在正字法文字上進行訓練,並在規範化文字上進行評估,以獲得兩全其美的效果。
整合所有內容
好的!本單元我們已經介紹了三個主題:預訓練模型、資料集選擇和評估。讓我們來點樂趣,將它們整合到一個端到端的示例中 🚀 我們將透過在 Common Voice 13 Dhivehi 測試集上評估預訓練的 Whisper 模型來為下一節的微調做好準備。我們將把獲得的 WER 數字作為我們微調執行的*基線*,或者我們試圖超越的目標 🥊
首先,我們將使用 pipeline()
類載入預訓練的 Whisper 模型。這個過程現在應該非常熟悉了!我們唯一要做的就是,如果在 GPU 上執行,則以半精度 (float16) 模式載入模型——這將加速推理,且幾乎不會犧牲 WER 精度。
from transformers import pipeline
import torch
if torch.cuda.is_available():
device = "cuda:0"
torch_dtype = torch.float16
else:
device = "cpu"
torch_dtype = torch.float32
pipe = pipeline(
"automatic-speech-recognition",
model="openai/whisper-small",
torch_dtype=torch_dtype,
device=device,
)
接下來,我們將載入 Common Voice 13 的迪維希語測試分割。您可能還記得,在上一節中,Common Voice 13 是*受限的*,這意味著我們必須同意資料集使用條款才能訪問資料集。現在我們可以將 Hugging Face 賬戶連結到我們的筆記本,這樣我們就可以從當前使用的機器訪問資料集了。
將筆記本連結到 Hub 很簡單——只需在提示時輸入您的 Hub 身份驗證令牌即可。在此處查詢您的 Hub 身份驗證令牌,並在提示時輸入。
from huggingface_hub import notebook_login
notebook_login()
太好了!一旦我們將筆記本連結到 Hugging Face 賬戶,就可以繼續下載 Common Voice 資料集了。這將需要幾分鐘才能下載和預處理,它會從 Hugging Face Hub 獲取資料並自動在您的筆記本上進行準備。
from datasets import load_dataset
common_voice_test = load_dataset(
"mozilla-foundation/common_voice_13_0", "dv", split="test"
)
對整個資料集進行評估與對單個示例進行評估非常相似——我們所要做的就是*遍歷*輸入音訊,而不是隻推理單個樣本。為此,我們首先將資料集轉換為 `KeyDataset`。這只是挑選出我們想要轉發到模型的特定資料集列(在我們的例子中,是 `"audio"` 列),忽略其餘的(例如我們不想用於推理的目標轉錄)。然後我們遍歷這些轉換後的資料集,將模型輸出附加到一個列表中以儲存預測。以下程式碼單元如果在 GPU 上以半精度執行,將大約需要五分鐘,峰值記憶體佔用為 12GB。
from tqdm import tqdm
from transformers.pipelines.pt_utils import KeyDataset
all_predictions = []
# run streamed inference
for prediction in tqdm(
pipe(
KeyDataset(common_voice_test, "audio"),
max_new_tokens=128,
generate_kwargs={"task": "transcribe"},
batch_size=32,
),
total=len(common_voice_test),
):
all_predictions.append(prediction["text"])
最後,我們可以計算 WER。讓我們首先計算正字法 WER,即不進行任何後處理的 WER。
from evaluate import load
wer_metric = load("wer")
wer_ortho = 100 * wer_metric.compute(
references=common_voice_test["sentence"], predictions=all_predictions
)
wer_ortho
輸出
167.29577268612022
好吧……167% 基本上意味著我們的模型輸出的是垃圾 😜 別擔心,我們的目標是透過在迪維希語訓練集上微調模型來改進這一點!
接下來,我們將評估規範化 WER,即經過規範化後處理的 WER。我們必須過濾掉規範化後將為空的樣本,否則我們的參考(N)中的總詞數將為零,這將導致計算中出現除零錯誤。
from transformers.models.whisper.english_normalizer import BasicTextNormalizer
normalizer = BasicTextNormalizer()
# compute normalised WER
all_predictions_norm = [normalizer(pred) for pred in all_predictions]
all_references_norm = [normalizer(label) for label in common_voice_test["sentence"]]
# filtering step to only evaluate the samples that correspond to non-zero references
all_predictions_norm = [
all_predictions_norm[i]
for i in range(len(all_predictions_norm))
if len(all_references_norm[i]) > 0
]
all_references_norm = [
all_references_norm[i]
for i in range(len(all_references_norm))
if len(all_references_norm[i]) > 0
]
wer = 100 * wer_metric.compute(
references=all_references_norm, predictions=all_predictions_norm
)
wer
輸出
125.69809089960707
我們再次看到了透過規範化我們的參考文獻和預測所實現的 WER 的大幅降低:基線模型的正字法測試 WER 為 168%,而規範化 WER 為 126%。
好的!這些就是我們微調模型時想要嘗試超越的數字,以便改進 Whisper 模型在迪維希語語音識別方面的表現。繼續閱讀以動手實踐微調示例 🚀
< > 在 GitHub 上更新