使用Tensorflow ops生成可变长度数据

使用Tensorflow ops生成可变长度数据,tensorflow,Tensorflow,我正在尝试学习音频文件的分类器。我读取WAV文件并将其转换为一系列光谱图图像,以便在自定义Python函数中进行训练。使用tf.py_func调用该函数,并返回具有相同形状的图像数组。换言之,图像形状定义良好,但图像数量是动态的。(例如,短音频片段3个频谱图,长音频片段15个频谱图) 是否有方法将结果列表解包,以便在tf.train.batch\u join()中进一步处理/排队?未定义的序列长度似乎是许多TF操作的问题。不知怎么能推断出长度吗 ... // Read the audio fil

我正在尝试学习音频文件的分类器。我读取WAV文件并将其转换为一系列光谱图图像,以便在自定义Python函数中进行训练。使用
tf.py_func
调用该函数,并返回具有相同形状的图像数组。换言之,图像形状定义良好,但图像数量是动态的。(例如,短音频片段3个频谱图,长音频片段15个频谱图)

是否有方法将结果列表解包,以便在
tf.train.batch\u join()中进一步处理/排队?未定义的序列长度似乎是许多TF操作的问题。不知怎么能推断出长度吗

...
// Read the audio file name and label from a CSV file
audio_file, label = tf.decode_csv(csv_content)

def read_audio(audio_file):

    signal = read_wav(audio_file)
    images = [generate_image(segment) for segment in split_audio(signal)]

    // This output is of varying length depending on the length of audio file.
    return images

// Convert audio file to a variable length sequence of images
// Shape: <unknown>, which is to be expected from tf.py_func
image_sequence = tf.py_func(wav_to_spectrogram, [audio_file], [tf.float32])[0]

// Auxilliary to set a shape for the images defined in tf.py_func
def process_image(in_image):
    image = tf.image.convert_image_dtype(in_image, dtype=tf.float32)
    image.set_shape([600, 39, 1])

    return (image, label)


// Shape: (?, 600, 39, 1)
images_labels = tf.map_fn(process_image, image_sequence, dtype=(tf.float32, tf.int32))


// This will not work. 'images_and_labels' needs to be a list
images, label_index_batch = tf.train.batch_join(
    images_and_labels,
    batch_size=batch_size,
    capacity=2 * num_preprocess_threads * batch_size,
    shapes=[data_shape, []],
)
。。。
//从CSV文件中读取音频文件名和标签
音频文件,标签=tf.解码csv(csv内容)
def读取音频(音频文件):
信号=读取波形(音频文件)
图像=[为分割音频(信号)中的片段生成图像(片段)]
//此输出的长度随音频文件的长度而变化。
返回图像
//将音频文件转换为可变长度的图像序列
//形状:,这是tf.py_func的预期形状
image_sequence=tf.py_func(wav_to_频谱图,[音频文件],[tf.float32])[0]
//辅助设置tf.py_func中定义的图像的形状
def过程图像(图像中):
image=tf.image.convert\u image\u dtype(在\u image中,dtype=tf.float32)
图像。设置_形状([600,39,1])
返回(图像、标签)
//形状:(?,600,39,1)
images\u labels=tf.map\u fn(process\u image,image\u sequence,dtype=(tf.float32,tf.int32))
//这行不通。”图像和标签需要是一个列表
图像,标签\u索引\u批次=tf.train.batch\u连接(
图像和标签,
批次大小=批次大小,
容量=2*num\u预处理线程数*batch\u大小,
形状=[data_shape,[]],
)

您可以使用可变大小的张量作为输入,并将许多张量作为可变大小的输入批处理

下面是一个
py_func
生成可变大小批次的示例,以及
enqueue\u many
将其转换为恒定大小批次的示例。

将tensorflow导入为tf
tf.reset_default_graph()
#从超时开始,以防止试验时挂起
config=tf.ConfigProto()
config.operation\u timeout\u in\u ms=2000
sess=tf.InteractiveSession(config=config)
#用1,2,1,2初始化第一个队列
queue1=tf.FIFOQueue(容量=4,数据类型=[tf.int32])
queue1_input=tf.placeholder(tf.int32)
queue1\u enqueue=queue1.enqueue(queue1\u输入)
run(queue1_enqueue,feed_dict={queue1_input:1})
run(queue1_enqueue,feed_dict={queue1_input:2})
run(queue1_enqueue,feed_dict={queue1_input:1})
run(queue1_enqueue,feed_dict={queue1_input:2})
sess.run(queue1.close())
#call_func将生成可变大小的张量
定义范围函数(x):
返回np.array(范围(x),dtype=np.int32)
[call_func]=tf.py_func(range_func,[queue1.dequeue()],[tf.int32])
queue2\u dequeue=tf.train.batch([call\u func],batch\u size=3,shapes=[[]],enqueue\u many=True)
coord=tf.train.Coordinator()
线程=tf.train.start\u queue\u runner(coord=coord)
尝试:
尽管如此:
打印sess.run(队列2\u出列)
除了tf.errors.OutOfRangeError:
通过
最后:
协调请求停止()
坐标连接(线程)
sess.close()
你应该看到

[0 0 1]
[0 0 1]

您可以使用可变大小的张量作为输入,并将此张量作为可变大小的输入批处理

下面是一个
py_func
生成可变大小批次的示例,以及
enqueue\u many
将其转换为恒定大小批次的示例。

将tensorflow导入为tf
tf.reset_default_graph()
#从超时开始,以防止试验时挂起
config=tf.ConfigProto()
config.operation\u timeout\u in\u ms=2000
sess=tf.InteractiveSession(config=config)
#用1,2,1,2初始化第一个队列
queue1=tf.FIFOQueue(容量=4,数据类型=[tf.int32])
queue1_input=tf.placeholder(tf.int32)
queue1\u enqueue=queue1.enqueue(queue1\u输入)
run(queue1_enqueue,feed_dict={queue1_input:1})
run(queue1_enqueue,feed_dict={queue1_input:2})
run(queue1_enqueue,feed_dict={queue1_input:1})
run(queue1_enqueue,feed_dict={queue1_input:2})
sess.run(queue1.close())
#call_func将生成可变大小的张量
定义范围函数(x):
返回np.array(范围(x),dtype=np.int32)
[调用\u func]=tf.py func(range_func,[queue1.devqueue()],[tf.int32])
queue2\u dequeue=tf.train.batch([call\u func],batch\u size=3,shapes=[[]],enqueue\u many=True)
coord=tf.train.Coordinator()
线程=tf.train.start\u queue\u runner(coord=coord)
尝试:
尽管如此:
打印sess.run(队列2\u出列)
除了tf.errors.OutOfRangeError:
通过
最后:
协调请求停止()
坐标连接(线程)
sess.close()
你应该看到

[0 0 1]
[0 0 1]

还有一件事。我理解示例的作用,但我缺少“标签部分”。如何将每个标签合并/连接到序列?当输入到
tf.train.batch()
时,
py_func
的每个可变长度输出应与其标签配对。我该怎么做?还有比这更好的解决方案吗?还有一件事。我理解示例的作用,但我缺少“标签部分”。如何将每个标签合并/连接到序列?当输入到
tf.train.batch()
时,
py_func
的每个可变长度输出应与其标签配对。我该怎么做?还有比这更好的解决方案吗?