量評(píng)估:google-research ged_tts 中 Fréchet Deep Speech Distance 重實(shí)現(xiàn)的原理與實(shí)戰(zhàn))
基于 DeepSpeech2 特征空間的 FDSD 語音質(zhì)量評(píng)估google-research ged_tts 中 Fréchet Deep Speech Distance 重實(shí)現(xiàn)的原理與實(shí)戰(zhàn)【免費(fèi)下載鏈接】google-researchGoogle Research項(xiàng)目地址: https://gitcode.com/gh_mirrors/go/google-researchFréchet Deep Speech DistanceFDSD是語音生成領(lǐng)域用于衡量真實(shí)語音與合成語音分布差異的經(jīng)典自動(dòng)評(píng)估指標(biāo)。本文以ged_tts/fdsd/目錄下 Google Research 提供的官方重實(shí)現(xiàn)為對(duì)象完整講解 FDSD 的數(shù)學(xué)原理、DeepSpeech2 特征提取器的架構(gòu)細(xì)節(jié)、預(yù)訓(xùn)練 checkpoint 的加載方式以及compute_fdsd.py命令行的完整使用方法。讀完本文你將掌握如何在本地對(duì)任意兩組 WAV 音頻樣本一鍵計(jì)算 FDSD 分?jǐn)?shù)并理解分?jǐn)?shù)從波形到最終數(shù)值的完整數(shù)據(jù)流。FDSD 是什么從原始論文到本倉(cāng)庫(kù)的重實(shí)現(xiàn)FDSDFréchet Deep Speech Distance最初由 Bińkowski 等人在 2019 年的論文《High fidelity speech synthesis with adversarial networks》arXiv:1909.11646中提出。其核心思想借鑒了圖像生成領(lǐng)域廣泛使用的 FIDFréchet Inception Distance先用一個(gè)預(yù)訓(xùn)練模型把樣本映射到高維語義特征空間再在該特征空間中用 Fréchet 距離度量?jī)山M樣本分布之間的差異。區(qū)別在于 FDSD 將特征提取器從圖像領(lǐng)域的 Inception 網(wǎng)絡(luò)換成語音識(shí)別領(lǐng)域的 DeepSpeech2從而讓評(píng)估結(jié)果更貼近語音內(nèi)容與發(fā)音質(zhì)量的語義維度。本倉(cāng)庫(kù)并未直接使用第三方實(shí)現(xiàn)而是提供了獨(dú)立的官方重實(shí)現(xiàn)位于ged_tts/fdsd/目錄見 fdsd/README.md。需要特別說明的是該重實(shí)現(xiàn)不只是簡(jiǎn)單的腳本封裝由于原版 DeepSpeech2 checkpoint 的 metagraph 依賴 CuDNN 的 GRU 算子無法在其他加速器上運(yùn)行作者使用 Keras 層重新搭建了與原始權(quán)重完全兼容的模型結(jié)構(gòu)依據(jù) ds2_encoder.py 中的模塊說明這也是本實(shí)現(xiàn)最值得研究的部分。倉(cāng)庫(kù)文件結(jié)構(gòu)入口、評(píng)估器與依賴ged_tts/fdsd/ ├── README.md # 使用說明本文主體所依據(jù)的文檔 ├── compute_fdsd.py # 命令行入口數(shù)據(jù)集構(gòu)建 指標(biāo)計(jì)算 ├── requirements.txt # 依賴清單 └── eval/ ├── __init__.py # 導(dǎo)出 NoOpScorer 與 DS2Scorer ├── ds2_encoder.py # DeepSpeech2 模型重實(shí)現(xiàn)特征前端 編碼器 ├── scorer.py # Fréchet 距離核心數(shù)學(xué)實(shí)現(xiàn)與 NoOpScorer └── tts_scorer.py # DS2Scorercheckpoint 恢復(fù) FDSD 分?jǐn)?shù)計(jì)算其中 eval/init.py 是統(tǒng)一的庫(kù)導(dǎo)入入口外部代碼通過from ged_tts.fdsd.eval import DS2Scorer即可使用評(píng)估器compute_fdsd.py則是面向命令行用戶的完整流程腳本。整個(gè) FDSD 計(jì)算在項(xiàng)目中的作用是充當(dāng) GEDSpectral Energy Distance論文《A Spectral Energy Distance for Parallel Speech Synthesis》的實(shí)驗(yàn)評(píng)估指標(biāo)——該論文正文中提到的 cFDSDconditional FDSD正是基于本套實(shí)現(xiàn)見 ged_tts/README.md。三步跑通 FDSD 評(píng)估第一步安裝依賴根據(jù) fdsd/README.md先安裝依賴。倉(cāng)庫(kù)提供的 requirements.txt 包含五個(gè)包tqdm tensorflow numpy scipy absltensorflow模型推理與數(shù)據(jù)管線代碼中使用tensorflow.compat.v2API需 TF 2.x 環(huán)境numpy/scipy特征統(tǒng)計(jì)量均值、協(xié)方差與矩陣平方根scipy.linalg.sqrtm計(jì)算absl命令行 flags 解析與日志tqdm特征收集時(shí)的進(jìn)度條顯示。原文檔給出的安裝命令為pip install -m requirements.txt需要提醒的是-m是 pip 的以模塊方式運(yùn)行參數(shù)安裝依賴清單的標(biāo)準(zhǔn)參數(shù)應(yīng)為-r即實(shí)際可用的命令是pip install -r requirements.txt第二步準(zhǔn)備 DeepSpeech2 預(yù)訓(xùn)練 checkpointFDSD 依賴一個(gè)已訓(xùn)練好的語音識(shí)別模型來提取特征。原文檔要求從 Open Seq2Seq 庫(kù)下載并解壓其 DeepSpeech 2 checkpoint即ds2_large模型。compute_fdsd.py 中給出了該 checkpoint 的默認(rèn)路徑與命名約定flags.DEFINE_string(ds2_ckpt, ds2_large/model.ckpt-54800, Path to the DeepSpeech2 checkpoint.)也就是說默認(rèn)期望在ds2_large/目錄下存在model.ckpt-54800這一 checkpoint 文件。若你的文件位置不同通過--ds2_ckpt參數(shù)顯式指定即可。該 checkpoint 只包含模型權(quán)重不含 metagraph因?yàn)橹貙?shí)現(xiàn)使用獨(dú)立搭建的 Keras 網(wǎng)絡(luò)通過張量名逐層加載權(quán)重這一點(diǎn)在下一節(jié)權(quán)重恢復(fù)中詳述。第三步運(yùn)行 compute_fdsd.py準(zhǔn)備兩個(gè)目錄各自存放一組 WAV 音頻一組為真實(shí)/參考音頻sample1一組為待評(píng)估的合成音頻sample2然后執(zhí)行python3 compute_fdsd.py \ --sample1 /path/to/real_audio \ --sample2 /path/to/fake_audio \ --ds2_ckpt ds2_large/model.ckpt-54800腳本運(yùn)行時(shí)會(huì)依次打印三類信息依據(jù) compute_fdsd.py 的主流程[i] Constructing datasets.、[i] Restoring DS2 checkpoint.、[i] Collecting samples.最后輸出[i] FDSD: %.3f格式的分?jǐn)?shù)。FDSD 數(shù)值越小說明兩組樣本在 DeepSpeech2 特征空間中的分布越接近即合成語音與真實(shí)語音的可區(qū)分度越低、質(zhì)量越高。compute_fdsd.py支持的完整命令行參數(shù)如下依據(jù) compute_fdsd.py參數(shù)類型默認(rèn)值說明--sample1str無必填第一組音頻樣本所在目錄--sample2str無必填第二組音頻樣本所在目錄--ds2_ckptstrds2_large/model.ckpt-54800DeepSpeech2 checkpoint 路徑--batch_sizeint64評(píng)估時(shí)的批大小輸入數(shù)據(jù)約定WAV 目錄與樣本數(shù)量一致性compute_fdsd.py對(duì)輸入有兩個(gè)硬性約束理解它們可以避免踩坑。約束一目錄下必須全部是.wav文件。數(shù)據(jù)集構(gòu)建函數(shù)make_wave_dataset通過os.path.join(path, *.wav)拼出文件匹配模式用tf.data.Dataset.list_files枚舉目錄下所有 WAV 文件再經(jīng)tf.audio.decode_wav解碼為波形張量依據(jù) compute_fdsd.py。約束二兩組樣本數(shù)量必須相等。腳本在構(gòu)建完兩個(gè)數(shù)據(jù)集后立即比較樣本數(shù)不一致會(huì)直接拋出UsageErrorif n_sample1 ! n_sample2: raise app.UsageError(Both sample sets must have the same number of waves (%d and %d). % (n_sample1, n_sample2))依據(jù) compute_fdsd.py。此外DS2Scorer.compute_scores內(nèi)部還會(huì)做一次兜底即使數(shù)量不同例如通過庫(kù) API 直接調(diào)用時(shí)也會(huì)取min(n_fake, n_real)個(gè)樣本參與計(jì)算并打印警告依據(jù) tts_scorer.py。特征收集階段使用tqdm顯示進(jìn)度并把每個(gè)樣本的激活單獨(dú)剝離出來逐條存入列表供后續(xù)統(tǒng)計(jì)計(jì)算使用依據(jù) compute_fdsd.py。工作原理從波形到 FDSD 分?jǐn)?shù)的完整數(shù)據(jù)流整個(gè) FDSD 計(jì)算可以拆成四段特征提取器搭建 → 波形預(yù)處理 → checkpoint 權(quán)重恢復(fù) → Fréchet 距離計(jì)算。1. DS2Scorer 與 DS2Encoder 模型結(jié)構(gòu)tts_scorer.py 中的DS2Scorer繼承了 scorer.py 中的NoOpScorer骨架用DS2Encoder作為實(shí)際推理模型并聲明只收集pooled_activations這一種輸出用于指標(biāo)計(jì)算。DS2Encoder依據(jù) ds2_encoder.py是對(duì) DeepSpeech2Amodei et al., 2016的結(jié)構(gòu)重實(shí)現(xiàn)其默認(rèn)超參數(shù)刻意與 Open Seq2Seq 的ds2_large_8gpus_mp配置保持一致結(jié)構(gòu)塊默認(rèn)配置說明卷積層兩層((11,41),(2,2),32)、((11,21),(1,2),32)Conv2D BatchNorm ReLUSAMEpadding、無 biasGRU 層5 層每層 800 單元雙向 GRUmerge_modeconcattanh 激活 sigmoid 循環(huán)激活全連接層1600 單元ReLU 激活的前 logits層代碼注釋注明本應(yīng)使用 float16 但 TPU 不支持CTC 層vocab_size29輸出 CTCDecoder 所需的 logitsDropout0.5每個(gè) GRU 層之后及全連接層之后施加模型前向__call__返回三個(gè)端點(diǎn)endpointsactivationsGRU 輸出經(jīng)全連接映射后的逐幀表示、pooled_activations對(duì)時(shí)間維度取平均專門為 FDSD 服務(wù)、logitsCTC 輸出。代碼注釋明確說明pooled_activations是Frechet DeepSpeech distance 所使用的量依據(jù) ds2_encoder.py。2. 特征前端 represent()從波形到標(biāo)準(zhǔn)化對(duì)數(shù)幅度譜DS2Encoder.represent方法負(fù)責(zé)把原始波形轉(zhuǎn)換為模型輸入依據(jù) ds2_encoder.py流程如下重縮放波形除以逐樣本最大絕對(duì)值并乘 32767模擬 16-bit PCM 的幅度范圍代碼中保留了與 PSF 完全一致的 int16 量化步驟注釋但因 TPU 不支持而默認(rèn)關(guān)閉加窗分幀默認(rèn)采樣率 24000 Hz、窗長(zhǎng) 0.02 s、窗移 0.01 s即 480 點(diǎn)漢寧窗、240 點(diǎn)步長(zhǎng)通過tf.signal.frame分幀STFT因?yàn)榇伴L(zhǎng)一般不是 2 的冪代碼用scipy.linalg.dft構(gòu)造 DFT 矩陣做矩陣乘法實(shí)現(xiàn) STFT取幅度譜后計(jì)算對(duì)數(shù)幅度10·log10特征選擇與標(biāo)準(zhǔn)化只保留前num_features160個(gè)頻點(diǎn)再用tf.nn.sufficient_statistics/tf.nn.normalize_moments沿時(shí)間與頻率軸做全局均值方差標(biāo)準(zhǔn)化。3. checkpoint 權(quán)重恢復(fù)CuDNN GRU 權(quán)重重排這是重實(shí)現(xiàn)中最精巧的部分。DS2Scorer.restore先向模型灌入一個(gè)形狀為[16, 48000, 1]的全 1 批次以觸發(fā)變量創(chuàng)建然后通過tf.train.load_checkpoint按張量名讀取權(quán)重依據(jù) tts_scorer.py。卷積、BatchNorm、全連接與 CTC 層的權(quán)重按ForwardPass/ds2_encoder/conv1/...、.../fully_connected/...等前綴直接賦值依據(jù) tts_scorer.py。GRU 部分則需要特殊處理原 checkpoint 中的cudnn_gru權(quán)重存儲(chǔ)格式與 KerasGRUCell不同load_gru_cell函數(shù)會(huì)把 gates kernel/bias、candidate 的 input/hidden projection 權(quán)重重新拼接為 Keras 期望的[kernel, recurrent_kernel, bias]三元組依據(jù) tts_scorer.py。這解釋了為什么必須依賴固定 checkpoint 結(jié)構(gòu)——權(quán)重是逐張量名對(duì)齊的。4. Fréchet 距離計(jì)算FID 數(shù)學(xué)在語音特征空間的遷移DS2Scorer.compute_scores先對(duì)兩組的pooled_activations分別計(jì)算均值向量mu與協(xié)方差矩陣sigma依據(jù) tts_scorer.py再調(diào)用 scorer.py 中的compute_frechet_inception_distancediff mu1 - mu2 covmean sqrtm(sigma1 · sigma2) # scipy.linalg.sqrtm FDSD diff·diff trace(sigma1) trace(sigma2) - 2·trace(covmean)這套公式與圖像領(lǐng)域 FID 完全同源——函數(shù)名也保留了compute_frechet_inception_distance的歷史命名。從源碼注釋Pooled activations are used by Frechet DeepSpeech distance可以確認(rèn)本實(shí)現(xiàn)計(jì)算的是無條件 FDSD即直接用兩組樣本池化特征的整體分布差異來衡量生成質(zhì)量不依賴任何條件標(biāo)簽論文正文中使用的 cFDSD 則是在此基礎(chǔ)上的條件化變體。數(shù)值穩(wěn)定性與工程細(xì)節(jié)奇異協(xié)方差處理sigma1.dot(sigma2)可能近乎奇異sqrtm結(jié)果含非有限值時(shí)會(huì)在兩個(gè)協(xié)方差對(duì)角線同時(shí)加上epsilon1e-6后重算并打印警告日志復(fù)數(shù)誤差防御矩陣平方根可能引入微小虛部代碼允許對(duì)角線虛部在1e-3容差內(nèi)并自動(dòng)取實(shí)部虛部不可忽略時(shí)直接拋出ValueError而不是靜默給出錯(cuò)誤分?jǐn)?shù)依據(jù) scorer.py顯式類型斷言mu必須為 1D 向量、sigma必須為 2D 矩陣且兩組形狀一致否則直接斷言失敗避免誤用TPU 兼容性取舍模型多處注釋提到應(yīng)使用 float16 但 TPU 不支持說明該實(shí)現(xiàn)有意兼顧多種硬件環(huán)境依據(jù) ds2_encoder.py。在 GED 論文中的角色與擴(kuò)展用法FDSD 重實(shí)現(xiàn)是《A Spectral Energy Distance for Parallel Speech Synthesis》項(xiàng)目ged_tts/的三大交付物之一與多尺度頻譜能量距離distance_function/spectral_ops.py和 GED 玩具示例toy_example并列依據(jù) ged_tts/README.md 的 Source code 一節(jié)。論文使用本實(shí)現(xiàn)報(bào)告了 cFDSD 指標(biāo)下的生成質(zhì)量對(duì)比因此當(dāng)你復(fù)現(xiàn)該論文或評(píng)估同類并行語音合成模型時(shí)ged_tts/fdsd即是論文所用指標(biāo)的官方參考實(shí)現(xiàn)。除了命令行用法你還可以把DS2Scorer作為庫(kù)函數(shù)嵌入自己的評(píng)估管線from ged_tts.fdsd.eval import DS2Scorer scorer DS2Scorer(ds2_large/model.ckpt-54800) scorer.restore() # 對(duì)任意波形批次調(diào)用 scorer.infer收集 pooled_activations 后 # 調(diào)用 scorer.compute_scores(real_samples..., fake_samples...) 得到 {FDSD: ...}已知限制與注意事項(xiàng)checkpoint 必須自備本倉(cāng)庫(kù)不隨代碼分發(fā) DeepSpeech2 預(yù)訓(xùn)練權(quán)重首次使用前需從 Open Seq2Seq 庫(kù)下載ds2_large模型并按默認(rèn)命名放置或通過--ds2_ckpt指定路徑權(quán)重按張量名對(duì)齊換用其他版本的 DeepSpeech2 checkpoint 時(shí)需要核對(duì)ForwardPass/ds2_encoder/...、cudnn_gru/...等張量名前綴是否一致否則恢復(fù)會(huì)失敗環(huán)境要求 TF 2.x所有模型與數(shù)據(jù)代碼基于tensorflow.compat.v2編寫不建議在 TF 1.x 環(huán)境中運(yùn)行樣本數(shù)量嚴(yán)格一致兩個(gè) WAV 目錄的文件數(shù)必須相同否則命令行會(huì)直接報(bào)錯(cuò)退出采樣率約定特征前端按 24 kHz、窗長(zhǎng) 20 ms、窗移 10 ms 的默認(rèn)參數(shù)做 STFT若你的音頻采樣率不同需要同步調(diào)整DS2Encoder構(gòu)造參數(shù)sample_freq、window_size、window_step以保證特征計(jì)算與 checkpoint 訓(xùn)練時(shí)一致。總體而言ged_tts/fdsd是一個(gè)小而完整的評(píng)估工具鏈從 WAV 目錄讀取、DeepSpeech2 特征提取、checkpoint 權(quán)重移植到 Fréchet 距離計(jì)算全部開源可查既是復(fù)現(xiàn) GED 論文實(shí)驗(yàn)結(jié)果的關(guān)鍵部件也可直接移植到其他語音合成項(xiàng)目中充當(dāng)自動(dòng)評(píng)估指標(biāo)?!久赓M(fèi)下載鏈接】google-researchGoogle Research項(xiàng)目地址: https://gitcode.com/gh_mirrors/go/google-research創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考