2015-11-26 15 views
13

Dostosowuję do mojego problemu cifar10 convolution example. Chciałbym zmienić dane wejściowe z projektu, który odczytuje obrazy pojedynczo z pliku do projektu działającego na zbiorze obrazów w pamięci. Oryginalny inputs() funkcja wygląda tak:"Operacja mapy" dla tensora?

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) 

W oryginalnej wersji, read_input jest tensor zawierające jedno zdjęcie.

Trzymam wszystkie moje obrazy w pamięci RAM, więc zamiast używać filename_queue, mam jeden wielki images_tensor = tf.constant(images), gdzie images_tensor.shape jest (coś, 32, 32, 3).

Moje pytanie jest bardzo-bardzo podstawowe: jaki jest najlepszy sposób, aby zastosować jakąś funkcję (tf.image.resize_image_with_crop_or_pad w moim przypadku) do wszystkich elementów images_tensor?

Powtórzanie jest problematyczne w tensorflow, z ograniczonymi plasterkami (TensorFlow - numpy-like tensor indexing). Czy istnieje rozwiązanie pozwalające to osiągnąć za pomocą tylko jednego polecenia?

Odpowiedz

8

Istnieje kilka odpowiedzi - żadna nie jest tak elegancka jak funkcja mapy. To, co najlepsze, zależy trochę od twojego pragnienia wydajności pamięci.

(a) Można używać enqueue_many wyrzucić je do tf.FIFOQueue a następnie rozkolejkowania i tf.image.resize_image_with_crop_or_pad obrazu w czasie, a Concat to wszystko z powrotem w jeden wielki Smoosh. Prawdopodobnie jest to powolne. Wymaga N połączeń, aby uruchomić dla obrazów N.

(b) Można użyć pojedynczego pliku zastępczego i uruchomić go, aby zmienić rozmiar i przyciąć go w drodze z oryginalnego źródła danych. Jest to prawdopodobnie najlepsza opcja z perspektywy pamięci, ponieważ nigdy nie trzeba przechowywać nierezydentowanych danych w pamięci.

(c) Można użyć opcji tf.control_flow_ops.While do iteracji całej partii i utworzenia wyniku w postaci tf.Variable. Szczególnie jeśli skorzystasz z równoległego wykonania dozwolonego przez jakiś czas, prawdopodobnie będzie to najszybsze podejście.

Prawdopodobnie wybrałbym opcję (c), chyba że chce się zminimalizować użycie pamięci, w którym to przypadku filtrowanie jej w drodze (opcja b) byłoby lepszym wyborem.

8

Od wersji 0.8 jest map_fn. Od 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

Nie znajduję 'map_fn' w żadnej wersji dokumentów. Połączyć? –

+2

Nie mogę znaleźć coś w Internecie albo - wyżej (a ja już zakończona go) CAM importowej tensorflow TF pomocy (tf.map_fn) Wystarczy upewnić się, że jesteś w wersji 0.8 lub nowszej. – DomJack

1

Tensorflow zapewnia kilka higher-order functions a jednym z nich jest tf.map_fn. Użycie jest bardzo proste: definiujesz swoje mapowanie i stosujesz je do tensora:

X = tf.Variable(...) 
mapping = lambda x: f(x) 
res = tf.map_fn(mapping, X) 
Powiązane problemy