如何在`tensorflow.keras`中替换`keras.layers.merge._Merge`

rom*_*zky 4 python keras tensorflow tf.keras

我想使用tf.kerasAPI创建自定义合并层。但是,新 API 隐藏了keras.layers.merge._Merge我想要继承的类。

这样做的目的是创建一个可以对两个不同层的输出执行加权求和/合并的层。之前,在keraspython API(不是包含在 中的那个tensorflow.keras)我可以从keras.layers.merge._Merge类继承,现在不能从tensorflow.keras.

在我可以做到这一点之前

class RandomWeightedAverage(keras.layers.merge._Merge):
    def __init__(self, batch_size):
        super().__init__()
        self.batch_size = batch_size
    def _merge_function(self, inputs):
        alpha = K.random_uniform((self.batch_size, 1, 1, 1))
        return (alpha * inputs[0]) + ((1 - alpha) * inputs[1])
Run Code Online (Sandbox Code Playgroud)

现在我不能使用相同的逻辑,如果使用 tensorflow.keras

class RandomWeightedAverage(tf.keras.layers.merge._Merge):
    def __init__(self, batch_size):
        super().__init__()
        self.batch_size = batch_size
    def _merge_function(self, inputs):
        alpha = K.random_uniform((self.batch_size, 1, 1, 1))
        return (alpha * inputs[0]) + ((1 - alpha) * inputs[1])
Run Code Online (Sandbox Code Playgroud)

生产

AttributeError: module 'tensorflow.python.keras.api._v1.keras.layers' has no attribute 'merge'
Run Code Online (Sandbox Code Playgroud)

我也尝试过从Layer类继承

AttributeError: module 'tensorflow.python.keras.api._v1.keras.layers' has no attribute 'merge'
Run Code Online (Sandbox Code Playgroud)

这给了我一个输出形状等于 的层multiple,而我希望输出形状得到很好的定义。我进一步尝试

class RandomWeightedAverage(tensorflow.keras.layers.Layer):
    def __init__(self, batch_size):
        super().__init__()
        self.batch_size = batch_size
    def call(self, inputs):
        alpha = K.random_uniform((self.batch_size, 1, 1, 1))
        return (alpha * inputs[0]) + ((1 - alpha) * inputs[1])
Run Code Online (Sandbox Code Playgroud)

但这并没有解决multiple作为输出形状的歧义。

小智 5

我稍微修改了您的代码以使用tf.random_uniform而不是K.random_uniform它在 1.13.1 和 1.14.0 上运行良好(完整片段和结果model.summary()如下)。

import tensorflow as tf
print(tf.__version__)


class RandomWeightedAverage(tf.keras.layers.Layer):
    def __init__(self, batch_size):
        super().__init__()
        self.batch_size = batch_size

    def call(self, inputs, **kwargs):
        alpha = tf.random_uniform((self.batch_size, 1, 1, 1))
        return (alpha * inputs[0]) + ((1 - alpha) * inputs[1])

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


x1 = tf.keras.layers.Input((32, 32, 1))
x2 = tf.keras.layers.Input((32, 32, 1))

y = RandomWeightedAverage(4)(inputs=[x1, x2])

model = tf.keras.Model(inputs=[x1, x2], outputs=[y])

print(model.summary())
Run Code Online (Sandbox Code Playgroud)

模型总结

  • 由于没有可训练的权重,这甚至可以通过一个简单的“Lambda”层来完成,仅使用一个“call(inputs)”函数。其中 `alpha = tf.random_uniform(K.shape(inputs)[:1])` 和 `alpha = K.reshape(alpha, (-1,1,1,1))` (2认同)