TensorFlow:如何将相同的图像失真应用于多个图像

时间:2016-05-15 10:41:57

标签: tensorflow distortion random-seed

Tensorflow CNN example开始,我尝试修改模型以将多个图像作为输入(这样输入不仅有3个输入通道,而且通过堆叠图像可以是3的倍数)。 为了增加输入,我尝试使用random image operations,例如TensorFlow中提供的翻转,对比度和亮度。 我当前对所有输入图像应用相同随机失真的解决方案是对这些操作使用固定的种子值:

def distort_image(image):
  flipped_image = tf.image.random_flip_left_right(image, seed=42)
  contrast_image = tf.image.random_contrast(flipped_image, lower=0.2, upper=1.8, seed=43)
  brightness_image = tf.image.random_brightness(contrast_image, max_delta=0.2, seed=44)
  return brightness_image

在图形构建时,每个图像都会多次调用此方法,因此我认为对于每个图像,它将使用相同的随机数序列,因此,它将导致对我的图像输入序列具有相同的应用图像操作。

# ...

# distort images
distorted_prediction = distort_image(seq_record.prediction)
distorted_input = []
for i in xrange(INPUT_SEQ_LENGTH):
    distorted_input.append(distort_image(seq_record.input[i,:,:,:]))
stacked_distorted_input = tf.concat(2, distorted_input)

# Ensure that the random shuffling has good mixing properties.
min_queue_examples = int(num_examples_per_epoch *
                         MIN_FRACTION_EXAMPLES_IN_QUEUE)

# Generate a batch of sequences and prediction by building up a queue of examples.
return generate_sequence_batch(stacked_distorted_input, distorted_prediction, min_queue_examples, 
                               batch_size, shuffle=True)

理论上,这很好用。经过一些测试后,这似乎解决了我的问题。但过了一段时间,我发现我有一个竞争条件,因为我使用CNN示例代码的输入管道和多个线程(这是TensorFlow中的建议方法)在运行时提高性能并减少内存消耗):

def generate_sequence_batch(sequence_in, prediction, min_queue_examples,
                        batch_size):
    num_preprocess_threads = 8 # <-- !!!
    sequence_batch, prediction_batch = tf.train.shuffle_batch(
        [sequence_in, prediction],
        batch_size=batch_size,
        num_threads=num_preprocess_threads,
        capacity=min_queue_examples + 3 * batch_size,
        min_after_dequeue=min_queue_examples)
return sequence_batch, prediction_batch

因为多个线程创建了我的示例,所以不能保证所有图像操作都以正确的顺序执行(从随机操作的正确顺序来看)。

在这里,我完全陷入困境。 是否有人知道如何解决此问题以将相同的图像失真应用于多个图像?

我的一些想法:

  • 我想在这些图像失真方法中做一些同步,但我可以找到TensorFlow提供的任何内容
  • 我尝试生成一个随机数,例如我自己使用 tf.random_uniform()的随机亮度增量,并将此值用于 tf.image.adjust_contrast()。但是TensorFlow随机生成器的结果总是一个张量,我还没有找到一种方法来使用这个张量作为 tf.image.adjust_contrast()的参数,它需要一个简单的float32用于它的< em> contrast_factor 参数。
  • 可以(部分)工作的解决方案是使用 tf.concat()将所有图像组合成一个巨大的图像,应用随机操作来改变对比度和亮度,然后分割图像。但这不适用于随机翻转,因为这会(至少在我的情况下)改变图像的顺序,并且无法检测 tf.image.random_flip_left_right()是否已执行翻页或不翻页,如有必要,可能需要修复错误的图像顺序。

2 个答案:

答案 0 :(得分:7)

通过查看tensorflow中的random_flip_up_down和random_flip_left_right的代码,我提出了以下内容:

def image_distortions(image, distortions):
    distort_left_right_random = distortions[0]
    mirror = tf.less(tf.pack([1.0, distort_left_right_random, 1.0]), 0.5)
    image = tf.reverse(image, mirror)
    distort_up_down_random = distortions[1]
    mirror = tf.less(tf.pack([distort_up_down_random, 1.0, 1.0]), 0.5)
    image = tf.reverse(image, mirror)
    return image


distortions = tf.random_uniform([2], 0, 1.0, dtype=tf.float32)
image = image_distortions(image, distortions)
label = image_distortions(label, distortions)

答案 1 :(得分:1)

我会使用<script> export default { props: [ 'user_id' ], data() { return { recentchats: [], recentchat: { id: '', chatroom_id: '', user_id: '', receiver_id: '', created_at: '', updated_at: '', } } }, created() { this.fetchchatrooms(); }, methods: { fetchchatrooms(){ fetch('/api/fetchrecentchat/' +this.user_id) .then(res => res.json()) .then(res => { console.log(res); this.recentchats = res.data }); } }, mounted() { console.log('Recent Chat mounted.') } } 做这样的事情。它允许您指定在满足特定条件https://www.tensorflow.org/api_docs/python/tf/case

的情况下返回的内容
tf.case

检查它是否有效。

import tensorflow as tf

def distort(image, x):
    # flip vertically, horizontally, both, or do nothing
    image = tf.case({
        tf.equal(x,0): lambda: tf.reverse(image,[0]),
        tf.equal(x,1): lambda: tf.reverse(image,[1]),
        tf.equal(x,2): lambda: tf.reverse(image,[0,1]),
    }, default=lambda: image, exclusive=True)

    return image

def random_distortion(image):
    x = tf.random_uniform([1], 0, 4, dtype=tf.int32)
    return distort(image, x[0])