对于每个卷积激活图,我想连接一层常量-更具体地说,我想连接一个网状网格。 (这是复制优步的论文。)
例如,假设我有一个(?, 256, 256, 32)
的激活图;那么我想连接形状为(?, 256, 256, 1)
的常量层。
这就是我的做法:
from keras import layers
import tensorflow as tf
import numpy as np
input_layer = layers.Input((256, 256, 3))
conv = layers.Conv2D(32, 3, padding='same')(input_layer)
print('conv:', conv.shape)
xx, yy = np.mgrid[:256, :256] # [(256, 256), (256, 256)]
xx = tf.constant(xx, np.float32)
yy = tf.constant(yy, np.float32)
xx = tf.reshape(xx, (-1, 256, 256, -1))
yy = tf.reshape(yy, (-1, 256, 256, -1))
print('xx:', xx.shape, 'yy:', yy.shape)
concat = layers.Concatenate()([conv, xx, yy])
print('concat:', concat.shape)
conv2 = layers.Conv2D(32, 3, padding='same')(concat)
print('conv2:', conv2.shape)
但是我得到了错误:
conv: (?, 256, 256, 32)
xx: (?, 256, 256, ?) yy: (?, 256, 256, ?)
concat: (?, 256, 256, ?)
Traceback (most recent call last):
File "temp.py", line 21, in <module>
conv2 = layers.Conv2D(32, 3, padding='same')(concat)
[...]
raise ValueError('The channel dimension of the inputs '
ValueError: The channel dimension of the inputs should be defined. Found `None`.
问题是我的常量层是(?, 256, 256, ?)
,而不是(?, 256, 256, 1)
,然后下一个卷积层出错了。
我尝试其他事情都没有成功。
PS:我尝试实施的论文已经implemented here。
答案 0 :(得分:1)
问题是tf.reshape无法推断一个以上维度的形状(即,对多个维度使用-1
会导致未定义的维度?
)。由于您希望xx
和yy
的形状为(?, 256, 256, 1)
,因此可以按如下所示对这些张量进行整形:
xx = tf.reshape(xx, (-1, 256, 256, 1))
yy = tf.reshape(yy, (-1, 256, 256, 1))
结果形状将为(1, 256, 256, 1)
。现在,conv
是(?, 256, 256, 32)
,keras.layers.Concatenate要求除了concat轴以外的所有输入的形状都必须匹配。然后,您可以使用tf.tile在第一个维度上重复张量xx
和yy
,以匹配批量大小:
xx = tf.tile(xx, [tf.shape(conv)[0], 1, 1, 1])
yy = tf.tile(yy, [tf.shape(conv)[0], 1, 1, 1])
xx
和yy
的形状现在为(?, 256, 256, 1)
,并且张量可以串联,因为它们的第一维与批处理大小匹配。