我试图从音频(.wav文件)中提取MFCC功能,我已经尝试了python_speech_features
和librosa
,但他们给出了完全不同的结果:
audio, sr = librosa.load(file, sr=None)
# librosa
hop_length = int(sr/100)
n_fft = int(sr/40)
features_librosa = librosa.feature.mfcc(audio, sr, n_mfcc=13, hop_length=hop_length, n_fft=n_fft)
# psf
features_psf = mfcc(audio, sr, numcep=13, winlen=0.025, winstep=0.01)
以下是图表:
利布罗萨:
python语音功能:
我是否为这两个方法传递了错误的参数?为什么这里有如此巨大的差异?
**更新:**我也尝试过tensorflow.signal实现,结果如下:
图本身与librosa中的图更接近,但比例更接近python_speech_features。(注意,这里我计算了80个mel bin,并取了前13个;如果我只使用13个bin进行计算,结果看起来也很不同)。代码如下:
stfts = tf.signal.stft(audio, frame_length=n_fft, frame_step=hop_length, fft_length=512)
spectrograms = tf.abs(stfts)
num_spectrogram_bins = stfts.shape[-1]
lower_edge_hertz, upper_edge_hertz, num_mel_bins = 80.0, 7600.0, 80
linear_to_mel_weight_matrix = tf.signal.linear_to_mel_weight_matrix(
num_mel_bins, num_spectrogram_bins, sr, lower_edge_hertz, upper_edge_hertz)
mel_spectrograms = tf.tensordot(spectrograms, linear_to_mel_weight_matrix, 1)
mel_spectrograms.set_shape(spectrograms.shape[:-1].concatenate(linear_to_mel_weight_matrix.shape[-1:]))
log_mel_spectrograms = tf.math.log(mel_spectrograms + 1e-6)
features_tf = tf.signal.mfccs_from_log_mel_spectrograms(log_mel_spectrograms)[..., :13]
features_tf = np.array(features_tf).T
我想我的问题是:哪个输出更接近MFCC的实际外观?
3条答案
按热度按时间bnl4lu3b1#
这里至少有两个因素在起作用,可以解释为什么你会得到不同的结果:
1.熔点刻度没有单一的定义。
Librosa
有两种实现方式:Slaney和HTK。其他软件包可能也将使用不同的定义,导致不同的结果。话虽如此,总体情况应该是相似的。这就引出了第二个问题...python_speech_features
默认将能量作为第一(索引零)系数(appendEnergy
默认为True
),这意味着当您请求例如13MFCC时,您实际上得到12 + 1。换句话说,您不是在比较13个
librosa
与13个python_speech_features
系数,而是在比较13个与12个系数。能量大小可能不同,因此由于色阶不同,产生的图像也会大不相同。现在,我将演示两个模块如何产生相似的结果:
正如你所看到的规模是不同的,但整体图片看起来真的很相似。注意,我必须确保传递给模块的一些参数是相同的。
ao218c7q2#
This answer是正确的(而且非常有用!),但并不完整,因为它没有解释两种方法之间的巨大差异。我的答案增加了一个重要的额外细节,但仍然没有实现精确匹配。
发生的事情很复杂,最好用下面一段冗长的代码来解释,它将
librosa
和python_speech_features
与另一个包torchaudio
进行了比较。log_mels
,它的默认值(False)模仿librosa的实现,但是如果设置为True,就会模仿python_speech_features。下面是一些示例代码:
老实说,这些实现都不能令人满意:
mo49yndu3#
关于与tf.signal的区别,对于任何仍在寻找这个的人:前段时间我也遇到过类似的问题:将librosa的 *mel滤波器组/mel谱图 * 匹配到tensorflow 实现。解决方案是对谱图使用不同的窗口方法,并将librosa的 mel 矩阵作为常量Tensor。请参见此处和此处。