Tensorflow输入管道中的在线过采样

时间:2016-07-20 14:29:11

标签: tensorflow pipeline

我有一个类似于Convolutional Neural Network教程中的输入管道。我的数据集是不平衡的,我想使用少数民族过采样来试图解决这个问题。理想情况下,我想这样做"在线",即我不想在磁盘上复制数据样本。

基本上,我想要做的是根据标签复制单个示例(有一些概率)。我一直在读Tensorflow中的控制流。似乎tf.cond(pred, fn1, fn2)是要走的路。我只是在努力找到正确的参数化,因为fn1fn2需要输出张量列表,其中列表具有相同的大小。

这大致是我到目前为止:

image = image_preprocessing(image_buffer, bbox, False, thread_id)            
pred = tf.reshape(tf.equal(label, tf.convert_to_tensor([2])), [])
r_image = tf.cond(pred, lambda: [tf.identity(image), tf.identity(image)], lambda: [tf.identity(image),])
r_label = tf.cond(pred, lambda: [tf.identity(label), tf.identity(label)], lambda: [tf.identity(label),])

然而,正如我之前提到的那样,这会引发错误:

ValueError: fn1 and fn2 must return the same number of results.

有什么想法吗?

P.S。:这是我的第一个Stack Overflow问题。对我的问题的任何反馈表示赞赏。

1 个答案:

答案 0 :(得分:1)

在做了一些研究之后,我找到了一个解决方案,我想做什么。我忘记提到的是,我的问题中提到的代码后跟批处理方法,例如batch()batch_join()

这些函数采用的参数允许您对不同批量大小的张量进行分组,而不仅仅是单个示例的张量。参数为enqueue_many,应设置为True

以下代码对我有用:

for thread_id in range(num_preprocess_threads):

    # Parse a serialized Example proto to extract the image and metadata.
    image_buffer, label_index = parse_example_proto(
            example_serialized)

    image = image_preprocessing(image_buffer, bbox, False, thread_id)

    # Convert 3D tensor of shape [height, width, channels] to 
    # a 4D tensor of shape [batch_size, height, width, channels]
    image = tf.expand_dims(image, 0)

    # Define the boolean predicate to be true when the class label is 1
    pred = tf.equal(label_index, tf.convert_to_tensor([1]))
    pred = tf.reshape(pred, [])

    oversample_factor = 2
    r_image = tf.cond(pred, lambda: tf.concat(0, [image]*oversample_factor), lambda: image)
    r_label = tf.cond(pred, lambda: tf.concat(0, [label_index]*oversample_factor), lambda: label_index)
    images_and_labels.append([r_image, r_label])

images, label_batch = tf.train.shuffle_batch_join(
    images_and_labels,
    batch_size=batch_size,
    capacity=2 * num_preprocess_threads * batch_size,
    min_after_dequeue=1 * num_preprocess_threads * batch_size,
    enqueue_many=True)