2015-11-26 9 views
13

Ich passe die cifar10 convolution example an mein Problem an. Ich möchte die Dateneingabe von einem Design ändern, das Bilder einzeln aus einer Datei in ein Design liest, das auf einem bereits im Speicher befindlichen Satz von Bildern ausgeführt wird. Die ursprüngliche inputs() Funktion sieht wie folgt aus:Tensorflow "Kartenoperation" für Tensor?

read_input = cifar10_input.read_cifar10(filename_queue) 
reshaped_image = tf.cast(read_input.uint8image, tf.float32) 
# Crop the central [height, width] of the image. 
resized_image = tf.image.resize_image_with_crop_or_pad(reshaped_image, 
                width, height) 

In der ursprünglichen Version, read_input ein Tensor ist ein Bild enthält.

Ich halte alle meine Bilder in RAM, so dass anstelle filename_queue zu verwenden, ich habe einen riesigen images_tensor = tf.constant(images), wo images_tensor.shape ist (etwas, 32, 32, 3).

Meine Frage ist sehr, sehr einfach: Was ist der beste Weg, um eine Funktion (tf.image.resize_image_with_crop_or_pad in meinem Fall) auf alle Elemente von images_tensor anzuwenden?

Iteration ist problematisch in Tensorflow, mit begrenzten Scheiben (TensorFlow - numpy-like tensor indexing). Gibt es eine Lösung, um dies mit nur einem Befehl zu erreichen?

Antwort

8

Es gibt ein paar Antworten - keine so elegant wie eine Kartenfunktion. Was am besten ist, hängt ein wenig von Ihrem Wunsch nach Speichereffizienz ab.

(a) können Sie enqueue_many verwenden sie in ein tf.FIFOQueue zu werfen und dann dequeue und tf.image.resize_image_with_crop_or_pad ein Bild zu einem Zeitpunkt, und alles wieder in einer großen smoosh verketten. Dies ist wahrscheinlich langsam. Erfordert N Aufrufe für N Bilder.

(b) Sie können einen einzelnen Platzhalter-Feed verwenden und ihn auf seiner ursprünglichen Datenquelle verkleinern und zuschneiden. Dies ist möglicherweise die beste Option aus der Speicherperspektive, da Sie die nicht gespeicherten Daten nie im Speicher speichern müssen.

(c) Sie könnten die tf.control_flow_ops.While op verwenden, um die gesamte Charge zu durchlaufen und das Ergebnis in einer tf.Variable aufzubauen. Insbesondere wenn Sie die parallele Ausführung von while nutzen, ist dies wahrscheinlich der schnellste Ansatz.

Ich würde wahrscheinlich für Option (c) gehen, wenn Sie Speicherverbrauch minimieren möchten, in diesem Fall wäre es besser, sie auf dem Weg in (Option b) zu filtern.

8

Ab Version 0.8 gibt es map_fn. Von der documentation:

map_fn(fn, elems, dtype=None, parallel_iterations=10, back_prop=True, swap_memory=False, name=None)

map on the list of tensors unpacked from elems on dimension 0.

This map operator repeatedly applies the callable fn to a sequence of elements from first to last. The elements are made of the tensors unpacked from elems . dtype is the data type of the return value of fn . Users must provide dtype if it is different from the data type of elems .

Suppose that elems is unpacked into values , a list of tensors. The shape of the result tensor is [len(values)] + fn(values[0]).shape .

Args:

fn: The callable to be performed.

elems: A tensor to be unpacked to apply fn .

dtype: (optional) The output type of fn .

parallel_iterations: (optional) The number of iterations allowed to run in parallel. back_prop: (optional) True enables back propagation. swap_memory: (optional) True enables GPU-CPU memory swapping. name: (optional) Name prefix for the returned tensors.

Returns:

A tensor that packs the results of applying fn to the list of tensors unpacked from elems , from first to last.

Raises:

TypeError: if fn is not callable.

Example:

elems = [1, 2, 3, 4, 5, 6] 
    squares = map_fn(lambda x: x * x, elems) 
    # squares == [1, 4, 9, 16, 25, 36] 
    ``` 
+0

Ich finde 'map_fn' in keiner Version der Dokumentation. Verknüpfung? –

+2

Ich kann nicht alles online entweder finden - die oben (und ich habe es fertig gestellt) cam von Import tensorflow als tf Hilfe (tf.map_fn) nur sicher, dass Sie Version 0.8 oder höher ist sein. – DomJack

1

bietet Tensorflow ein paar higher-order functions und einer von ihnen ist tf.map_fn. Die Verwendung ist sehr einfach: Sie definieren Ihre Zuordnung und wenden sie auf den Tensor an:

X = tf.Variable(...) 
mapping = lambda x: f(x) 
res = tf.map_fn(mapping, X) 
Verwandte Themen