tensorflow
Использование 1D свертки
Поиск…
Основной пример
Обновление: TensorFlow теперь поддерживает 1D-свертку с версии r0.11, используя tf.nn.conv1d
.
Рассмотрим основной пример с вводом длины 10
и размером 16
. Размер партии 32
. Поэтому у нас есть местозаполнитель с формой ввода [batch_size, 10, 16]
.
batch_size = 32
x = tf.placeholder(tf.float32, [batch_size, 10, 16])
Затем мы создаем фильтр шириной 3, и мы принимаем 16
каналов в качестве входных данных и выводим также 16
каналов.
filter = tf.zeros([3, 16, 16]) # these should be real values, not 0
Наконец, применим tf.nn.conv1d
с шагом и дополнением:
- Шаг : целое число
s
- padding : это работает как в 2D, вы можете выбирать между
SAME
иVALID
.SAME
будет выводить одну и ту же длину ввода, в то время какVALID
не будет добавлять нулевое дополнение.
В нашем примере мы делаем шаг 2 и допустимое дополнение.
output = tf.nn.conv1d(x, filter, stride=2, padding="VALID")
Форма вывода должна быть [batch_size, 4, 16]
.
С padding="SAME"
у нас была бы форма вывода [batch_size, 5, 16]
.
Для предыдущих версий TensorFlow вы можете просто использовать 2D свертки при установке высоты входов и фильтров на 1
.
Математика за 1-й сверткой с передовыми примерами в TF
`Чтобы вычислить 1D свертку вручную, вы сдвигаете свое ядро над входом, вычисляете умножения по элементам и суммируете их.
Самый простой способ - заполнить = 0, шаг = 1
Поэтому, если ваш 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
Функция conv1d TF вычисляет свертки пакетами, поэтому, чтобы сделать это в TF, нам необходимо предоставить данные в правильном формате (doc объясняет, что вход должен быть в [batch, in_width, in_channels]
, он также объясняет, как должно выглядеть ядро лайк). Так
import tensorflow as tf
i = tf.constant([1, 0, 2, 3, 0, 1, 1], dtype=tf.float32, name='i')
k = tf.constant([2, 1, 3], dtype=tf.float32, name='k')
print i, '\n', k, '\n'
data = tf.reshape(i, [1, int(i.shape[0]), 1], name='data')
kernel = tf.reshape(k, [int(k.shape[0]), 1, 1], name='kernel')
print data, '\n', kernel, '\n'
res = tf.squeeze(tf.nn.conv1d(data, kernel, 1, 'VALID'))
with tf.Session() as sess:
print sess.run(res)
который даст вам тот же ответ, который мы рассчитали ранее: [ 8. 11. 7. 9. 4.]
Свертка с прокладкой
Отступы - это просто причудливый способ сказать append и добавить ваш ввод с некоторой ценностью. В большинстве случаев это значение равно 0, и именно поэтому большинство людей называют его нулевым заполнением. TF поддерживает «VALID» и «SAME» нулевое заполнение, для произвольного заполнения вам нужно использовать tf.pad () . Отметка «VALID» означает отсутствие отступов вообще, где то же самое означает, что выход будет иметь тот же размер ввода. Вычислим свертку с padding=1
в том же примере (обратите внимание, что для нашего ядра это «SAME» padding). Для этого мы просто добавляем наш массив с 1 нулем в начале / конце: input = [0, 1, 0, 2, 3, 0, 1, 1, 0]
.
Здесь вы можете заметить, что вам не нужно пересчитывать все: все элементы остаются неизменными, кроме первого / последнего:
- 1 = 0 * 2 + 1 * 1 + 0 * 3
- 3 = 1 * 2 + 1 * 1 + 0 * 3
Таким образом, результат [1, 8, 11, 7, 9, 4, 3]
который совпадает с рассчитанным с TF:
res = tf.squeeze(tf.nn.conv1d(data, kernel, 1, 'SAME'))
with tf.Session() as sess:
print sess.run(res)
Свертка с шагами
Стыки позволяют пропустить элементы во время скольжения. Во всех наших предыдущих примерах мы сдвинули 1 элемент, теперь вы можете сдвигать элементы s
за раз. Поскольку мы будем использовать предыдущий пример, есть трюк: скольжение по n
элементам равно скользящему на 1 элемент и выбору каждого n-го элемента.
Поэтому, если мы используем наш предыдущий пример с padding=1
и изменяем stride
до 2, вы просто берете предыдущий результат [1, 8, 11, 7, 9, 4, 3]
и оставляете каждый 2-й элемент, что приведет к [1, 11, 9, 3]
. Вы можете сделать это в TF следующим образом:
res = tf.squeeze(tf.nn.conv1d(data, kernel, 2, 'SAME'))
with tf.Session() as sess:
print sess.run(res)