【问题标题】:How to chain/compose layers in keras 2 functional API without specifying input (or input shape)如何在不指定输入(或输入形状)的情况下在 keras 2 功能 API 中链接/组合图层
【发布时间】:2018-01-08 10:03:37
【问题描述】:

我希望能够将多个层放在一起,但在指定输入之前,如下所示:

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

请注意,如果可以避免,我不想指定输入或其形状,我想稍后将其用作多个输入的共享层。

有没有办法做到这一点?上面给出了以下错误:

>>> 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.

获取 conv 层的输出也不能解决问题:

>>> 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.

【问题讨论】:

    标签: python-3.x keras keras-layer keras-2


    【解决方案1】:

    您也可以将tk.Sequential 视为层

    import tensorflow.keras as tk
    import tensorflow as tf
    
    _layer1 = tk.layers.Conv2D(
        64, (3,3), activation='relu', 
        padding='same', name='conv'
    )
    _layer2 = tk.layers.BatchNormalization()
    
    _composed_layer = tk.Sequential(
        [_layer1, _layer2]
    )
    
    _some_input = tf.random.normal((100,20,33,2))
    _out = _composed_layer(_some_input)
    

    【讨论】:

      【解决方案2】:

      如何使用 Lambda 层。

      import functools
      from typing import List
      
      from tensorflow import keras
      
      
      def compose_layers(layers: List[keras.layers.Layer], **kargs) -> keras.layers.Layer:
        return keras.layers.Lambda(
          lambda x: functools.reduce(lambda tensor, layer: layer(tensor), layers, x),
          **kargs,
        )
      
      

      那么你可以调用compose_layers方法来获取合成。

      layers = [
        Conv2D(64, (3,3), activation='relu', padding='same', name='conv'),
        BatchNormalization()
      ]
      
      composed_layers = compose_layers(layers, name='composed_layers')
      

      【讨论】:

        【解决方案3】:

        试试这个:

        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
        

        稍后,您可以执行以下操作:

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

        【讨论】:

        • 聪明的解决方法! :) 我想知道是否有更“惯用”的方式,这似乎应该是一个自然的功能。
        猜你喜欢
        • 2021-11-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-04
        • 2019-05-07
        • 1970-01-01
        • 2021-05-20
        • 2018-02-27
        相关资源
        最近更新 更多