Аргумент "Тензорный поток"

Я пытаюсь понять аргумент strides в tf.nn.avg_pool, tf.nn.max_pool, tf.nn.conv2d.

В документации говорится:

strides: Список целых чисел с длиной >= 4. Шаг раздвижного окна для каждого измерения входного тензора.

Мои вопросы:

  • Что представляет собой каждый из целых чисел 4+?
  • Почему у них есть шаги [0] = strides [3] = 1 для convnets?
  • В в этом примере мы видим tf.reshape(_X,shape=[-1, 28, 28, 1]). Почему -1?

К сожалению, примеры в документах для изменения с использованием -1 не слишком хорошо переводятся в этот сценарий.

Ответ 1

Объединение и сверточные операции сдвигают "окно" через входной тензор. Используя tf.nn.conv2d в качестве примера: Если входной тензор имеет 4 измерения: [batch, height, width, channels], то свертка работает в 2D окне в измерениях height, width.

strides определяет, сколько окон сдвигается в каждом из измерений. Типичное использование задает первый (пакетный) и последний (глубину) шаг равным 1.

Позвольте использовать очень конкретный пример: Запуск 2-й свертки над входным изображением с серой шкалой 32x32. Я говорю оттенки серого, потому что тогда входное изображение имеет глубину = 1, что помогает сохранить его просто. Пусть это изображение выглядит так:

00 01 02 03 04 ...
10 11 12 13 14 ...
20 21 22 23 24 ...
30 31 32 33 34 ...
...

Запустите окно свертки 2x2 по одному примеру (размер партии = 1). Мы дадим свертку глубину выходного канала 8.

Ввод свертки имеет shape=[1, 32, 32, 1].

Если вы укажете strides=[1,1,1,1] с padding=SAME, то выход фильтра будет [1, 32, 32, 8].

Сначала фильтр создаст выход для:

F(00 01
  10 11)

И затем для:

F(01 02
  11 12)

и т.д. Затем он переместится во вторую строку, вычисляя:

F(10, 11
  20, 21)

затем

F(11, 12
  21, 22)

Если вы укажете шаг [1, 2, 2, 1], он не будет перекрывать окна. Он вычислит:

F(00, 01
  10, 11)

а затем

F(02, 03
  12, 13)

Шаг работает аналогично для операторов объединения.

Вопрос 2: Почему strides [1, x, y, 1] для convnets

Первая 1 - это партия: вы обычно не хотите пропускать примеры в своей партии или не должны были включать их в первую очередь.:)

Последняя 1 - это глубина свертки: по той же причине вы обычно не хотите пропускать входы.

Оператор conv2d более общий, поэтому вы можете создавать свертки, которые перемещают окно по другим измерениям, но это не типичное использование в convnets. Типичное использование - использовать их пространственно.

Зачем перерисовываться до -1 -1 является заполнителем, который говорит "при необходимости отрегулируйте, чтобы соответствовать размеру, необходимому для полного тензора". Это способ сделать код независимым от размера входной партии, так что вы можете изменить свой конвейер и не изменять размер партии в коде.

Ответ 2

Входы 4-мерные и имеют форму: [batch_size, image_rows, image_cols, number_of_colors]

Шаги в общем случае определяют совпадение между применяемыми операциями. В случае conv2d указывается, какое расстояние между последовательными приложениями сверточных фильтров. Значение 1 в определенном измерении означает, что мы применяем оператор в каждой строке /col, значение 2 означает каждую секунду и т.д.

Re 1) Значения, которые имеют значение для сверток, являются вторыми и третьими, и они представляют собой перекрытие при применении сверточных фильтров вдоль строк и столбцов. Значение [1, 2, 2, 1] говорит, что мы хотим применять фильтры для каждой второй строки и столбца.

Re 2) Я не знаю технических ограничений (может быть, требование CuDNN), но обычно люди используют шаги по размерам строк или столбцов. Не обязательно иметь смысл делать это по размеру партии. Не уверен в последний размер.

Re 3) Установка -1 для одного из средств измерения: "установите значение для первого измерения так, чтобы общее количество элементов в тензоре не изменилось". В нашем случае -1 будет равен batch_size.

Ответ 3

Начнем с того, что делает шаг в одномерном случае.

Предположим, что ваш input = [1, 0, 2, 3, 0, 1, 1] и kernel = [2, 1, 3] результат свертки [8, 11, 7, 9, 4], который вычисляется путем сдвига вашего ядра над входом, выполнения умножения по элементам и суммирования всего. Как это:

  • 8 = 1 * 2 + 0 * 1 + 2 * 3
  • 11 = 0 * 2 + 2 * 1 + 3 * 3
  • 7 = 2 * 2 + 3 * 1 + 0 * 3
  • 9 = 3 * 2 + 0 * 1 + 1 * 3
  • 4 = 0 * 2 + 1 * 1 + 1 * 3

Здесь мы перемещаемся по одному элементу, но ничто не останавливает вас, используя любое другое число. Этот номер - ваш шаг. Вы можете думать об этом как о снижении результатов 1-ступенчатой ​​свертки, просто принимая каждый s-й результат.

Зная размер ввода i, размер ядра k, шаг s и дополнение p, вы можете легко вычислить выходной размер свертки как:

введите описание изображения здесь

Здесь || оператор означает работу потолка. Для слоя объединения s = 1.


N-мерный случай.

Зная математику для 1-мерного случая, n-мерный случай прост, если вы увидите, что каждый dim независим. Таким образом, вы просто перемещаете каждый размер отдельно. Ниже приведен пример для 2-го. Обратите внимание, что вам не нужно иметь один и тот же шаг во всех измерениях. Таким образом, для N-dim ввода/ядра вы должны обеспечить N шагов.


Итак, теперь легко ответить на все ваши вопросы:

  • Что представляет собой каждый из целых чисел 4+?. conv2d, pool сообщает вам, что этот список представляет собой шаг между каждым измерением. Обратите внимание, что длина списка шагов совпадает с рангом тензора ядра.
  • Зачем им делать шаги [0] = strides 3= 1 для convnets?, Первое измерение - размер партии, последний - каналы. Нет смысла пропускать ни пакет, ни канал. Итак, вы делаете их 1. Для ширины/высоты вы можете пропустить что-то и почему они могут быть не 1.
  • tf.reshape(_X, shape = [- 1, 28, 28, 1]). Почему -1? tf.reshape, он охватывает вас:

    Если одним компонентом формы является специальное значение -1, размер этого измерения вычисляется так, чтобы общий размер оставался постоянным. В частности, форма [-1] выравнивается в 1-D. Не более одной составляющей формы может быть -1.