我使用tf.data.Dataset作为tensorflow中的管道来读取和转换音频。 我想添加音频重采样以减少过度拟合。我搜索了一种方法来重新采样python / tensorflow中的文件,我发现python只有像resampy这样的解决方案。它工作得很好,但它减慢了我的pipline 10次,因为我不得不使用tf.py_func来运行它。我的音频文件长1秒,速率为16000,下面是我的代码进行重新采样,然后填充或剪辑生成的数组:
def _resample(pcm, label):
if resample_range < 1e-8:
return pcm, label
import resampy
desired_samples=16000
def clip_o_pad(pcm):
margin = pcm.shape[0] - desired_samples + 2
if margin > 0:
out = pcm[margin // 2: (pcm.shape[0] - margin // 2)]
elif margin < 0:
out = np.pad(clip, -margin // 2, 'constant', constant_values=(0))
else:
out = pcm
return out[:desired_samples]
def _resample_py(pcm):
pcm = pcm.reshape(desired_samples)
new_rate = np.random.randint(desired_samples*(1-resample_range), desired_samples*(1+resample_range))
resampled = resampy.resample(pcm, desired_samples, new_rate)
out = clip_o_pad(resampled)
out = out.reshape(desired_samples,1)
return out
return tf.py_func(_resample_py, [pcm], pcm.dtype), label
你知道张量流中的任何库/函数,它允许我在纯张量流图中做同样的事情(即不使用py_func)
答案 0 :(得分:0)
经过一些谷歌搜索后,我注意到tf.contrib.ffmpeg.decode_audio可以进行重新采样。
然而,改变我的pipline以使用上述程序并没有提高我的管道速度。显然,减速是由重新采样而不是使用tf.py_func:/引起的。加载200个示例需要200毫秒而不重新采样,5200毫秒使用resamply和py_func,5700毫秒使用ffmepg和纯张量流代码。
如果有人发现它有用,上面的代码重写为tensorflow如下:
import tensorflow as tf
def _decode_n_resample(data, label):
min_rate = desired_samples * (1 - resample_range)
max_rate = desired_samples * (1 - resample_range)
if min_rate < max_rate:
samples_per_second = tf.random_uniform([], min_rate, max_rate, dtype=tf.int32)
else:
samples_per_second = desired_samples
pcm = tf.contrib.ffmpeg.decode_audio(data, file_format='wav', samples_per_second=samples_per_second,
channel_count=1)
number_of_samples = tf.shape(pcm)[0]
samples_to_pad = desired_samples - number_of_samples
padding = tf.cond(samples_to_pad > 0,
lambda : tf.to_int64([[tf.floor(samples_to_pad/2), tf.ceil(samples_to_pad/2)], [0, 0]]),
lambda : tf.to_int64([[0, 0], [0, 0]]))
padded_pcm = tf.pad(
pcm,
padding,
mode='CONSTANT')
sliced_pcm = tf.slice(padded_pcm, [0, 0], [desired_samples, -1])
return sliced_pcm, label