是否有可能从tensorflow mfcc和librosa mfcc得到完全相同的结果?

时间:2017-11-01 13:49:05

标签: audio tensorflow mfcc librosa

我试图让tensorflow mfcc给我与python lybrosa mfcc相同的结果 我试图匹配librosa使用的所有默认参数 在我的tensorflow代码中得到了不同的结果

这是我使用的张量流代码:

waveform = contrib_audio.decode_wav(
 audio_binary,
 desired_channels=1,
 desired_samples=sample_rate,
 name='decoded_sample_data')


sample_rate = 16000

transwav = tf.transpose(waveform[0])

stfts = tf.contrib.signal.stft(transwav,
  frame_length=2048,
  frame_step=512,
  fft_length=2048,
  window_fn=functools.partial(tf.contrib.signal.hann_window, 
  periodic=False), 
  pad_end=True)

spectrograms = tf.abs(stfts)
num_spectrogram_bins = stfts.shape[-1].value
lower_edge_hertz, upper_edge_hertz, num_mel_bins = 0.0,8000.0, 128
linear_to_mel_weight_matrix = 
tf.contrib.signal.linear_to_mel_weight_matrix(
num_mel_bins, num_spectrogram_bins, sample_rate, 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.log(mel_spectrograms + 1e-6)
mfccs = tf.contrib.signal.mfccs_from_log_mel_spectrograms(
    log_mel_spectrograms)[..., :20]

librosa中的等价物: libr_mfcc = librosa.feature.mfcc(wav,16000)

以下是结果图: tensorflow mfcc results

librosa mfcc results

4 个答案:

答案 0 :(得分:2)

我是tf.signal的作者。抱歉,我们没有很快看到此帖子,但是如果在将信号传递到tf.signal.stft之前居中填充信号,则可以得到librosa和tf.signal.stft匹配。有关更多详细信息,请参见this GitHub issue

答案 1 :(得分:1)

我花了整整1天的时间使它们匹配。即使是rryan的解决方案对我也不起作用(在librosa中,center = False),但我最终发现,TF和librosa STFT仅在librosa中的win_length == n_fft和TF中的frame_length == fft_length的情况下匹配。这就是rryan的colab example起作用的原因,但是您可以尝试如果设置frame_length!= fft_length,则幅值会非常不同(尽管在视觉上绘制后,图案看起来很相似)。典型示例-如果您选择一些win_length / frame_length,然后将n_fft / fft_length设置为比win_length / frame_length大的最小2的幂,那么结果将有所不同。因此,您需要坚持使用窗口大小给定的低效FFT ...我不知道为什么会这样,但是事实就是如此,希望它会对某人有所帮助。

答案 2 :(得分:0)

contrib_audio.decode_wav的输出应为DecodeWav,其中{audio,sample_rate}和audio形状为(sample_rate,1),那么获取波形的第一项并进行转置的目的是什么?

transwav = tf.transpose(waveform[0])

答案 3 :(得分:0)

没有直接的方法,因为librosa stft使用center = True,它不符合tf stft。 如果center = False,stft tf / librosa会给出足够的结果。参见Khmer rendered by Pillow

但是,尽管如此,尝试将librosa代码导入tf还是一个很大的麻烦。这是我开始放弃的。接近但不够远。

afterFetch