2017-02-16 5 views
0

Ich möchte mein Eingabebild (Tensor) in jeder Charge nach oben/unten oder rechts/links verschieben lassen.Wie Tensors in Tensorflow zufällig verschoben oder verschoben werden

Zum Beispiel habe ich eine Charge von Graustufenbildern mit der Größe [10, 48, 64, 1].

Wenn es ein Bild ist, ich weiß, ich tf.pad und tf.slice (oder andere integrierte Funktionen) kann

Aber ich will zu 10 verschiedenen Bildern mit einer Operation Zufallsverschiebung anzuwenden.

Ist es möglich? oder sollte ich Schleife wie tf.scan verwenden?

Antwort

1

Suchen Sie nach tf.random_crop und tf.pad?

Nun, wenn tf.random_crop verwendet wird, wird eine zufällige Verschiebung auf alle Bilder im Stapel angewendet. Die Verschiebung innerhalb einer Charge ist dieselbe, kann jedoch für verschiedene Chargen unterschiedlich sein.

Wenn Sie verschiedene Verschiebung innerhalb einer Charge verwenden möchten, ist es besser, eine Warteschlange/Eingabe-Pipeline zu verwenden. Siehe https://www.tensorflow.org/programmers_guide/reading_data für mehr. Hier ist ein Beispielcode aus einem Teil meines eigenen Projekts. self.image_names ist eine Python-Liste, die Pfade zu allen Trainingsbildern enthält. In einer Eingabepipeline ist der Datenfluss wie ein Stream: Sie müssen nur mit einem Bild arbeiten, und die Warteschlange kümmert sich automatisch um die Planung (einige Threads lesen die Daten, andere verarbeiten die Daten, einige gruppieren Einzelbilder zu Batches, andere geben die Daten an GPU usw. weiter, um die gesamte Pipeline beschäftigt zu halten. Im folgenden Code sind images und labels Warteschlangen. Das heißt, wenn Sie diese Variable verarbeiten (wie ich in self.data_augmentation), können Sie denken, es enthält nur ein Bild, aber die Warteschlange verarbeitet jedes Element darin (Es ist wie eine implizite Schleife), dann tf.train.shuffle_batch wird Trainingsdaten mischen in der Warteschlange und gruppieren sie in Chargen.

def data_augmentation(images): 
    if FLAGS.random_flip_up_down: 
     images = tf.image.random_flip_up_down(images) 
    if FLAGS.random_brightness: 
     images = tf.image.random_brightness(images, max_delta=0.3) 
    if FLAGS.random_contrast: 
     images = tf.image.random_contrast(images, 0.8, 1.2) 
    return images 

def input_pipeline(self, batch_size, num_epochs=None, aug=False): 
    images_tensor = tf.convert_to_tensor(self.image_names, dtype=tf.string) 
    labels_tensor = tf.convert_to_tensor(self.labels, dtype=tf.int64) 
    input_queue = tf.train.slice_input_producer([images_tensor, labels_tensor], num_epochs=num_epochs) 

    labels = input_queue[1] 
    images_content = tf.read_file(input_queue[0]) 
    images = tf.image.convert_image_dtype(tf.image.decode_png(images_content, channels=1), tf.float32) 
    if aug: 
     images = self.data_augmentation(images) 
    new_size = tf.constant([FLAGS.image_size, FLAGS.image_size], dtype=tf.int32) 
    images = tf.image.resize_images(images, new_size) 
    image_batch, label_batch = tf.train.shuffle_batch([images, labels], batch_size=batch_size, capacity=50000, 
                 min_after_dequeue=10000) 
    # print 'image_batch', image_batch.get_shape() 
    return image_batch, label_batch 
+0

Ist es möglich, alle verschiedenen zufälligen Verschiebung innerhalb einer Charge anzuwenden? – user270700

+0

aktualisierte meine Antwort. – soloice

2

Als Alternative könnte man auch tf.contrib.image.transform() verwenden und die Parameter a2 und b2 das Bild zu übersetzen:

import numpy as np 
import tensorflow as tf 

image1 = np.array([[[.1], [.1], [.1], [.1]], 
        [[.2], [.2], [.2], [.2]], 
        [[.3], [.3], [.3], [.3]], 
        [[.4], [.4], [.4], [.4]]]) 
image2 = np.array([[[.1], [.2], [.3], [.4]], 
        [[.1], [.2], [.3], [.4]], 
        [[.1], [.2], [.3], [.4]], 
        [[.1], [.2], [.3], [.4]]]) 
images = np.stack([image1, image2]) 
images_ = tf.convert_to_tensor(images, dtype=tf.float32) 

shift1_x = 1 
shift1_y = 2 
shift2_x = -1 
shift2_y = 0 
transforms_ = tf.convert_to_tensor([[1, 0, -shift1_x, 0, 1, -shift1_y, 0, 0], 
            [1, 0, -shift2_x, 0, 1, -shift2_y, 0, 0]], 
            tf.float32) 
shifted_ = tf.contrib.image.transform(images=images_, 
             transforms=transforms_) 
with tf.Session() as sess: 
    sess.run(tf.global_variables_initializer()) 

    shifted = sess.run([shifted_]) 
    print(shifted) 

Die verwandelt Projektionsmatrix kann auch ein Tensor sein der Größe N x 8, so ist es möglich, jedes Bild einer Charge unterschiedlich zu verschieben. Dies kann einfach um tf.random_uniform() erweitert werden, um eine gewisse Zufälligkeit zur x/y-Verschiebung jedes Bildes zu beinhalten.

Edit: Um für jedes Bild der Charge Zufallsverschiebungen zu verwenden:

... 
images_ = tf.convert_to_tensor(images, dtype=tf.float32) 

num_imgs = images.shape[0] 
base_ = tf.convert_to_tensor(np.tile([1, 0, 0, 0, 1, 0, 0, 0], [num_imgs, 1]), dtype=tf.float32) 
mask_ = tf.convert_to_tensor(np.tile([0, 0, 1, 0, 0, 1, 0, 0], [num_imgs, 1]), dtype=tf.float32) 
random_shift_ = tf.random_uniform([num_imgs, 8], minval=-2.49, maxval=2.49, dtype=tf.float32) 
transforms_ = base_ + random_shift_ * mask_ 

shifted_ = tf.contrib.image.transform(images=images_, 
             transforms=transforms_) 
... 

Edit 2: Aus Gründen der Fertigstellung hier nur eine weitere Hilfsfunktion mit gilt Zufallsrotation und Verschiebung zu jedem einzelnen Bild einer Charge:

def augment_data(input_data, angle, shift): 
    num_images_ = tf.shape(input_data)[0] 
    # random rotate 
    processed_data = tf.contrib.image.rotate(input_data, 
              tf.random_uniform([num_images_], 
                   maxval=math.pi/180 * angle, 
                   minval=math.pi/180 * -angle)) 
    # random shift 
    base_row = tf.constant([1, 0, 0, 0, 1, 0, 0, 0], shape=[1, 8], dtype=tf.float32) 
    base_ = tf.tile(base_row, [num_images_, 1]) 
    mask_row = tf.constant([0, 0, 1, 0, 0, 1, 0, 0], shape=[1, 8], dtype=tf.float32) 
    mask_ = tf.tile(mask_row, [num_images_, 1]) 
    random_shift_ = tf.random_uniform([num_images_, 8], minval=-shift, maxval=shift, dtype=tf.float32) 
    transforms_ = base_ + random_shift_ * mask_ 

    processed_data = tf.contrib.image.transform(images=processed_data, 
               transforms=transforms_) 
    return processed_data 
Verwandte Themen