Ответ 1
Спасибо за вопрос! Вы совершенно правы - проблема в том, что входные и выходные измерения передаются в tf.nn.conv2d_transpose, не согласны. (Ошибка может быть обнаружена при вычислении градиентов, но вычисление градиента не является проблемой.)
Посмотрите только на первую часть своего кода и немного упростите ее:
sess = tf.Session()
batch_size = 3
output_shape = [batch_size, 8, 8, 128]
strides = [1, 2, 2, 1]
l = tf.constant(0.1, shape=[batch_size, 32, 32, 4])
w = tf.constant(0.1, shape=[7, 7, 128, 4])
h1 = tf.nn.conv2d_transpose(l, w, output_shape=output_shape, strides=strides, padding='SAME')
print sess.run(h1)
Я заменил переменные на константы --- легче видеть, что происходит.
Если вы попытаетесь запустить этот код, вы получите аналогичную ошибку:
InvalidArgumentError: Conv2DCustomBackpropInput: Size of out_backprop doesn't match computed: actual = 32, computed = 4
[[Node: conv2d_transpose_6 = Conv2DBackpropInput[T=DT_FLOAT, data_format="NHWC", padding="SAME", strides=[1, 2, 2, 1], use_cudnn_on_gpu=true, _device="/job:localhost/replica:0/task:0/cpu:0"](conv2d_transpose_6/output_shape, Const_25, Const_24)]]
Теперь ошибка немного вводит в заблуждение - она говорит об аргументе 'out_backprop' для "Conv2DCustomBackpropInput". Ключ в том, что tf.nn.conv2d_transpose на самом деле является только градиентом tf.nn.conv2d, поэтому Tensorflow использует тот же код внутри (Conv2DCustomBackpropInput) для вычисления градиента tf.nn.conv2d и для вычисления tf.nn.conv2d_transpose.
Ошибка означает, что запрошенный "output_shape" невозможен, учитывая формы "l" и "w".
Так как tf.nn.conv2d_transpose - это обратный (градиентный) аналог tf.nn.conv2d, один из способов увидеть, какими должны быть правильные фигуры, - использовать соответствующую переднюю операцию:
output = tf.constant(0.1, shape=output_shape)
expected_l = tf.nn.conv2d(output, w, strides=strides, padding='SAME')
print expected_l.get_shape()
# Prints (3, 4, 4, 4)
То есть в прямом направлении, если вы предоставили тензор формы 'output_shape', вы получите тензор формы (3, 4, 4, 4). Таким образом, одним из способов решения проблемы является изменение формы "l" на (3, 4, 4, 4); если вы измените код выше:
l = tf.constant(0.1, shape=[batch_size, 4, 4, 4])
все работает нормально.
В общем, попробуйте использовать tf.nn.conv2d, чтобы понять, какова связь между тензорными фигурами. Так как tf.nn.conv2d_transpose является его обратной копией, он имеет одинаковую зависимость между форматами ввода, вывода и фильтра (но с изменением ролей ввода и вывода).
Надеюсь, что это поможет!