Как заменить `keras.layers.merge._Merge` в` tenorflow.keras` - PullRequest
0 голосов
/ 27 сентября 2019

Я хочу создать пользовательский слой слияния, используя tf.keras API.Однако новый API скрывает класс keras.layers.merge._Merge, от которого я хочу наследовать.

Цель этого состоит в том, чтобы создать слой, который может выполнять взвешенную сумму / объединение выходных данных двух разных слоев.Раньше и в keras Python 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])

Теперь я не могу использовать ту же логику при использовании 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])

Производит

AttributeError: module 'tensorflow.python.keras.api._v1.keras.layers' has no attribute 'merge'

Я также пытался наследовать от Layer классавместо этого

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])

, который дает мне слой с выходной формой, равной 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])

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

Но это не решило неопределенность multiple в качестве выходной формы.

1 Ответ

2 голосов
/ 27 сентября 2019

Я немного изменил ваш код, чтобы использовать 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())

model summary

...