首页 > 解决方案 > 将除自定义 Keras 层中的最大值之外的所有内容清零

问题描述

我目前正在创建一个没有可训练参数的自定义 keras 层

该层的输入具有形状(批量大小、序列长度、特征)。这与一维全局最大池化层的输入基本相同。

我试图用这个自定义层做的是在不降低维度的情况下执行一维全局最大池化。(只想将每个特征的非最大条目归零)除此之外,我希望输出具有一个额外的维度,以便可以将其传递给 2D 卷积层。

所以这个层的输出应该是形状(批量大小,序列长度,特征,1)其中一维全局最大池是通过将所有不是最大值的东西归零来执行的

这是Layer的骨架

class GlobalMaxPoolZeroOutNonMax(Layer):

    def __init__(self, **kwargs):
        super(GlobalMaxPoolZeroOutNonMax, self).__init__(**kwargs)
        self.input_spec = InputSpec(ndim=3)
        self.data_format = K.normalize_data_format('channels_last')

    def compute_output_shape(self, input_shape):
        return (input_shape[0], input_shape[1], input_shape[2], 1)

    def call(self, inputs):
        # THIS IS WHERE I NEED HELP to zero out the non max and add a dimension
        raise NotImplemented

    def get_config(self):
        config = {'data_format': self.data_format}
        base_config = super(GlobalMaxPoolZeroOutNonMax, self).get_config()
        return dict(list(base_config.items()) + list(config.items()))

感谢您的时间!

标签: tensorflowkeraskeras-layer

解决方案


您不必使用子类化。您可以通过以下方式实现此目的。您必须记住的一件事是,这将保留所有最大值(不仅仅是一个最大值 - 但在真正的神经网络层中极不可能有两个最大值)。

from tensorflow.keras import layers, models
import tensorflow as tf
width = 20
n_channels = 3
inp = layers.Input(shape=(width, n_channels))
out = layers.Lambda(lambda x: tf.expand_dims(tf.cast(tf.equal(x, tf.reduce_max(x)), tf.float32)*x,axis=-1))(inp)

model = models.Model(inputs=inp, outputs=out)
model.summary()

测试

x = np.zeros(shape=(10, width, n_channels))
x[0, 2, 2] = 2.0

y = model.predict(x)
print(y.shape)
print(y)

结果

(10, 20, 3, 1)

[[[[0.]
   [0.]
   [0.]]

  [[0.]
   [0.]
   [0.]]

  [[0.]
   [0.]
   [2.]]

  [[0.]
   [0.]
   [0.]]

  ...

  [[0.]
   [0.]
   [0.]]]]

推荐阅读