Подтвердить что ты не робот

Тензорный поток "операция отображения" для тензора?

Я приспосабливаю пример свертки cifar10 к моей проблеме. Я хотел бы изменить ввод данных из дизайна, который каждый раз считывает изображения из файла в проект, который работает с уже установленным в памяти набором изображений. Оригинальная функция inputs() выглядит следующим образом:

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)

В исходной версии read_input - тензор, содержащий одно изображение.

Я сохраняю все свои изображения в ОЗУ, поэтому вместо использования filename_queue у меня есть один огромный images_tensor = tf.constant(images), где images_tensor.shape есть (что-то, 32, 32, 3).

Мой вопрос очень-очень простой: как лучше всего применить некоторую функцию (tf.image.resize_image_with_crop_or_pad в моем случае) ко всем элементам images_tensor?

Итерация проблематична в тензорном потоке с ограниченными фрагментами (TensorFlow - индексирование тензоподобных тензоров). Есть ли решение для этого, используя только одну команду?

4b9b3361

Ответ 1

Есть несколько ответов - не так элегантно, как функция карты. Это лучше всего зависит от вашего желания по эффективности использования памяти.

(a) Вы можете использовать enqueue_many, чтобы выбросить их в tf.FIFOQueue, а затем удалить из очереди и tf.image.resize_image_with_crop_or_pad изображение за раз, и выполнить его все обратно в один большой smoosh. Это, вероятно, медленно. Требуется N вызовов для выполнения N изображений.

(b) Вы можете использовать один канал-заполнитель и запускать его для изменения размера и обрезать их по своему исходному исходному источнику данных. Это, пожалуй, лучший вариант с точки зрения памяти, потому что вам никогда не нужно хранить нераспределенные данные в памяти.

(c) Вы можете использовать tf.control_flow_ops.While op для перебора всей партии и создания результата в tf.Variable. В частности, если вы воспользуетесь параллельным выполнением, разрешенным while, это, скорее всего, самый быстрый подход.

Я бы выбрал вариант (c), если вы не хотите минимизировать использование памяти, и в этом случае фильтрация его по пути (вариант b) будет лучшим выбором.

Ответ 2

Начиная с версии 0.8 есть map_fn. Из документации:

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

карта в списке тензоров, распакованных из elems по размерности 0.

Этот оператор карты повторно применяет вызываемый fn к последовательности элементов от первого до последнего. Элементы изготовлены из тензоров, распакованных из elems. dtype - это тип данных возвращаемого значения fn. Пользователи должны предоставить dtype если он отличается от типа данных elems.

Предположим, что elems распаковывается в values, список тензоров. Форма тензора результата имеет вид [len(values)] + fn(values[0]).shape.

Args:

fn: вызываемый для выполнения.

elems: тензор, распаковываемый для применения fn.

dtype: (необязательно) тип вывода fn.

parallel_iterations: (необязательно) Количество итераций, разрешенных для параллельного выполнения. back_prop: (необязательно) True разрешает обратное распространение. swap_memory: (необязательно) True включает обмен памяти GPU-CPU. name: (необязательно) префикс имени для возвращаемых тензоров.

Возвращает:

Тензор, который упаковывает результаты применения fn к списку тензоров, распакованных от elems, от первого до последнего.

поднимает:

Ошибка типа: если fn не вызывается.

Пример:

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

Ответ 3

Tensorflow предоставляет несколько функций высшего порядка, одной из которых является tf.map_fn. Использование очень просто: вы определяете свой маппинг и применяете его к тензору:

variable = tf.Variable(...)
mapping = lambda x: f(x)
res = tf.map_fn(mapping, variable)