2015-11-26 37 views
13

Sto adattando il cifar10 convolution example al mio problema. Mi piacerebbe cambiare l'input dei dati da un design che legge le immagini una alla volta da un file a un disegno che opera su un set di immagini già in memoria. La funzione originaria inputs() assomiglia a questo:Tensorflow "operazione mappa" per tensore?

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) 

Nella versione originale, read_input è un tensore che contiene un'immagine.

ho mantenere tutte le mie immagini nella RAM, quindi invece di utilizzare filename_queue, ho una enorme images_tensor = tf.constant(images), dove images_tensor.shape è (cosa, 32, 32, 3).

La mia domanda è molto di base: qual è il modo migliore per applicare alcune funzioni (tf.image.resize_image_with_crop_or_pad nel mio caso) a tutti gli elementi di images_tensor?

L'iterazione è problematica in tensorflow, con sezioni limitate (TensorFlow - numpy-like tensor indexing). C'è una soluzione per raggiungere questo utilizzando solo un comando?

risposta

8

Ci sono alcune risposte - nessuna abbastanza elegante come una funzione di mappa. La cosa migliore dipende un po 'dal tuo desiderio di efficienza della memoria.

(a) È possibile utilizzare enqueue_many per gettarli in un'immagine un tf.FIFOQueue e poi dequeue e tf.image.resize_image_with_crop_or_pad alla volta, e concat tutto indietro in un unico grande Smoosh. Questo è probabilmente lento. Richiede N chiamate da eseguire per N immagini.

(b) È possibile utilizzare un singolo feed di segnaposto ed eseguirlo per ridimensionare e ritagliarli dall'interno dell'origine dati originale. Questa è probabilmente la migliore opzione dal punto di vista della memoria, perché non è necessario memorizzare i dati non sottoposti a memoria.

(c) È possibile utilizzare l'op tf.control_flow_ops.While per eseguire l'iterazione dell'intero batch e creare il risultato in un tf.Variable. Soprattutto se si sfrutta l'esecuzione parallela consentita da tempo, questo è probabilmente l'approccio più veloce.

Probabilmente opterei per l'opzione (c) a meno che non si desideri ridurre al minimo l'uso della memoria, nel qual caso il filtro durante il passaggio (opzione b) sarebbe una scelta migliore.

8

A partire dalla versione 0.8 è map_fn. Dal 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

Non trovo 'map_fn' in nessuna versione dei documenti. Link? –

+2

non riesco a trovare nulla online o - quanto sopra (e ho completato esso) cam da importazione tensorflow come tf aiuto (tf.map_fn) tanto per essere sicuro che sei versioni 0.8 o successiva. – DomJack

1

tensorflow fornisce un paio di higher-order functions e uno di loro è tf.map_fn. L'utilizzo è molto semplice: si definisce il mappping e si applica al tensore:

X = tf.Variable(...) 
mapping = lambda x: f(x) 
res = tf.map_fn(mapping, X) 
Problemi correlati