python實(shí)現(xiàn)語音常用度量方法的代碼詳解
語音信號處理一般都要進(jìn)行主觀評價實(shí)驗(yàn)和客觀評價實(shí)驗(yàn)。
- 主觀評價:邀請測聽者對語音進(jìn)行測聽,給出主觀意見得分
- 客觀評價:根據(jù)算法來衡量語音質(zhì)量
主觀投票受多種因素影響,如個體受試者的偏好和實(shí)驗(yàn)的語境(其他條件)。一個好的客觀質(zhì)量度量應(yīng)該與許多不同的主觀實(shí)驗(yàn)有很高的相關(guān)性
信噪比(SNR)
有用信號功率與噪聲功率的比(此處功率為平均功率),也等于幅度比的平方
其中:$P_{signal}$為信號功率(平均功率或者實(shí)際功率);$P_{noise}$為噪聲功率;$A_{signal}$為信號幅度;$A_{noise}$為噪聲幅度值,功率等于幅度值的平方
MATLAB版本代碼
# 信號與噪聲長度應(yīng)該一樣 function snr=SNR_singlech(Signal,Noise) P_signal = sum(Signal-mean(Signal)).^2; # 信號的能量 P_noise = sum(Noise-mean(Noise)).^2; # 噪聲的能量 snr = 10 * log10(P_signal/P_noise)
tensorflow版本SNR
def tf_compute_snr(labels, logits): # labels和logits都是三維數(shù)組 (batch_size, wav_data, 1) signal = tf.reduce_mean(labels ** 2, axis=[1, 2]) noise = tf.reduce_mean((logits - labels) ** 2, axis=[1, 2]) noise = tf.reduce_mean((logits - labels) ** 2 + 1e-6, axis=[1, 2]) snr = 10 * tf.log(signal / noise) / tf.log(10.) # snr = 10 * tf.log(signal / noise + 1e-8) / tf.log(10.) snr = tf.reduce_mean(snr, axis=0) return snr
def Volodymyr_snr(labels, logits): # labels和logits都是三維數(shù)組 (batch_size, wav_data, 1) noise = tf.sqrt(tf.reduce_mean((logits - labels) ** 2 + 1e-6, axis=[1, 2])) signal = tf.sqrt(tf.reduce_mean(labels ** 2, axis=[1, 2])) snr = 20 * tf.log(signal / noise + 1e-8) / tf.log(10.) avg_snr = tf.reduce_mean(snr, axis=0) return avg_snr
Volodymyr Kuleshov論文實(shí)現(xiàn)方法
批注:這里的1e-6和1e-8,目的是為了防止出現(xiàn)Nan值,如果沒有這個需求可以去除
numpy版本代碼
def numpy_SNR(labels, logits): # origianl_waveform和target_waveform都是一維數(shù)組 (seq_len, ) # np.sum實(shí)際功率;np.mean平均功率,二者結(jié)果一樣 signal = np.sum(labels ** 2) noise = np.sum((labels - logits) ** 2) snr = 10 * np.log10(signal / noise) return snr
峰值信噪比(PSNR)
表示信號的最大瞬時功率和噪聲功率的比值,最大瞬時功率為語音數(shù)據(jù)中最大值得平方。
def psnr(label, logits): MAX = np.max(label) ** 2 # 信號的最大平時功率 MSE = np.mean((label - logits) ** 2) return np.log10(MAX / MSE)
分段信噪比(SegSNR)
由于語音信號是一種緩慢變化的短時平穩(wěn)信號,因而在不同時間段上的信噪比也應(yīng)不一樣。為了改善上面的問題,可以采用分段信噪比。分段信噪比即是先對語音進(jìn)行分幀,然后對每一幀語音求信噪比,最好求均值。
MATLAB版本的代碼
function [segSNR] = Evaluation(clean_speech,enhanced) N = 25*16000/1000; %length of the segment in terms of samples M = fix(size(clean_speech,1)/N); %number of segments segSNR = zeros(size(enhanced)); for i = 1:size(enhanced,1) for m = 0:M-1 sum1 =0; sum2 =0; for n = m*N +1 : m*N+N sum1 = sum1 +clean_speech(n)^2; sum2 = sum2 +(enhanced{i}(n) - clean_speech(n))^2; end r = 10*log10(sum1/sum2); if r>55 r = 55; elseif r < -10 r = -10; end segSNR(i) = segSNR(i) +r; end segSNR(i) = segSNR(i)/M; end
python代碼
def SegSNR(ref_wav, in_wav, windowsize, shift): if len(ref_wav) == len(in_wav): pass else: print('音頻的長度不相等!') minlenth = min(len(ref_wav), len(in_wav)) ref_wav = ref_wav[: minlenth] in_wav = in_wav[: minlenth] # 每幀語音中有重疊部分,除了重疊部分都是幀移,overlap=windowsize-shift # num_frame = (len(ref_wav)-overlap) // shift # = (len(ref_wav)-windowsize+shift) // shift num_frame = (len(ref_wav) - windowsize + shift) // shift # 計(jì)算幀的數(shù)量 SegSNR = np.zeros(num_frame) # 計(jì)算每一幀的信噪比 for i in range(num_frame): noise_frame_energy = np.sum(ref_wav[i * shift: i * shift + windowsize] ** 2) # 每一幀噪聲的功率 speech_frame_energy = np.sum(in_wav[i * shift: i * shift + windowsize] ** 2) # 每一幀信號的功率 SegSNR[i] = np.log10(speech_frame_energy / noise_frame_energy) return 10 * np.mean(SegSNR)
信號回聲比 (Signal to echo ratio, SER)
其中E是統(tǒng)計(jì) 期望操作,$s(n)$是近端語音,$d(n)$是遠(yuǎn)端回聲
def SER(near_speech, far_echo): """signal to echo ratio, 信號回聲比 :param near_speech: 近端語音 :param far_echo: 遠(yuǎn)端回聲 """ return 10*np.log10(np.mean(near_speech**2)/np.mean(far_echo**2))
回聲損失增強(qiáng) (Echo Return Loss Enhancement, ERLE)
回波損失增強(qiáng)度量(ERLE)通常用于評估系統(tǒng)在沒有近端信號的單通話情況下 的回聲減少。ERLE的定義是
其中E是統(tǒng)計(jì) 期望操作,$y(n)$是麥克風(fēng)信號,$\hat{s}(n)$是估計(jì)的近端語音信號。
def compute_ERLE(mic_wav, predict_near_end_wav): """ :param mic_wav: 麥克風(fēng)信號(y) = 近端語音(s) + 遠(yuǎn)端語音回聲(s) + 噪聲(v) :param predict_near_end_wav: 估計(jì)的近端語音信號 \hat{s} 麥克風(fēng)信號 """ mic_mear = np.mean(mic_wav**2) predict_near_end_wav = np.mean(predict_near_end_wav**2) ERLE = 10 * np.log10(mic_mear/predict_near_end_wav) return ERLE
為了評估系統(tǒng)在雙講情況下的性能,通常采用PESQ(語音質(zhì)量感知評價)或STOI (短時語音可懂度),他是通過將估計(jì)的近端語音和僅在雙講通話期間真實(shí)的近端語音進(jìn)行比較得到的。PESQ評分范圍為-0.5 ~ 4.5,分?jǐn)?shù)越高質(zhì)量越好。STOI評分范圍為0~1,分?jǐn)?shù)越高越好。
對數(shù)擬然對比度 (log Likelihood Ratio Measure)
坂倉距離測度是通過語音信號的線性預(yù)測分析來實(shí)現(xiàn)的。ISD基于兩組線性預(yù)測參數(shù)(分別從原純凈語音和處理過的語音的同步幀得到)之間的差異。LLR可以看成一種坂倉距離(Itakura Distance,IS)但是IS距離需要考慮模型增益。而LLR不需要考慮模型爭議引起的幅度位移,更重視整體譜包絡(luò)的相似度。
語音質(zhì)量感知評估 (Perceptual Evaluation of Speech Quality, PESQ)
引言:我先做個簡要介紹,再講使用。使用之前建議還是詳細(xì)了解一下,不要用錯了,導(dǎo)致論文被拒,或者做了偽研究,以下內(nèi)容是我挑重點(diǎn)摘自ITU-T P862建議書,比較權(quán)威,重要的地方我會加粗。想要進(jìn)一步了解的自行去下載原文。
PESQ是由國際電信聯(lián)盟(International Telecommunication Union,ITU) 2001年提供的ITU-T P862建議書:語音質(zhì)量的感知評估(PESQ):窄帶電話網(wǎng)絡(luò)和語音編解碼器的端到端語音質(zhì)量評估的客觀方法,并提供了ANSI-C語言實(shí)現(xiàn)代碼。真實(shí)系統(tǒng)可能包括濾波和可變延遲,以及由于信道誤差和低比特率編解碼器引起的失真。國際電聯(lián)電信政策861中描述的PSQM方法僅被推薦用于評估語音編解碼器,不能適當(dāng)考慮濾波、可變延遲和短時局部失真。PESQ通過傳遞函數(shù)均衡、時間校準(zhǔn)和一種新的時間平均失真算法來解決這些影響。PESQ的驗(yàn)證包括許多實(shí)驗(yàn),這些實(shí)驗(yàn)專門測試了它在濾波、可變延遲、編碼失真和信道誤差等因素組合下的性能。
建議將PESQ用于3.1kHz(窄帶)手機(jī)電話和窄帶語音編解碼器的語音質(zhì)量評估。PESQ是屬于客觀評價,和主觀分?jǐn)?shù)之間的相關(guān)性約為0.935,但PESQ算法不能用來代替主觀測試。
PESQ算法沒有提供傳輸質(zhì)量的綜合評估。它只測量單向語音失真和噪聲對語音質(zhì)量的影響。響度損失、延遲、側(cè)音、回聲和其他與雙向互動相關(guān)的損傷(如中央削波器)的影響不會反映在PESQ分?jǐn)?shù)中。因此,有可能有很高的PESQ分?jǐn)?shù),但整體連接質(zhì)量很差。
PESQ的感知模型用于計(jì)算原始信號$X(t)$與退化信號$Y(t)$之間的距離(PESQ分?jǐn)?shù)),退化信號$Y(t)$是$X(t)$通過通信系統(tǒng)的結(jié)果。PESQ的輸出是對受試者在主觀聽力測試中給予$Y(t)$的感知質(zhì)量的預(yù)測。取值在-0.5到4.5的范圍內(nèi),得分越高表示語音質(zhì)量越好,盡管在大多數(shù)情況下輸出范圍在1.0到4.5之間。
ITU提供了C語言代碼,下載請點(diǎn)擊這里,但是在使用之前我們需要先編譯C腳本,生成可執(zhí)行文件exe
編譯方式為:在命令行進(jìn)入下載好的文件
- cd\Software\source
- gcc -o PESQ *.c
經(jīng)過編譯,會在當(dāng)前文件夾生成一個pesq.exe的可執(zhí)行文件
使用方式為:
- 命令行進(jìn)入pesq.exe所在的文件夾
- 執(zhí)行命令:pesq 采樣率 "原始文件路徑名" "退化文件路徑名”,采樣率必須選擇+8000(窄帶)或+16000(寬帶),
- 回車
- 等待結(jié)果即可,值越大,質(zhì)量越好。
例如:pesq +16000 raw.wav processed.wav
python代碼實(shí)現(xiàn)
參考地址:https://github.com/ludlows/python-pesq
首先我們需要安裝pesq庫:pip install pesq
from scipy.io import wavfile from pesq import pesq rate, ref = wavfile.read("./audio/speech.wav") rate, deg = wavfile.read("./audio/speech_bab_0dB.wav") print(pesq(rate, ref, deg, 'wb')) print(pesq(rate, ref, deg, 'nb'))
該python庫返回的是MOS-LQO,屬于pesq的映射,現(xiàn)在用的更多的也是MOS-LQO。如果你硬是想要PESQ得分,你可以自行逆變換回去,公式見下一節(jié)
MOS-LQO
MOS-LQO (Mean Opinion Score – Listening Quality Objective),使用客觀測量技術(shù)評估主觀聽力質(zhì)量)與之相對的還有MOS-LQS(Mean Opinion Score – Listening Quality Subjective),使用樣本的主觀評分直接衡量聽力質(zhì)量,就是主觀評價了。
功能:將P.862原始結(jié)果分?jǐn)?shù)轉(zhuǎn)換為MOS-LQO的映射,P862.1:用于將P.862原始結(jié)果分?jǐn)?shù)轉(zhuǎn)換為MOS-LQO的映射函數(shù).pdf
ITU-TP.862建議書提供的原始分?jǐn)?shù)在-0.5到4.5之間。希望從PESQ (P.862)得分中轉(zhuǎn)換為MOS-LQO (P.862.1)分?jǐn)?shù),從而可以與MOS進(jìn)行線性比較。該建議書介紹了從原始P.862得分到MOS-LQO(P.800.1)的映射函數(shù)及其性能。映射函數(shù)已在代表不同應(yīng)用程序和語言的大量主觀數(shù)據(jù)上進(jìn)行了優(yōu)化,所呈現(xiàn)的性能優(yōu)于原始的PESQ(P862),取值在[1, 4.5]之間,連續(xù)的。公式為:
$$公式1:y=0.999+\frac{4.999-0.999}{1+e^{-1.4945x+4.6607}}$$
python實(shí)現(xiàn)
def pesq2mos(pesq): """ 將PESQ值[-0.5, 4.5]映射到MOS-LQO得分[1, 4.5]上,映射函數(shù)來源于:P.862.1 """ return 0.999 + (4.999 - 0.999) / (1 + np.exp(-1.4945 * pesq + 4.6607))
MATLAB官方實(shí)現(xiàn)請參見:
- v_pesq2mos.m
- pesq2mos.m
公式2給出了從MOS-LQO分?jǐn)?shù)到PESQ分?jǐn)?shù)的轉(zhuǎn)換的反映射函數(shù)
python實(shí)現(xiàn)
def mos2pesq(mos): """ 將MOS-LQO得分[1, 4.5]映射到PESQ值[-0.5, 4.5]上,映射函數(shù)來源于:P.862.1""" inlog = (4.999 - mos) / (mos - 0.999) return (4.6607 - np.log(inlog)) / 1.4945
需要注意的是,所提供的函數(shù)有一些實(shí)際限制:
- 本文提供的映射函數(shù)對源自所有類型應(yīng)用程序的數(shù)據(jù)庫進(jìn)行了優(yōu)化。僅針對特定應(yīng)用程序或語言進(jìn)行優(yōu)化的其他映射函數(shù)可能在該特定應(yīng)用程序或語言上比提供的函數(shù)執(zhí)行得更好。
- 雖然訓(xùn)練數(shù)據(jù)庫包含分?jǐn)?shù)較低的MOS區(qū)域中的樣本比例很大,但是在原始P.862分?jǐn)?shù)0.5到1的范圍內(nèi)缺少樣本。在此范圍內(nèi),映射的P.862函數(shù)進(jìn)行插值,因此確定了預(yù)測誤差Ep和平均殘差Em
PESQ-WB
2007年11.13國際電聯(lián)公布了PESQ的寬帶版本(ITU-T P862.2,PESQ-WB),P.862建議書的寬帶擴(kuò)展,用于評估寬帶電話網(wǎng)絡(luò)和語音編解碼器,主要用于寬帶音頻系統(tǒng) (50-7000 Hz),盡管它也可以應(yīng)用于帶寬較窄的系統(tǒng)。例如聽眾使用寬帶耳機(jī)的語音編解碼器。相比之下,ITU-T P.862建議書假設(shè)使用標(biāo)準(zhǔn)的IRS型窄帶電話手機(jī),在300 Hz以下和3100 Hz以上會強(qiáng)烈衰減。
使用范圍
- 不建議將PESQ-WB用在信號插入點(diǎn)和信號捕獲點(diǎn)之間包含噪聲抑制算法的系統(tǒng)。 另外,應(yīng)使用干凈的語音樣本,因?yàn)猷须s的語音樣本,即那些信噪比較差的語音樣本,可能會導(dǎo)致預(yù)測錯誤。 用戶還應(yīng)注意,寬帶語音主觀實(shí)驗(yàn)中不同失真類別的相對排名可能會隨語言種類而略有變化。 特別要注意的是,寬帶擴(kuò)展可能會高估ITU-T Rec.3建議書的MOS分?jǐn)?shù)。
- 當(dāng)使用PESQ-WB來比較可能對音頻信號進(jìn)行頻帶限制的系統(tǒng)的性能時,建議使用一個寬帶(50-7000 Hz音頻帶寬)版本的信號作為所有參考信號。被限制帶寬的測試系統(tǒng)會導(dǎo)致語音性能下降,降低輸出分?jǐn)?shù)。這種限制可能會降低信號的預(yù)測精度。不建議存在信號退化的嚴(yán)重限制,即小于傳統(tǒng)電話帶寬(300- 3400hz) 。
- PESQ-WB是評估寬帶語音條件的主觀實(shí)驗(yàn)的背景下預(yù)測主觀意見,即音頻帶寬從50赫茲擴(kuò)展到7000赫茲的信號。這意味著,由于不同的實(shí)驗(yàn)環(huán)境,無法直接比較寬帶擴(kuò)展產(chǎn)生的分?jǐn)?shù)和基線[ITU-T P862]或[ITU-T P862.1]產(chǎn)生的分?jǐn)?shù)。
基本的P.862模型提供的原始分?jǐn)?shù)在–0.5到4.5之間。 [ITU-T P.862]的PESQ-WB包括一個映射函數(shù),輸出的也是映射值,該函數(shù)允許與主觀評價的MOS得分進(jìn)行線性比較,這些主觀實(shí)驗(yàn)包括音頻帶寬為50-7000 Hz的寬帶語音條件。 這意味著由于實(shí)驗(yàn)環(huán)境的不同,無法直接比較PESQ-WB產(chǎn)生的分?jǐn)?shù)和基線[ITU-T P.862]或[ITU-T P.862.1]產(chǎn)生的分?jǐn)?shù)。PESQ-WB中使用的輸出映射函數(shù)定義如下:
其中$x$是原模型輸出。
[ITU-T P.862]的附件A中給出了了PESQ-WB的寬帶擴(kuò)展的ANSI-C參考實(shí)現(xiàn)。
感知客觀語音質(zhì)量評估 (POLQA)
POLQA度量方法授權(quán)給了epticom公司,只有該公司授權(quán)的機(jī)構(gòu)才能使用,我總結(jié)在這就是讓大家了解一下,反正我們都用不了,哈哈
ITU P.863建議書提供了一種客觀評價方法:感知客觀語音質(zhì)量評估 (Perceptual objective listening quality prediction, P.OLQA),ITU-T P.863建議書支持兩種操作模式,一種用于窄帶 (NB, 300Hz-3.4kHz),一種用于全帶 (FB, 20Hz-20kHz)。
可以應(yīng)用到全頻帶語音編解碼器(例如,OPUS,增強(qiáng)語音服務(wù)(EVS))。比較參考信號X(t)和退化信號Y(t),其中Y(t)是通過通信系統(tǒng)傳遞X(t)的結(jié)果,人類聽覺系統(tǒng)中音頻信號的心理物理表征,
ITU-T P.863算法消除了參考信號中的低水平噪聲,同時對退化輸出信號中的噪聲也進(jìn)行了部分抑制。
一個好的客觀質(zhì)量測量應(yīng)該與多個不同的主觀實(shí)驗(yàn)有很高的相關(guān)性。在實(shí)踐中,使用ITU-T P.863算法,回歸映射通常幾乎是線性的,在日常實(shí)踐中,不需要對客觀分?jǐn)?shù)進(jìn)行特殊映射,因?yàn)镮TU-T P.863分?jǐn)?shù)已經(jīng)映射到MOS尺度,反映了大量單獨(dú)數(shù)據(jù)集的平均值。
POLQA結(jié)果主要是模型平均意見得分(MOS),涵蓋從1(差)到5(優(yōu)秀)的范圍。在全頻帶模式下得分為MOS-LQO 4.80,在窄帶模式下得分為MOS-LQO 4.5。這反映了一個事實(shí),即不是所有的主觀測試參與者都會給最高的評級,即使是不降級的參考。
對數(shù)譜距離(LSD)
對數(shù)譜距離Log Spectral Distance,LSD是兩個頻譜之間的距離度量。也稱為“對數(shù)譜失真”
式中,$l$和$m$分別為頻率索引和幀索引,$M$為語音幀數(shù),$L$為頻點(diǎn)數(shù),$\hat{S}(l, m)$和$S(l, m)$分別為估計(jì)音頻和寬帶音頻經(jīng)過短時短時傅里葉變換后的頻譜。
numpy版本
# 方法一 def numpy_LSD(labels, logits): """ labels 和 logits 是一維數(shù)據(jù) (seq_len,)""" labels_spectrogram = librosa.stft(labels, n_fft=2048) # (1 + n_fft/2, n_frames) logits_spectrogram = librosa.stft(logits, n_fft=2048) # (1 + n_fft/2, n_frames) labels_log = np.log10(np.abs(labels_spectrogram) ** 2) logits_log = np.log10(np.abs(logits_spectrogram) ** 2) # 先處理頻率維度 lsd = np.mean(np.sqrt(np.mean((labels_log - logits_log) ** 2, axis=0))) return lsd # 方法二 def get_power(x): S = librosa.stft(x, n_fft=2048) # (1 + n_fft/2, n_frames) S = np.log10(np.abs(S) ** 2) return S def compute_log_distortion(labels, logits): """labels和logits數(shù)據(jù)維度為 (batch_size, seq_len, 1)""" avg_lsd = 0 batch_size = labels.shape[0] for i in range(batch_size): S1 = get_power(labels[i].flatten()) S2 = get_power(logits[i].flatten()) # 先處理頻率軸,后處理時間軸 lsd = np.mean(np.sqrt(np.mean((S1 - S2) ** 2, axis=0)), axis=0) avg_lsd += lsd return avg_lsd / batch_size
tensorflow版本
def get_power(x): x = tf.squeeze(x, axis=2) # 去掉位置索引為2維數(shù)為1的維度 (batch_size, input_size) S = tf.signal.stft(x, frame_length=2048, frame_step=512, fft_length=2048, window_fn=tf.signal.hann_window) # [..., frames, fft_unique_bins] S = tf.log(tf.abs(S) ** 2) / tf.log(10.) # S = tf.log(tf.abs(S) ** 2 + 9.677e-9) / tf.log(10.) return S def tf_compute_log_distortion(labels, logits): """labels和logits都是三維數(shù)組 (batch_size, input_size, 1)""" S1 = get_power(labels) # [..., frames, fft_unique_bins] S2 = get_power(logits) # [..., frames, fft_unique_bins] # 先處理頻率維度,后處理時間維度 lsd = tf.reduce_mean(tf.sqrt(tf.reduce_mean((S1 - S2) ** 2, axis=2)), axis=1) lsd = tf.reduce_mean(lsd, axis=0) return lsd
但如果想要numpy版本的值和tensorflow版本的值一樣,可以使用下面的代碼
# numpy版本一:處理一個batch,(batch, seq_len, 1) def numpy_LSD(labels, logits): """ labels 和 logits 是一維數(shù)據(jù)""" labels_spectrogram = librosa.stft(labels, n_fft=2048, hop_length=512, win_length=2048, window="hann", center=False) # (1 + n_fft/2, n_frames) logits_spectrogram = librosa.stft(logits, n_fft=2048, hop_length=512, win_length=2048, window="hann", center=False) # (1 + n_fft/2, n_frames) labels_log = np.log10(np.abs(labels_spectrogram) ** 2 + 1e-8) logits_log = np.log10(np.abs(logits_spectrogram) ** 2 + 1e-8) original_target_squared = (labels_log - logits_log) ** 2 lsd = np.mean(np.sqrt(np.mean(original_target_squared, axis=0))) return lsd # numpy版本二:處理一個batch,(batch, seq_len, 1) def get_power1(x): S = librosa.stft(x, n_fft=2048, hop_length=512, win_length=2048, window="hann", center=False) # (1 + n_fft/2, n_frames) S = np.log10(np.abs(S) ** 2 + 1e-8) return S def compute_log_distortion(labels, logits): avg_lsd = 0 batch_size = labels.shape[0] for i in range(batch_size): S1 = get_power1(labels[i].flatten()) S2 = get_power1(logits[i].flatten()) # 先處理頻率軸,后處理時間軸 lsd = np.mean(np.sqrt(np.mean((S1 - S2) ** 2, axis=0)), axis=0) avg_lsd += lsd return avg_lsd / batch_size # tensorflow版本 def get_power(x): x = tf.squeeze(x, axis=2) # 去掉位置索引為2維數(shù)為1的維度 (batch_size, input_size) S = tf.signal.stft(x, frame_length=2048, frame_step=512, fft_length=2048, window_fn=tf.signal.hann_window) # [..., frames, fft_unique_bins] S = tf.log(tf.abs(S) ** 2 + 9.677e-9) / tf.log(10.) return S def tf_compute_log_distortion(labels, logits): # labels和logits都是三維數(shù)組 (batch_size, input_size, 1) S1 = get_power(labels) # [..., frames, fft_unique_bins] S2 = get_power(logits) # [..., frames, fft_unique_bins] # 先處理頻率維度,后處理時間維度 lsd = tf.reduce_mean(tf.sqrt(tf.reduce_mean((S1 - S2) ** 2, axis=2)), axis=1) lsd = tf.reduce_mean(lsd, axis=0) return lsd
批注:librosa.stft中center設(shè)為False,和np.log10中加1e-8,目的是為了最終的值和tensorflow版本的lsd值相近,如果沒有這個需求可以去除。這里tf.log中加9.677e-9是為了和numpy中的值相近,如果沒有這個需求可以去除
短時客觀可懂度(STOI)
下載一個 pystoi 庫:pip install pystoi
STOI 反映人類的聽覺感知系統(tǒng)對語音可懂度的客觀評價,STOI 值介于0~1 之間,值越大代表語音可懂度越高,越清晰。
from pystoi import stoi stoi_score = stoi(label, logits, fs_sig=16000)
加權(quán)譜傾斜測度(WSS)
WSS值越小說明扭曲越少,越小越好,范圍
參考
【CSDN文章】PESQ語音質(zhì)量測試
視頻質(zhì)量度量指標(biāo)
度量方法倉庫
【github代碼,內(nèi)涵多種度量方法】pysepm
【python庫】python-pesq
【python庫】pystoi
speechmetrics
Voice quality metrics
以上就是python實(shí)現(xiàn)語音常用度量方法的詳細(xì)內(nèi)容,更多關(guān)于python語音度量方法的資料請關(guān)注本站其它相關(guān)文章!
版權(quán)聲明:本站文章來源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請保持原文完整并注明來源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來,僅供學(xué)習(xí)參考,不代表本站立場,如有內(nèi)容涉嫌侵權(quán),請聯(lián)系alex-e#qq.com處理。