语音信号处理一般都要进行主观评价实验和客观评价实验。
主观听力测试可能是评估语音质量或语音清晰度最可靠的方法。但是主观评价实验受到以下限制:
出于以上原因,研究人员设计了一些客观评价来评估语音质量。理想的客观评价方法应该能准确地预测由正常听力者进行的主观听力测试的结果,应包括语音不同处理层次的信息,包括低级信息(如心理声学)和高级信息(如语义、语言学和语用学)。本文概述了多种客观评价方法,这些方法已被用来评估质量和可理解度的语音处理的降噪算法。
本章需要使用的python库:
主观语音质量测量可以通过主观听力测试获得,在主观听力测试中,参与者根据意见量表对系统的性能或信号质量进行评价[表1]。主观听力测试通常由几个受试者进行,他们将听原始的(如果有的话),通过增强算法退化和增强的语音信号。受试者使用预定义的听力质量量表提供他们对每个信号质量的意见。最后,通过平均分得到的MOS值表明了被测算法的主观质量。为了获得一个真实的MOS,需要大量的受试者。因此,主观质量测量的主要缺点是成本。即使有大量的被试,MOS的方差也可能很高。此外,从测试中获得的主观评分还取决于听力工具的类型和质量(耳机或扬声器)和环境条件。
主观质量评价可分为相对偏好法和绝对品类评价法两类。在相对偏好方法中,听者被提供成对的语音刺激。它们是参考刺激和测试刺激。听众在听经过处理的演讲之前,将未处理的演讲作为参考呈现给他们。在绝对类别评价方法中,只提出了试验刺激。
这一般分为两个阶段,即训练和评估阶段。在训练阶段,向听众提供一组参考信号及其评级。
主观方法就是通过人类对语音进行打分,比如MOS、CMOS和ABX Test。
绝对等级评价(ACR)
失真等级评价(DCR)
相对等级评价(CCR)
最常用和相对简单的主观质量指标是分级判断方法,采取5个级别对被测语音的质量进行评价。待测语音的质量是在所有试听人员的评分上求平均得到的。这种方式被称作平均意见得分(Mean Opinion Score, MOS)。下表给出了语音评价的等级分级。
评分 | 语音质量 | 失真程度 |
5 | 非常好(Excellent) | 不可察觉(Imperceptible) |
4 | 好(Good) | 略可察觉(Not annoying) |
3 | 一般(Fair) | 可察觉(Slightly annoying) |
2 | 差(Poor) | 不可接受(Not objectionable) |
1 | 很差(Bad) | 难以接受(objectionable) |
MOS评分有两个阶段。训练阶段,听者需要听一系列参考信号,保证大家对质量评级的标准尽可能一致;评估阶段,试听人员对所听到的信号,进行主观打分。
客观评价的度量可以分为有参考度量和无参考度量。
一般来说,客观的语音质量指标可以分为
有用信号功率与噪声功率的比(此处功率为平均功率),也等于幅度比的平方
SNR(dB)=10log10∑N−1n=0s2(n)∑N−1n=0d2(n)=10∗log10(PsignalPnoise)=20∗log10(AsignalAnoise)
SNR(dB)=10log10∑N−1n=0s2(n)∑N−1n=0[x(n)−s(n)]2
其中:
- # 信号与噪声长度应该一样
- 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)
MATLAB版本SNR
- def tf_compute_snr(labels, logits):
- # labels和logits都是三维数组 (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都是三维数组 (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
批注:这里的1e-6和1e-8,目的是为了防止出现Nan值,如果没有这个需求可以去除
numpy版本代码
- def numpy_SNR(labels, logits):
- # origianl_waveform和target_waveform都是一维数组 (seq_len, )
- # np.sum实际功率;np.mean平均功率,二者结果一样
- signal = np.sum(labels ** 2)
- noise = np.sum((labels - logits) ** 2)
- snr = 10 * np.log10(signal / noise)
- return snr
由于语音信号是一种缓慢变化的短时平稳信号,因而在不同时间段上的信噪比也应不一样。为了改善上面的问题,可以采用分段信噪比。分段信噪比(Segmental Signal-to-Noise Ratio Measures, SegSNR)是先对语音进行分帧,然后对每一帧语音求信噪比,最后求均值。
SNRseg=10M∑M−1m=0log10∑Nm+N−1n=Nmx2(n)∑Nm+N−1n=Nm[x(n)−ˆx(n)]2
其中
SNRseg有一个潜在问题,语音信号(在会话语音中非常丰富)在安静期间的信号能量非常小,导致较大的负SNRseg值,这将使整体评估出现偏差。为了解决这一问题可以使用VAD检测的方法在只有语音段才计算信噪比。另外一种方法就是限制信噪比在一定范围内如[-10, 35dB]这样就不需要额外进行VAD检测。
后续研究通过将 log 函数移动 1 提出了分段 SNR 的不同定义,即
SNRsegR=10M∑M−1m=0log10(1+∑Nm+N−1n=Nmx2(n)∑Nm+N−1n=Nm(x(n)−ˆx(n))2)
这样做可以避免在沉默(silent)语音帧期间获得大的负值的可能性。 因为SNRseg_R的最小可值现在为零而不是负无穷大。 上述分段 SNR 定义的主要优点是它避免了对语音和无语音帧进行显式标记的需要。
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代码
- import pysepm
-
- pysepm.SNRseg(clean_speech, noisy_speech, fs)
具体细节
- 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 # 计算帧的数量
-
- SegSNR = np.zeros(num_frame)
- # 计算每一帧的信噪比
- 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)
频率加权分段信噪比(Frequency-weighted Segmental SNR,fwSNRseg)与SegSNR相似,只是在频带上增加了一个平均。频带与耳朵的临界频带成正比。FWSSNR可定义为:
fwSNRseg =10M∑M−1m=0∑Kj=1Wjlog10[X2(j,m)/(X(j,m)−ˆX(j,m))2]∑Kj=1Wj
其中
与时域 SNRseg相比,fwSNRseg 可以为频谱的不同频段设置不同权重。 在选择感知动机(motivated)的频率间隔方面(例如临界频带间隔)也具有灵活性。
- import pysepm
-
- fwSNRseg = pysepm.fwSNRseg(clean_speech, enhanced_speech, fs)
权重可以通过回归分析得到(有兴趣的可以搜索frequency-variant objective measures),另一种方法就是查表,如下表所示。
表示信号的最大瞬时功率和噪声功率的比值,最大瞬时功率为语音数据中最大值得平方。
ˆsi=starget +einterf +enoise +eartif
其中,starget是真正的源,einterf是干扰、enoise是噪声、eartif是人工伪影。
SNR(dB)=10log10MAX[s(n)]21N∑N−1n=0[x(n)−s(n)]2=20log10MAX[s(n)]√MSE
- def psnr(label, logits):
- MAX = np.max(label) ** 2 # 信号的最大平时功率
- MSE = np.mean((label - logits) ** 2)
- return np.log10(MAX / MSE)
Scale-invariant signal to distortion ratio (SI-SDR),SI-SDR也被称为SI-SNR,常用于语音分离。
【论文】2019_SDR–half-baked or well done?
SI-SDR =10log10(‖etarget ‖2‖eres ‖2)=10log10(‖ˆsTs‖s‖2s‖2‖ˆsTs‖s‖2s−ˆs‖2)
- def SI_SDR(estimate, reference):
- """Scale-Invariant Signal to Distortion Ratio (SI-SDR)
- :param estimate:估计的信号
- :param reference:参考信号
- """
- eps = np.finfo(np.float).eps
- alpha = np.dot(estimate.T, reference) / (np.dot(estimate.T, estimate) + eps)
- print(alpha)
-
- molecular = ((alpha * reference) ** 2).sum() # 分子
- denominator = ((alpha * reference - estimate) ** 2).sum() # 分母
-
- return 10 * np.log10((molecular) / (denominator+eps))
这类方法是以LPC 分析技术为基础的, 把LPC 系数及其导出参数作为评价的依据参量。由LPC 导出的方法有:LRC(Linear reflection coefficient)、LLR(Log likelihood ratio)、LSP(Linespecturm pairs)、LAR(Log area ratio)、ISD(Itakura-Saito Distance)、CD(CDCepstrum Distance)等方法以及它们的一些改进方法
有的算法针对干净语音和增强语音信号的所有LPC模型之间的差异,提出了客观评价标准。我们将语音用p阶全极点模型来表示,即
x(n)=∑pi=1ax(i)x(n−i)+Gxu(n)
其中
坂仓距离(Itakura-Saito Distance,ISD)通过语音信号的线性预测分析来实现的。ISD基于两组线性预测参数(分别从干净语音和增强语音的同步帧得到)之间的差异。
dLS=GxˉGx¯aTˆxRx¯axaTˆxRxax+log(GxˉGx)−1
其中Gx为增益,计算公式为:
Gx=(rTxax)1/2
rTx是自相关矩阵的第一行。这种方法有个缺点增强信号和原始信号频谱的差异会被这个算法惩罚,但心理声学研究表明频谱水平的差异对质量的影响最小。
对数似然比(log Likelihood Ratio,LLR),LLR可以看成一种坂仓距离(Itakura-Saito Distance,ISD)但是ISD距离需要考虑模型增益。而LLR不需要考虑模型争议引起的幅度位移,更重视整体谱包络的相似度。其计算方式为:
dLLR(ax,¯aˆx)=log¯aTˆxRx¯axaTˆxRxax
同样的将其扩展到频域
dLLR(ax,¯aˆx)=log(1+∫π−π|Ax(ω)−ˉAˆx(ω)Ax(ω)|2dω)
其中ax是原始语音的LPC系数,¯ax是增强后语音的LPC系数,Rx是原始语音LPC系数的自相关矩阵。Ax(w)对应的是频谱。LLR可以理解为增强信号和原始号的预测残差的能量之比。
- import pysepm
-
- llr_value = pysepm.llr(clean_speech, enhanced_speech, fs)
对数面积比(Log-area Ratio,LAR)度量也涉及到LP分析,但依赖于LP反射系数。
LAR=|1P∑Pi=1(log1+rs(i)1−rs(i)−log1+rd(i)1−rd(i))2|1/2
其中rs(i)和rd(i)是LP反射系数矢量,定义为
rs(i)=1+as(i)1−as(i),rd(i)=1+ad(i)1−ad(i)
由于反射系数与功率谱直接相关,LAR度量可以有效地估计纯净和干扰或增强语音信号的频谱对数之间的差异。
倒谱距离(Cepstrum Distance,CD),倒谱系数可以从LPC系数递归得到,即
c(m)=am+∑m−1k=1kmc(k)am−k
然后我们就可以使用基于倒谱的测度
dcep (cx,¯cˆx)=10ln10√2∑pk=1[cx(k)−cˆx(k)]2
- import pysepm
-
- pysepm.cepstrum_distance(clean_speech, enhanced_speech, fs)
基于频谱距离的评价方法是以语音信号平滑谱之间的比较为基础的。谱距离评价有很多种, 主要有:SD(Spectral Distance)、LSD(Log SD)、FVLISD(Frequency variant linear SD)、FVLOSD(Frequency variant log SD)、WSD(Weighted-slope SD)、ILSD(Inverse log SD)等方法。
频谱距离评价通常优先于时域评价,因为频谱较少受到原始和增强信号之间可能的时间偏差的影响。
对数谱距离(Log-Spectral Distance,LSD),LSD是两个频谱之间的距离度量。也称为“对数谱失真”
LSD=1T∑Tt=1√{1F∑Ff=1[10log10|s(t,f)|2−10log10|ˆs(t,f)|2]2}
式中,f和t分别为频率索引和帧索引,T为语音帧数,F为频点数,ˆS(t,f)和S(t,f)分别为估计音频和宽带音频经过短时短时傅里叶变换后的幅度谱。
numpy版本
- # 方法一
- def numpy_LSD(labels, logits):
- """ labels 和 logits 是一维数据 (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数据维度为 (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维数为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都是三维数组 (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 是一维数据"""
- 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维数为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都是三维数组 (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设为False,和np.log10中加1e-8,目的是为了最终的值和tensorflow版本的lsd值相近,如果没有这个需求可以去除。这里tf.log中加9.677e-9是为了和numpy中的值相近,如果没有这个需求可以去除
【论文】Mel-cepstral distance measure for objective speech quality assessment
梅尔倒谱距离(Mel-cepstral distance, MCD)
该类评价方法是以人感知语音信号的心理听觉特性为基础。具有代表性的听觉模型方法有BSD、MBSD、PSQM、PESQ、PLP、MSD(Mel Spectral Distortion)等。
心理声学研究表明,人们对共振峰频率不同的成对元音感觉最敏锐。加权谱倾斜测度(Weighted Spectral Slope, WSS) 首先通过一阶差分来计算每个频段的频谱斜率
Sx(k)=Cx(k+1)−Cx(k)
ˉSx(k)=ˉCx(k+1)−ˉCx(k)
然后根据频段是在谱峰值附近还是在波谷附近,峰值是否是最大峰值等条件对谱斜率进行加权,加权公式为:
W(k)=Kmax
其中max下标表示全局最大值,locmax表示离其最近的最大值。最后WSS测度可以表示为:
d_{W S M}\left(C_{x}, \bar{C}_{x}\right)=\sum_{k=1}^{36} W(k)\left(S_{x}(k)-\bar{S}_{\hat{x}}(k)\right)^{2}
WSS值越小说明扭曲越少,越小越好
- import pysepm
-
- pysepm.wss(clean_speech, enhanced_speech, fs)
巴克谱失真(Bark Spectral Distortion, BSD) 度量是基于语音质量与语音响度直接相关的假设。响度是一个心理声学术语,定义为听觉的大小。它本质上是一个包含心理声学反应的客观测量。BSD度量定义为原始语音和干扰或增强语音估计响度的平均平方欧氏距离。为了计算响度,使用心理声学测量结果对语音信号进行处理,包括:临界频带分析、等响度预加重(equal loudness pre-emphasis)和强度-响度幂律(intensity-loudness power law)。BSD测度计算为
B S D=\frac{1}{M} \frac{\sum_{m=1}^{M} \sum_{b=1}^{K}\left[L_{s}(b, m)-L_{d}(b, m)\right]^{2}}{\sum_{m=1}^{M} \sum_{b=1}^{K}\left[L_{s}(b, m)\right]^{2}}
其中K为临界频带数,L_s(b, m)和L_d(b, m)分别为原始语音和干扰语音或增强语音对应的第m帧第b个临界频带的Bark谱。BSD在浊音区域的失真代表整体失真的情况下工作良好,因为它只处理浊音区域;因此,必须检测语音区域。
- import pysepm
-
- pysepm.bsd(clean_speech, enhanced_speech, fs)
MBSD度量将噪声掩蔽阈值的概念纳入到传统的BSD度量中,任何低于噪声掩蔽阈值的失真都不包括在BSD度量中。MBSD度量的概念框图如下图所示。传统的BSD和MBSD有两个不同之处。首先,MBSD使用噪声掩蔽阈值来确定声音失真,而BSD使用经验确定的功率阈值。其次,BSD和MBSD的失真计算是不同的。BSD将失真定义为估计响度的平均平方欧氏距离,而MBSD将失真定义为估计响度的平均差值。
通过临界频带分析、传播函数应用和绝对阈值的考虑,对噪声掩蔽阈值进行了估计。该噪声掩蔽阈值估计考虑了音调掩蔽噪声和噪声掩蔽音调。将噪声掩蔽阈值的响度与原语音和编码语音的响度差进行比较,以确定失真是否可感知。当响度差低于噪声掩蔽阈值时,该响度差是不可见的。
因此,它不包括在MBSD的计算中。因此,MBSD计算为:
M B S D=\frac{1}{N} \sum_{j=1}^{M}\left[\sum_{i=1}^{K} Z(i)\left|L_{s}(i, m)-L_{d}(i, m)\right|^{n}\right]
其中,L_s(i, m)和L_d(i, m)分别表示第m帧纯净语音和干扰/增强语音的Bark频谱。K是临界频带的总数,M是帧的总数。Z(i)是可感知失真的指示器。当失真可感知时,Z(i)为1,否则Z(i)为0。这是通过比较响度和噪声掩蔽阈值得到的。
引言:我先做个简要介绍,再讲使用。使用之前建议还是详细了解一下,不要用错了,导致论文被拒,或者做了伪研究,以下内容是我挑重点摘自ITU-T P862建议书,比较权威,重要的地方我会加粗。想要进一步了解的自行去下载原文。
语音质量感知评估 (Perceptual Evaluation of Speech Quality, PESQ)是由国际电信联盟(International Telecommunication Union,ITU) 2001年提供的ITU-T P862建议书:语音质量的感知评估(PESQ):窄带电话网络和语音编解码器的端到端语音质量评估的客观方法,并提供了ANSI-C语言实现代码。真实系统可能包括滤波和可变延迟,以及由于信道误差和低比特率编解码器引起的失真。国际电联电信政策861中描述的PSQM方法仅被推荐用于评估语音编解码器,不能适当考虑滤波、可变延迟和短时局部失真。PESQ通过传递函数均衡、时间校准和一种新的时间平均失真算法来解决这些影响。PESQ的验证包括许多实验,这些实验专门测试了它在滤波、可变延迟、编码失真和信道误差等因素组合下的性能。
建议将PESQ用于3.1kHz(窄带, 8000Hz采样率)手机电话和窄带语音编解码器的语音质量评估。PESQ是属于客观评价,和主观分数之间的相关性约为0.935,但PESQ算法不能用来代替主观测试。
PESQ算法没有提供传输质量的综合评估。它只测量单向语音失真和噪声对语音质量的影响。响度损失、延迟、侧音、回声和其他与双向互动相关的损伤(如中央削波器)的影响不会反映在PESQ分数中。因此,有可能有很高的PESQ分数,但整体连接质量很差。
PESQ的感知模型用于计算原始信号X(t)与退化信号Y(t)之间的距离(PESQ分数),退化信号Y(t)是X(t)通过通信系统的结果。PESQ的输出是对受试者在主观听力测试中给予Y(t)的感知质量的预测。取值在-0.5到4.5的范围内,得分越高表示语音质量越好,尽管在大多数情况下输出范围在1.0到4.5之间。
ITU提供了C语言代码,下载请点击这里,但是在使用之前我们需要先编译C脚本,生成可执行文件exe
编译方式为:在命令行进入下载好的文件
经过编译,会在当前文件夹生成一个pesq.exe的可执行文件
使用方式为:
python代码实现
python实现的PESQ有两个库分别是 pesq 和 pypesq:
- import pesq
- import pypesq
- import librosa
-
- fs = 16000
- clean = librosa.load("./p234_001_clean.wav", sr=fs)[0]
- enhance = librosa.load("./p234_001_enhance.wav", sr=fs)[0]
-
- print(pesq.pesq(fs, clean, enhance, 'wb')) # 1.571152925491333
- print(pypesq.pesq(clean, enhance, fs=fs)) # 2.643505334854126
我发现不同库算的值相差太大,另外我也跑了一下官方C语言版本的PESQ,
- pesq +16000 ./p234_001_clean.wav ./p234_001_noisy.wav
- ...
- Prediction : PESQ_MOS = 2.826
惊奇的发现没有一个库对的上官方的,但是pypesq接近,所以写论文需要用PESQ的小伙伴留个心眼啊。
该python库返回的是MOS-LQO,属于pesq的映射,现在用的更多的也是MOS-LQO。如果你硬是想要PESQ得分,你可以自行逆变换回去,公式见下一节
MOS-LQO (Mean Opinion Score – Listening Quality Objective),使用客观测量技术评估主观听力质量)与之相对的还有MOS-LQS (Mean Opinion Score – Listening Quality Subjective) ,使用样本的主观评分直接衡量听力质量,就是主观评价了。
功能:将P.862原始结果分数转换为MOS-LQO的映射,P862.1:用于将P.862原始结果分数转换为MOS-LQO的映射函数.pdf
ITU-T P.862建议书 提供的原始分数在-0.5到4.5之间。希望从PESQ (P.862)得分中转换为MOS-LQO (P.862.1)分数,从而可以与MOS进行线性比较。该建议书介绍了从原始P.862得分到MOS-LQO (P.800.1)的映射函数及其性能。映射函数已在代表不同应用程序和语言的大量主观数据上进行了优化,所呈现的性能优于原始的PESQ(P862),取值在[1, 4.5]之间,连续的。公式为:
公式1:y=0.999+\frac{4.999-0.999}{1+e^{-1.4945x+4.6607}}
python实现
- def pesq2mos(pesq):
- """ 将PESQ值[-0.5, 4.5]映射到MOS-LQO得分[1, 4.5]上,映射函数来源于:P.862.1 """
- return 0.999 + (4.999 - 0.999) / (1 + np.exp(-1.4945 * pesq + 4.6607))
MATLAB官方实现请参见:
公式2给出了从MOS-LQO分数到PESQ分数的转换的反映射函数
公式2:x=\frac{4.6607-\ln \frac{4.999-y}{y-0.999}}{1.4945}
python实现
- def mos2pesq(mos):
- """ 将MOS-LQO得分[1, 4.5]映射到PESQ值[-0.5, 4.5]上,映射函数来源于:P.862.1"""
- inlog = (4.999 - mos) / (mos - 0.999)
- return (4.6607 - np.log(inlog)) / 1.4945
需要注意的是,所提供的函数有一些实际限制:
2007年11.13国际电联公布了PESQ的宽带版本(ITU-T P862.2,PESQ-WB),P.862建议书的宽带扩展,用于评估宽带电话网络和语音编解码器,主要用于宽带音频系统 (50-7000 Hz),16000Hz采样率,尽管它也可以应用于带宽较窄的系统。例如听众使用宽带耳机的语音编解码器。相比之下,ITU-T P.862建议书假设使用标准的IRS型窄带电话手机,在300 Hz以下和3100 Hz以上会强烈衰减。
使用范围
基本的P.862模型提供的原始分数在–0.5到4.5之间。 [ITU-T P.862]的PESQ-WB包括一个映射函数,输出的也是映射值,该函数允许与主观评价的MOS得分进行线性比较,这些主观实验包括音频带宽为50-7000 Hz的宽带语音条件。 这意味着由于实验环境的不同,无法直接比较PESQ-WB产生的分数和基线[ITU-T P.862]或[ITU-T P.862.1]产生的分数。 PESQ-WB中使用的输出映射函数定义如下:
y=0.999+\frac{4.999-0.999}{1+e^{-1.3669x+3.8224}}
其中x是原模型输出。
[ITU-T P.862]的附件A中给出了了PESQ-WB的宽带扩展的ANSI-C参考实现。
POLQA度量方法授权给了epticom公司,只有该公司授权的机构才能使用,我总结在这就是让大家了解一下,反正我们都用不了,哈哈
ITU P.863建议书提供了一种客观评价方法:感知客观语音质量评估 (Perceptual objective listening quality prediction, P.OLQA), ITU-T P.863建议书支持两种操作模式,一种用于窄带 (NB, 300Hz-3.4kHz),一种用于全带 (FB, 20Hz-20kHz)。
可以应用到全频带语音编解码器(例如,OPUS,增强语音服务(EVS))。比较参考信号X(t)和退化信号Y(t),其中Y(t)是通过通信系统传递X(t)的结果,人类听觉系统中音频信号的心理物理表征,
ITU-T P.863算法消除了参考信号中的低水平噪声,同时对退化输出信号中的噪声也进行了部分抑制。
一个好的客观质量测量应该与多个不同的主观实验有很高的相关性。在实践中,使用ITU-T P.863算法,回归映射通常几乎是线性的,在日常实践中,不需要对客观分数进行特殊映射,因为ITU-T P.863分数已经映射到MOS尺度,反映了大量单独数据集的平均值。
POLQA结果主要是模型平均意见得分(MOS),涵盖从1(差)到5(优秀)的范围。在全频带模式下得分为MOS-LQO 4.80,在窄带模式下得分为MOS-LQO 4.5。这反映了一个事实,即不是所有的主观测试参与者都会给最高的评级,即使是不降级的参考。
【文献】
- 2015_ViSQOL: an objective speech quality model
- 2017_Objective assessment of perceptual audio quality using ViSQOLAudio
- 2020_Visqol v3: An open source production ready objective speech and audio metric
【代码】https://github.com/google/visqol (不要去下载 Releases,直接clone,Releases里面是打包好的老版本,使用的过程中会出现一些问题,clone能下到最新的版本)
【关键字】有参考,主要用于评价VoIP语音传输质量
ViSQOL(Virtual Speech Quality Objective Listener) 使用参考和测试语音信号之间的频谱时间相似性度量 建模人类语音质量感知。该度量被特别设计为与VoIP传输相关的质量问题的健壮性。论文描述了该算法,并与ITU-T标准度量PESQ和POLQA对VoIP常见问题的质量预测进行了比较,这些问题包括
结果表明,ViSQOL和POLQA显著优于PESQ,其中ViSQOL与POLQA具有较好的竞争优势。实验对各种质量缺陷的性能进行了基准测试,包括VoIP降级、各种背景噪声类型、语音增强方法和信噪比水平。结果和随后的分析表明,在某些VoIP条件下,ViSQOL和POLQA都存在一些性能缺陷和感知质量预测不足。两者都比PESQ或更微不足道的距离度量具有更广泛的应用和对条件的鲁棒性。所以ViSQOL在预测VoIP语音质量方面也只是提供了一个有用的替代方案。
【论文】WARP-Q: Quality Prediction For Generative Neural Speech Codecs
【代码】https://github.com/wjassim/WARP-Q
【关键词】有参考,主要用于评估编码语音质量
语音编码已被证明可以使用波形匹配或参数重建来实现良好的语音质量。对于非常低的比特率流,最近开发的生成语音模型可以从标准参数编码器的比特流中以低于 3 kb/s 的速度重建高质量的宽带语音。生成式编解码器基于来自 DNN 和参数输入的合成语音生成高质量语音。但是,现有的客观语音质量模型(例如 ViSQOL、POLQA)不能用于从生成模型准确评估编码语音的质量,因为它们基于主观听力测试结果中不明显的信号差异进行惩罚。
我们提出了 WARP-Q 度量,WARP-Q(生成神经语音编解码器的质量预测)是感知语音质量的客观、完整的参考指标。它使用子序列动态时间扭曲 (SDTW) 算法作为参考(原始)和测试(降级)语音信号之间的相似性来生成原始质量分数。它旨在预测由低比特率语音编码器处理的语音信号的质量分数。
图 1:WARP-Q 度量的框图
WARP-Q 度量的算法由四个处理阶段组成:
图2:基于sdtw的累计成本和两个信号之间的最优路径。
(a)以6kb /s的速度从一个WaveNet编码器获得的参考信号及其相应的编码版本的图(从VAD阶段获得),
(b)两个信号的归一化MFCC矩阵,
(c)基于SDTW的累计对齐代价矩阵D(X,Y)及其在参考信号的MFCC矩阵Y与退化信号的MFCC矩阵提取的patch X之间的最优路径P^*图。并给出了最优指标(a^*和b^*)。X对应于小波网信号(用绿色突出显示)的一个短段(2秒长)。
使用波形匹配、基于参数和生成神经声码器的编解码器以及信道和环境噪声的评估表明,与传统指标相比,WARP-Q 对新型编解码器具有更好的相关性和编解码器质量排名,以及捕获其他类型退化的多功能性,例如附加噪声和传输通道退化。
结果表明,虽然 WARP-Q 是一个建立在完善的语音信号处理特征和算法上的简单模型,但它解决了可应用于生成神经编解码器的语音质量模型的未满足需求。
综合客观语音质量(Composite Objective Speech Quality,composite)度量是将现有的客观度量结合起来,形成一个新的度量。理想情况下,我们希望结合出与主观评价高度相关的客观评价度量方法,同时捕捉增强信号中出现的失真的不同特征。除了尝试不同的组合并评估产生的相关性之外,没有直接的方法可以选择用于复合度量的最佳客观度量子集。在不同的噪声失真条件和处理下,计算每个客观测量值与主观得分的相关性。然后采用线性回归分析或非线性技术将客观得分映射为主观得分。图5显示了复合度量的基本概念。
最近,Hu和Loizou提出了一种这样的复合度量来评价语音增强算法,即在客观语音评价指标上使用多元线性回归分析和多元自适应回归样条(multivariate adaptive regression splines, MARS)。该方法从三个不同的角度对增强语音的质量进行评估。他们是
C_{sig}值越高,C_{bak}值越高,C_{ovl}值越高,信号失真度越低,背景干扰越低,语音质量越好。这些值是通过将以下现有的客观测量值线性组合得到的:
C_{s i g}=3.093-1.029 \mathrm{LLR}+0.603 \mathrm{P} \mathrm{ESQ}-0.009 \mathrm{~W} \mathrm{SS}
C_{b a k}=1.634+0.478 \mathrm{P} \mathrm{ESQ}-0.007 \mathrm{~W} \mathrm{SS}+0.063 \mathrm{segSN} \mathrm{R}
C_{ovl}=1.594+0.805 \text {PESQ }-0.512 \mathrm{LLR}-0.007 \mathrm{~WSS}
其中LLR、P ESQ、W SS、segSNR分别表示对数似然比、语音质量感知评价、加权斜率谱距离和分段信噪比。最终的目标评分值在1到5之间,像MOS。该测量得到的MOS值是基于ITU-T P.835标准。
- import pysepm
-
- pysepm.composite(clean_speech, enhanced_speech, fs)
- # (1.0, 1.5970461451303148, 1.0)
由于深度学习的火热,也有部分人利用深度网络评估语音质量。这类方法都比较简单,因为使用的深度网络可以自动进行特征提取,因此这类方法直接将梅尔频谱系数或者MFCC直接送入模型即可。
【论文】
- 2019_Non-intrusive speech quality assessment for super-wideband speech communication networks(older NISQA (v0.42))
- 2020_Deep Learning Based Assessment of Synthetic Speech Naturalness(NISQA-TTS)
- 2020_Full-reference speech quality estimation with attentional Siamese neural networks(double-ended NISQA model)
- 2021_NISQA: A Deep CNN-Self-Attention Model for Multidimensional Speech Quality Prediction with Crowdsourced Datasets(NISQA model or the NISQA Corpus)
【代码】https://github.com/gabrielmittag/NISQA
【关键字】无参考、评估超宽带语音质量
近年来,通过将可用音频带宽从窄带扩展到宽带,再到超宽带,语音通信网络的质量得到了显著提高。这种带宽扩展标志着我们从普通的老式电话服务中所知道的典型的沉闷声音的结束。提高语音质量的另一个原因是全数字分组传输。但是,到目前为止,没有一个语音质量预测模型能够在没有清晰参考信号的情况下估计超宽带质量。
NISQA是一种非侵入式(non-intrusive,也可以理解为无参考)语音质量评估模型。
新版NISQA模型结构
- 【论文】2019_MOSNet: Deep Learning based Objective Assessment for Voice Conversion
- 【代码】https://github.com/aliutkus/speechmetrics(提供了多种度量方法,如:MOSNet、SRMR、BSSEval、PESQ、STOI、SISDR)
- 【代码】https://github.com/lochenchou/MOSNet
- 【关键字】有参考、评估音色转换后的语音质量
现有的语音音色转换(voice conversion,VC)客观评价指标并不总是与人的感知相关。因此,用这种准则训练VC模型可能不能有效提高转换语音的自然度和相似度。该论文提出了基于深度学习的评估模型来预测转换语音的人类评分。我们采用卷积神经网络和循环神经网络模型来建立一个平均意见评分(MOS)预测器,称为MOSNet。在2018年语音转换挑战(Voice Conversion Challenge, VCC)的大规模听力测试结果上测试了所提出的模型。实验结果表明,所提出的MOSNet的预测得分在系统级与人类的MOS评分高度相关,而在话语级与人类的MOS评分相当相关。同时,我们对MOSNet进行了改进,对相似度评分进行了预测,初步结果表明,预测的评分与人类评分也有相当的相关性。这些结果证实了所提出的模型可以作为计算评估器来测量VC系统的MOS,以减少昂贵的人力评价的需要。
在这项工作中,我们构建了一个度量,通过拟合一个深度神经网络到一个新的大数据集的众包人类判断。受试者被提示回答一个直接、客观的问题:两段录音是否相同?这两端语音是通过各种干扰算法生成的,包括噪声、混响和压缩伪影;探测扰动空间的目的是有效识别主体的刚好可察觉差异 (JND) 水平。 我们表明,由此产生的学习度量与人类判断进行了很好的校准,优于基线方法。 由于它是一个深度网络,度量是可微的,使其适合作为其他任务的损失函数。 因此,通过主观成对比较来衡量,简单地用我们的度量替换现有损失(例如,深度特征损失)可以显着改善去噪网络。
一种基于对比学习的多维深度感知音频相似度度量 (CDPAM)是一种建立在 DPAM 基础上并对其进行改进的指标。使用三个关键思想:(1) 对比学习、(2) 多维表示学习、(3) 三元组学习。对比学习是一种自我监督学习的形式,它用合成(因此是无限的)数据来增强一组有限的人类注释:对应该被视为不同(或不相同)的数据的扰动。我们使用多维表示学习来分别建模内容相似性(例如说话者或话语之间)和声学相似性(例如录音环境之间)。对比学习和多维表示学习的结合使 CDPAM 能够更好地概括具有有限人类注释的内容差异(例如看不见的说话者)。最后,为了进一步提高对大扰动(远远超出 JND)的鲁棒性,我们收集了基于三元组比较的判断数据集,询问受试者:A 还是 B 更接近参考 C?
将这个指标添加到现有的语音合成和增强方法中会产生显着的改进,这是通过客观和主观测试来衡量的。
训练架构:
(a)、我们首先使用对比学习训练一个音频编码器
(b)、在JND数据上训练loss-net
(c)、最后,我们在新收集的三元组比较数据集上微调损失网络
据我们所知,对于一个语音来说,之前的所有作品都只使用不同法官的多个分数的平均值作为训练目标,而丢弃了每个法官的分数,没有很好地利用宝贵的 MOS 训练数据。在本文中,我们提出了 MBNet,一个具有平均子网和偏置子网的 MOS 预测器,以更好地利用 MOS 数据集中的每个判断分数,其中平均子网用于预测每个话语的平均分数,类似于以前的工作,和偏差子网来预测偏差分数(平均分数和每个评委得分之间的差异)并捕捉每个评委的个人偏好。实验表明,与仅利用平均得分进行训练的 MOSNet 基线相比,MBNet 在 VCC 2018 数据集上将系统级 spearmans 等级相关系数 (SRCC) 提高了 2.9%,在 VCC 2016 数据集上提高了 6.7%。
语音可懂度的评估大致可以分为基于清晰度指数、基于语言传输指数和基于相干性指数三类,我们今天先介绍第一类。
- from pystoi import stoi
-
- stoi_score = stoi(label, logits, fs_sig=16000)
Coherence and speech intelligibility index (CSII)
- import pysepm
-
- pysepm.csii(clean_speech, enhanced_speech, fs)
- # (0.527623436040412, 0.2437425452887004, 0.010118033728508934)
Normalized-covariance measure (NCM)
- import pysepm
-
- pysepm.ncm(clean_speech, enhanced_speech, fs)
- import pysepm
-
- pysepm.srmr(enhanced_speech, fs)
语音混响调制能量比(SRMR)
SDR
源信号失真比(Source to Distortion Ratio, SDR)表示信号整体的失真情况
SIR
源信号干扰比(Source to Interferences Ratio, SIR)表示抑制干扰成分的能力
SAR
人造误差成分(Signal to Artifacts Ratio, SAR)表示了经算法处理生成的人造噪音的情况
SER=10\log_{10}\frac{E\{s^2(n)\}}{E\{d^2(n)\}}
其中
- def SER(near_speech, far_echo):
- """signal to echo ratio, 信号回声比
- :param near_speech: 近端语音
- :param far_echo: 远端回声
- """
- return 10*np.log10(np.mean(near_speech**2)/np.mean(far_echo**2))
回波损失增强(ERLE)通常用于评估系统在 没有近端信号 的 单通话情况下 的回声抑制。ERLE的公式:
ERLE(dB)=10\log_{10}\frac{E\{y^2(n)\}}{E\{\hat{s}^2(n)\}}
其中E是统计 期望操作,y(n)是麦克风信号,\hat{s}(n)是估计的近端语音信号。
- def compute_ERLE(mic_wav, predict_near_end_wav):
- """
- :param mic_wav: 麦克风信号(y) = 近端语音(s) + 远端语音回声(s) + 噪声(v)
- :param predict_near_end_wav: 估计的近端语音信号 \hat{s}
- 麦克风信号
- """
- mic_near = np.mean(mic_wav**2)
- predict_near_end_wav = np.mean(predict_near_end_wav**2)
- ERLE = 10 * np.log10(mic_near/predict_near_end_wav)
- return ERLE
ERLE的得分越高,代表回声消除系统越好。
为了评估系统在双讲情况下的性能,通常采用PESQ (语音质量感知评价)或STOI (短时语音可懂度),他是通过将估计的近端语音和仅在双讲通话期间真实的近端语音进行比较得到的。PESQ评分范围为-0.5 ~ 4.5,分数越高质量越好。STOI评分范围为0~1,分数越高越好。
在语音合成领域,研究的比较少,论文中常常通过展示频谱细节,计算MCD(mel cepstral distortion)等方法作为客观评价。
有利用P.563做合成语音质量评估的尝试:
【论文】2010_Synthesized speech quality evaluation using ITU-T P. 563
识别错误率
在本文中,简要回顾了可用于评估嘈杂语音增强算法的各种主观和客观质量度量。 客观测量主要用于算法开发阶段,用于调整各种参数。 主观测量通常可用于无法获取参考语音信号的实时应用中。 一般来说,客观测量没有考虑原始语音嘈杂的情况。 语音增强算法可能会产生比输入的嘈杂语音在感知上增强的语音。 客观措施应考虑这种情况。 这篇综述主要集中在语音增强算法的质量方面。 类似地,文献中有几种可懂度特定的主观和客观度量。 我们未来的研究将集中在这方面。
语音质量评估对给予了语音一个定量指标,对语音质量的评价(Audio Quality Assessment)其实是一个多年以来得到了深入研究的问题。大致可以分为需要标准信号的无参考(Non-intrusive)和有参考(instrusive)方法。无参考语音质量评估在实时通讯领域出现了许多传统和深度学习方法,
大多数语音客观评价标准都关注在语音信号的失真程度,较少从人类的听觉去分析,不同评价标准和真实情况的相关系数如下表所示。
使用皮尔逊相关系数(Pearson’s correlation coefficient)和标准差的误差 来评价主观评价得分与客观评价得分之间的相关性:
皮尔逊相关系数\rho公式表达为(\rho值越接近于1,代表客观评价与主观评价的相关性越高,客观度量方法的性能越好):
https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.pearsonr.html
\rho=\frac{\sum_{i}\left(o_{i}-\bar{o}\right)\left(s_{i}-\bar{s}\right)}{\sqrt{\sum_{i}\left(o_{i}-\bar{o}\right)^{2}} \sqrt{\sum_{i}\left(s_{i}-\bar{s}\right)^{2}}}
其中
标准差的误差\hat{\sigma}_{e}公式表达为(\hat{\sigma}_{e}越小,代表算法的性能越好):
\hat{\sigma}_{e}=\hat{\sigma}_{s} \sqrt{1-\rho^{2}}
其中:
\hat{\sigma}_{s}:主观评价得分的标准差
\rho:皮尔逊相关系数
斯皮尔曼等级相关(Spearman rank correlation)
https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.spearmanr.html
【ITU】P.800.1 : Mean opinion score (MOS) terminology
【论文】语音质量客观评价方法研究进展。陈国, 胡修林, 张蕴玉, 朱耀庭(华中科技大学电子与信息工程系)
【论文】An Overview of Subjective and Objective Quality Measures for Noisy Speech Enhancement Algorithms
【代码】speech-mos (基于深度学习,使用音频频谱图和 ConvNet 进行非侵入式语音质量评估)
【代码】利用MOS预测的自监督表示
Voice quality metrics:包含一组用于在不同语音质量估计指标(如 PESQ MOS、MOS LQO、R-factor)之间进行转换的函数。
后续工作(以下均有论文+代码):
iMetricGAN:使用基于生成对抗网络的度量学习增强噪声语音的清晰度
MetricGAN:用于语音增强的基于生成对抗网络的黑盒度量分数优化