用于选通操作的 keras 自定义层中的自定义卷积和 none 类型对象

Custom convolutions and none type object in keras custom layer for gating operation

我正在尝试在 keras 中实现门控池化层,这需要首先找到该层的最大池化和平均池化。之后,它使用跨所有深度维度的相同可训练掩码计算区域参数。

例如,如果输入大小为 (batch, 28, 28, 6),则最大和平均池化将 return (batch, 14, 14, 6),步幅为 (2,2)。门操作应该 return (batch, 14, 14, 6) 在掩码(形状 (2,2) )与输入区域的点积之后,然后找到最大和平均池的加权和.但是我无法执行此操作,因为我无法使用 'None' type for batch.

声明输出维度

我有多个线程和各种操作。重塑操作在自定义层中不起作用,将其作为单独的层添加到模型中也会引发错误。我也尝试过很多其他的东西,但我无法处理这个问题。如果能提供帮助,我们将不胜感激。

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)