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

qlfbtfca  于 2022-12-19  发布在  其他
关注(0)|答案(5)|浏览(155)

我试图使tensorflow mfcc给予与python lybrosa mfcc相同的结果我尝试匹配我的tensorflow代码中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 =库文件.特征.mfcc(wav,16000)
以下是结果图表:

5cnsuln7

5cnsuln71#

我是tf.signal的作者。很抱歉没有早点看到这篇文章,但是如果你在将信号传递给tf.signal.stft之前将其居中填充,你可以让librosa和tf.signal.stft匹配。更多细节请参见GitHub本期。

fhity93d

fhity93d2#

我花了整整一天的时间试图让他们匹配。甚至rryan的解决方案对我也不起作用(在librosa中center=False),但我最终发现,TF和librosa的STFT只在librosa中win_length==n_fft和TF中frame_length==fft_length的情况下匹配。这就是为什么rryan的colab示例可以工作,但如果您设置frame_length!=fft_length,振幅非常不同(虽然在视觉上,绘制后,图案看起来很相似)典型的例子-如果你选择一些Win_Length/Frame_Length,然后你想将N_FFT/FFT_Length设置为大于Win_Length/Frame_Length的2的最小幂,那么结果就会不同。所以你需要坚持使用你的窗口大小所给出的低效FFT...我不知道为什么会这样,但就是这样,希望它能对某些人有所帮助。

9lowa7mx

9lowa7mx3#

contrib_audio.decode_wav的输出应为DecodeWav,具有{ audio,sample_rate },audio形状为(sample_rate,1),那么获取波形的第一项并进行转置的目的是什么?
transwav = tf.transpose(waveform[0])

hxzsmxv2

hxzsmxv24#

没有直接的方法,因为librosa stft使用了center=True,这与tf stft不一致。如果它是center=False,stft tf/librosa将给予足够的结果。参见colab sniff
但即使如此,试图将librosa代码导入tf也是一件很头疼的事,下面是我开始和放弃的事情,接近但还不够接近。

def pow2db_tf(X):
    amin=1e-10
    top_db=80.0
    ref_value = 1.0
    log10 = 2.302585092994046
    log_spec = (10.0/log10) * tf.log(tf.maximum(amin, X))
    log_spec -= (10.0/log10) * tf.log(tf.maximum(amin, ref_value))
    pow2db = tf.maximum(log_spec, tf.reduce_max(log_spec) - top_db)
    return pow2db

def librosa_feature_like_tf(x, sr=16000, n_fft=2048, n_mfcc=20):
    mel_basis = librosa.filters.mel(sr, n_fft).astype(np.float32)
    mel_basis = mel_basis.reshape(1, int(n_fft/2+1), -1)
    tf_stft = tf.contrib.signal.stft(x, frame_length=n_fft, frame_step=hop_length, fft_length=n_fft)
    print ("tf_stft", tf_stft.shape)
    tf_S = tf.matmul(tf.abs(tf_stft), mel_basis);
    print ("tf_S", tf_S.shape)
    tfdct = tf.spectral.dct(pow2db_tf(tf_S), norm='ortho'); print ("tfdct", tfdct.shape)
    print ("tfdct before cut", tfdct.shape)
    tfdct = tfdct[:,:,:n_mfcc];
    print ("tfdct afer cut", tfdct.shape)
    #tfdct = tf.transpose(tfdct,[0,2,1]);print ("tfdct afer traspose", tfdct.shape)
    return tfdct

x = tf.placeholder(tf.float32, shape=[None, 16000], name ='x')
tf_feature = librosa_feature_like_tf(x)
print("tf_feature", tf_feature.shape)
mfcc_rosa = librosa.feature.mfcc(wav, sr).T
print("mfcc_rosa", mfcc_rosa.shape)
wtzytmuj

wtzytmuj5#

对于任何人仍然在寻找这个:前段时间我也遇到过类似的问题:将librosa的 * mel滤波器组/mel谱图 * 匹配到tensorflow 实现。解决方案是对谱图使用不同的窗口方法,并将librosa的 * mel * 矩阵作为常量Tensor。请参见此处和此处。

相关问题