Как conv2d_transpose работает в Tensorflow - PullRequest
0 голосов
/ 26 августа 2018

Я использую FCN для сегментации изображения и реализую его с помощью Tensorflow. В этой сети используются слои с «повышающей дискретизацией», которые на самом деле являются «conv2d_transpose». Мне нужно знать, как на самом деле работает эта функция, потому что я хочу заново реализовать функцию "conv2d_transpose" в C ++.

Для моего приложения мне нужно расширить вход с помощью формы [1, 16, 16, 6], где 1 - размер пакета, 16 - ширина / высота и 6 - количество каналов, до выхода с форма [1, 32, 32, 6]. Я использую веса с этой формой [4, 4, 6, 6], где 4 - это размер ядра, а 6 - входные и выходные каналы, а также ОДИНАКОВОЕ заполнение.

  • input [1, 16, 16, 6]
  • output [1, 32, 32, 6]
  • weights [4, 4, 6, 6]
  • strides [1, 2, 2, 1]
  • padding SAME

Итак, после некоторого исследования я нашел эту тему , и эту одну , но я все еще очень запутался. Кажется, функция работает так:

conv2d_transpose () просто транспонирует веса и переворачивает их на 180 градусов. Затем он применяет стандарт conv2d (). «Транспонировать» практически означает, что он меняет порядок «столбцов» в тензоре весов.

Итак, для проверки этой теории я попробовал небольшой фрагмент кода, но похоже, что он не транспонирует веса и переворачивает их на 180. Я думаю, что после многих исследований я все еще что-то упускаю. ..

Для более понятного примера я использовал эту конфигурацию:

  • input [1, 2, 2, 2]
  • output [1, 4, 4, 2]
  • weights [4, 4, 2, 2]
  • strides [1, 2, 2, 1]
  • padding SAME

Это код:

import tensorflow as tf
import numpy as np

channels   = 2
img_width  = 2
img_height = 2
kernel     = 4

np.random.seed(10)

w   = np.zeros((kernel, kernel, channels, channels))
for i in range(kernel):
  w[i] += i+1
img = np.zeros((1, img_height, img_width, channels))
img[0][0][0][0] = 1
print(img)
print(w)

weights = tf.constant(w)
inp = tf.constant(img)

real_output = tf.nn.conv2d_transpose(
    inp,
    weights,
    output_shape=[1,img_height*2,img_width*2,channels],
    strides=[1,2,2,1],
    padding='SAME'
)

with tf.Session() as sess:
  print(sess.run([real_output]))

Результат здесь (с красивым рисунком).

Наконец, мой вопрос: что не так с моими аргументами и почему весы не были «транспонированы и повернуты»?

...