Многоразовый блок в функциональном API Keras - PullRequest
1 голос
/ 21 октября 2019

Цель состоит в том, чтобы создать блок слоев, используя функциональный API Keras, который можно использовать (также с точки зрения синтаксиса) как «обычный» слой Keras. Вот игрушечный пример

from tensorflow.keras import layers as kl

def layer_block(prev_layer, args):
    # some code using 'args'
    layer = kl.Dense(units=prev_layer.shape[1])(prev_layer)
    layer = kl.Dense(units=5)(layer)
    layer = kl.Dense(units=prev_layer.shape[1])(layer)

    return layer

Этот блок вызывается с использованием layer_block(prev_layer, args), что противоречит синтаксису функционального API Keras. Скорее, он должен выглядеть следующим образом: layer_block(args)(prev_layer).

. До сих пор подход заключался в том, чтобы обернуть этот блок другим блоком:

def outer_block(args):
    def layer_block(prev_layer, args):
        # some code using 'args'
        layer = kl.Dense(units=prev_layer.shape[1])(prev_layer)
        layer = kl.Dense(units=5)(layer)
        layer = kl.Dense(units=prev_layer.shape[1])(layer)

        return layer
    return lambda prev_layer: layer_block(prev_layer, args)

Теперь возникает два вопроса:

  1. Есть ли более простой способ добиться этого?
  2. Эффективен ли он таким образом или отрицательно влияет на производительность?

Заранее спасибо!

1 Ответ

2 голосов
/ 21 октября 2019

То, что вы делаете, не влияет на производительность, вы прекрасно создаете слои.

Нет проблем в любом из ваших двух подходов, но если вы хотите, чтобы он работал как фактический слой, преобразуйте его в модель.

Это может не сработать в каждой кераверсия:

class LayerBlock(tensorflow.keras.Model): #not sure if it works in normal keras (without tf)

    def __init__(self):
        super(LayerBlock, self).__init__(outer_units)
        self.layer1 = kl.Dense(units=outer_units)
        self.layer2 = kl.Dense(units=5)
        self.layer3 = kl.Dense(units=outer_units)

    def call(self, inputs):
        x = self.layer1(inputs)
        x = self.layer2(x)
        x = self.layer3(x)
        return x

Этот урок , кажется, предполагает, что вы можете использовать tf.keras.Layer вместо tf.keras.Model, но это звучит странно для меня. Он может работать в активном режиме, но ему не хватает метода build с оператором self.built=True.

...