我正在尝试在keras中实现门控池层,这首先需要找到该层的最大池和平均池。之后,它使用所有深度维度上的相同可训练蒙版计算区域明智参数。
例如,如果输入为大小(batch,28、28、6),则最大池和平均池将以步幅(2,2)返回(batch,14、14、6)。门操作应在蒙版(形状为(2,2))与输入区域的点积之后返回(批处理,14、14、6),然后找到最大池和平均池的加权和。但是我无法执行此操作,因为无法为批次声明“ None”类型的输出尺寸。
我有多个线程和各种操作。整形操作不适用于自定义层,将其添加为模型中的单独层也会引发错误。我也尝试了许多其他事情,但无法解决此问题。一些帮助将不胜感激。
class Gated_pooling(tf.keras.layers.Layer):
def __init__(self, **kwargs):
super(Gated_pooling, self).__init__(**kwargs)
def build(self, input_shape):
self.batch, self.row, self.col, self.channel = input_shape.as_list()
self.output_size = self.row//2
self.mask = self.add_weight(name='mask', shape=(2,2,1,1),
initializer='truncated_normal',
trainable=True
)
self.maxpool = tf.keras.layers.MaxPooling2D(pool_size=(2, 2), strides=(2,2), padding='VALID')
self.avgpool = tf.keras.layers.AveragePooling2D(pool_size=(2, 2), strides=(2,2), padding='VALID')
super(Gated_pooling, self).build(input_shape)
def call(self, x):
x1 = self.maxpool(x)
x2 = self.maxpool(x)
xs = tf.zeros(x1.shape)
i=0
for c in tf.split(x, self.channel, 3):
xs[:, :, i] = tf.nn.conv2d(input=c, filters=self.mask, strides=[2,2,1,1], padding='VALID')
i+=1
#z = tf.math.sigmoid(tf.reshape(xs, [self.batch, self.output_size, self.output_size, self.channel]))
z = tf.math.sigmoid(xs)
output = tf.add(tf.multiply(z, x1), tf.multiply((1-z), x2))
#return tf.reshape(output, [self.batch, self.output_size, self.output_size, self.channel])
return output
这似乎起作用...
class Gated_pooling(tf.keras.layers.Layer):
def __init__(self, **kwargs):
super(Gated_pooling, self).__init__(**kwargs)
self.mask = self.add_weight(name='mask', shape=(2,2,1,1),
initializer='truncated_normal',
trainable=True
)
self.maxpool = tf.keras.layers.MaxPooling2D(pool_size=(2, 2), strides=(2,2), padding='VALID')
self.avgpool = tf.keras.layers.AveragePooling2D(pool_size=(2, 2), strides=(2,2), padding='VALID')
def call(self, x):
self.batch, self.row, self.col, self.channel = x.shape
self.output_size = self.row//2
x1 = self.maxpool(x)
x2 = self.maxpool(x)
xs = []
for c in tf.split(x, self.channel, 3):
xs.append(tf.nn.conv2d(c, filters=self.mask, strides=[2,2], padding='VALID'))
xs = tf.concat(xs, axis=-1)
z = tf.math.sigmoid(xs)
output = tf.add(tf.multiply(z, x1), tf.multiply((1-z), x2))
return output
用法:
X = np.random.uniform(0,1, (32,10,10,3)).astype('float32')
gp = Gated_pooling()
gp(X)