2017-08-01 5 views
0

Je voudrais être en mesure de plusieurs couches ensemble, mais avant de spécifier l'entrée, quelque chose comme ce qui suit:Comment chaîne/composer des couches dans keras 2 API fonctionnelle sans spécifier entrée (ou la forme d'entrée)

# conv is just a layer, no application 
conv = Conv2D(64, (3,3), activation='relu', padding='same', name='conv') 
# this doesn't work: 
bn = BatchNormalization()(conv) 

Notez que je ne veux pas spécifier l'entrée ni sa forme si cela peut être évité, je veux l'utiliser comme couche partagée pour plusieurs entrées plus tard.

Y a-t-il un moyen de faire cela? Ce qui précède donne l'erreur suivante:

>>> conv = Conv2D(64, (3,3), activation='relu', padding='same', name='conv') 
>>> bn = BatchNormalization()(conv) 
Traceback (most recent call last): 
    File "/home/mitchus/anaconda3/envs/tf/lib/python3.6/site-packages/keras/engine/topology.py", line 419, in assert_input_compatibility 
    K.is_keras_tensor(x) 
    File "/home/mitchus/anaconda3/envs/tf/lib/python3.6/site-packages/keras/backend/tensorflow_backend.py", line 393, in is_keras_tensor 
    raise ValueError('Unexpectedly found an instance of type `' + str(type(x)) + '`. ' 
ValueError: Unexpectedly found an instance of type `<class 'keras.layers.convolutional.Conv2D'>`. Expected a symbolic tensor instance. 

During handling of the above exception, another exception occurred: 

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/home/mitchus/anaconda3/envs/tf/lib/python3.6/site-packages/keras/engine/topology.py", line 552, in __call__ 
    self.assert_input_compatibility(inputs) 
    File "/home/mitchus/anaconda3/envs/tf/lib/python3.6/site-packages/keras/engine/topology.py", line 425, in assert_input_compatibility 
    str(inputs) + '. All inputs to the layer ' 
ValueError: Layer batch_normalization_4 was called with an input that isn't a symbolic tensor. Received type: <class 'keras.layers.convolutional.Conv2D'>. Full input: [<keras.layers.convolutional.Conv2D object at 0x7f3f6e54b748>]. All inputs to the layer should be tensors. 

Saisissant la sortie de la couche conv ne fait pas l'affaire soit:

>>> bn = BatchNormalization()(conv.output) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/home/mitchus/anaconda3/envs/tf/lib/python3.6/site-packages/keras/engine/topology.py", line 941, in output 
    ' has no inbound nodes.') 
AttributeError: Layer conv has no inbound nodes. 

Répondre

1

Essayez ceci:

def create_shared_layers(): 
    layers = [ 
     Conv2D(64, (3,3), activation='relu', padding='same', name='conv'), 
     BatchNormalization() 
    ] 
    def shared_layers(x): 
     for layer in layers: 
      x = layer(x) 
     return x 
    return shared_layers 

Plus tard, vous pouvez faire quelque chose comme:

shared_layers = create_shared_layers() 
... 
h1 = shared_layers(x1) 
h2 = shared_layers(x2) 
+0

Solution de contournement astucieuse! :) Je me demande s'il existe un moyen plus "idiomatique", il semble que cela devrait être une fonctionnalité naturelle. – mitchus