tensorflow
Математика за двумерной сверткой с передовыми примерами в TF
Поиск…
Вступление
2D-свертка вычисляется аналогичным образом, чтобы вычислить 1D-свертку : вы сдвигаете свое ядро над входом, вычисляете умножения по элементам и суммируете их. Но вместо вашего ядра / ввода, являющегося массивом, здесь они являются матрицами.
Нет отступов, шагов = 1
Это самый простой пример: самые простые вычисления. Предположим, что ваш input
и kernel
:
Когда вы получите ядро, вы получите следующий результат: , который рассчитывается следующим образом:
- 14 = 4 * 1 + 3 * 0 + 1 * 1 + 2 * 2 + 1 * 1 + 0 * 0 + 1 * 0 + 2 * 0 + 4 * 1
- 6 = 3 * 1 + 1 * 0 + 0 * 1 + 1 * 2 + 0 * 1 + 1 * 0 + 2 * 0 + 4 * 0 + 1 * 1
- 6 = 2 * 1 + 1 * 0 + 0 * 1 + 1 * 2 + 2 * 1 + 4 * 0 + 3 * 0 + 1 * 0 + 0 * 1
- 12 = 1 * 1 + 0 * 0 + 1 * 1 + 2 * 2 + 4 * 1 + 1 * 0 + 1 * 0 + 0 * 0 + 2 * 1
Функция conv2d TF вычисляет свертки в партиях и использует немного другой формат. Для ввода [batch, in_height, in_width, in_channels]
для ядра это [filter_height, filter_width, in_channels, out_channels]
. Поэтому нам необходимо предоставить данные в правильном формате:
import tensorflow as tf
k = tf.constant([
[1, 0, 1],
[2, 1, 0],
[0, 0, 1]
], dtype=tf.float32, name='k')
i = tf.constant([
[4, 3, 1, 0],
[2, 1, 0, 1],
[1, 2, 4, 1],
[3, 1, 0, 2]
], dtype=tf.float32, name='i')
kernel = tf.reshape(k, [3, 3, 1, 1], name='kernel')
image = tf.reshape(i, [1, 4, 4, 1], name='image')
После этого свертка вычисляется с помощью:
res = tf.squeeze(tf.nn.conv2d(image, kernel, [1, 1, 1, 1], "VALID"))
# VALID means no padding
with tf.Session() as sess:
print sess.run(res)
И будет эквивалентно той, которую мы вычислили вручную.
Некоторые дополнения, шаги = 1
Padding - просто причудливое название: окружайте свою матрицу ввода некоторой константой. В большинстве случаев константа равна нулю, и поэтому люди называют ее нулевым заполнением. Поэтому, если вы хотите использовать дополнение 1 в нашем исходном вводе (проверьте первый пример с padding=0, strides=1
), матрица будет выглядеть так:
Чтобы вычислить значения свертки, вы делаете одно и то же скольжение. Обратите внимание, что в нашем случае многие значения в середине не нужно пересчитывать (они будут такими же, как в предыдущем примере. Я также не буду показывать все вычисления здесь, потому что идея проста: результат:
где
- 5 = 0 * 1 + 0 * 0 + 0 * 1 + 0 * 2 + 4 * 1 + 3 * 0 + 0 * 0 + 0 * 1 + 1 * 1
- ...
- 6 = 4 * 1 + 1 * 0 + 0 * 1 + 0 * 2 + 2 * 1 + 0 * 0 + 0 * 0 + 0 * 0 + 0 * 1
TF не поддерживает произвольное заполнение в функции conv2d , поэтому, если вам нужно некоторое дополнение, которое не поддерживается, используйте tf.pad () . К счастью для нашего ввода прокладка «SAME» будет равна padding = 1. Поэтому нам нужно изменить почти ничего в нашем предыдущем примере:
res = tf.squeeze(tf.nn.conv2d(image, kernel, [1, 1, 1, 1], "SAME"))
# 'SAME' makes sure that our output has the same size as input and
# uses appropriate padding. In our case it is 1.
with tf.Session() as sess:
print sess.run(res)
Вы можете проверить, что ответ будет таким же, как рассчитывается вручную.
Заполнение и шаг (самый общий случай)
Теперь мы применим свернутую свертку к нашему ранее описанному дополненному примеру и вычислим свертку, где p = 1, s = 2
Раньше, когда мы использовали strides = 1
, наше скользящее окно перемещалось на 1 позицию, а strides = s
перемещалось по s
позициям (вам нужно вычислить s^2
элемента меньше. Но в нашем случае мы можем воспользоваться ярлыком и не выполнять никаких действий вычислений вообще. Поскольку мы уже вычислили значения для s = 1
, в нашем случае мы можем просто захватить каждый второй элемент.
Поэтому, если решение является случаем s = 1
было
в случае s = 2
это будет:
Проверьте позиции значений 14, 2, 12, 6 в предыдущей матрице. Единственное изменение, которое нам нужно выполнить в нашем коде, - это изменить шаги от 1 до 2 для измерения ширины и высоты (2-й, 3-й).
res = tf.squeeze(tf.nn.conv2d(image, kernel, [1, 2, 2, 1], "SAME"))
with tf.Session() as sess:
print sess.run(res)
Кстати, нет ничего, что помешало бы нам использовать разные шаги для разных измерений.