【问题标题】:'KerasLayer' object has no attribute 'layers''KerasLayer' 对象没有属性 'layers'
【发布时间】:2020-06-27 06:46:56
【问题描述】:

我正在尝试自定义从 tf hub 获取的模型,但是 无法访问图层并出现以下错误 'KerasLayer' 对象没有属性 'layers'

以我的代码为例:

import tensorflow_hub as hub

from tensorflow.keras import layers

feature_extractor_url = "https://tfhub.dev/tensorflow/efficientnet/lite0/feature-vector/1" 

base_model = hub.KerasLayer(feature_extractor_url,
                                         input_shape=(224,224,3))

base_model.trainable = True


import tensorflow
from tensorflow.keras.models import Model

x =  base_model.layers[-10].output
x = tensorflow.keras.layers.Conv2D(4, (3, 3), padding="same", activation="relu")(x)
x = tensorflow.keras.layers.GlobalMaxPooling2D()(x)
x = tensorflow.keras.layers.Flatten()(x)
outputs = tensorflow.keras.layers.Activation('sigmoid', name="example_output")(x)

model = Model(base_model.input, outputs=outputs)

model.summary()

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-43-0501ec56d6c4> in <module>()
     14 from tensorflow.keras.models import Model
     15 
---> 16 x =  base_model.layers[-10].output
     17 x = tensorflow.keras.layers.Conv2D(4, (3, 3), padding="same", activation="relu")(x)
     18 x = tensorflow.keras.layers.GlobalMaxPooling2D()(x)

AttributeError: 'KerasLayer' object has no attribute 'layers'

我尝试过的: 我使用顺序 api 构建了模型:

model = tf.keras.Sequential([
  base_model,
  layers.Dense(image_data.num_classes)
])

model.summary()

但我仍然无法访问 base_model 中的图层。

如何从 KerasLayer 访问图层?

谢谢!

【问题讨论】:

    标签: tensorflow keras-layer tf.keras tensorflow-hub


    【解决方案1】:

    您可以通过 Hub 模型的权重访问图层。

    遗憾的是,TF 文档中并未直接提及该主题。这是迄今为止我可以挖掘的深度,希望它能够为访问 Hub 上的层提供一些启示。

    TF 2.5.0 和 TF-Hub 0.12.0 已用于以下测试。

    1. KerasLayer 对象中的图层
    >>> import tensorflow_hub as hub
    >>> model = hub.KerasLayer("https://tfhub.dev/deepmind/ganeval-cifar10-convnet/1")
    >>> model
    <tensorflow_hub.keras_layer.KerasLayer object at 0x7f0c79372190>
    >>> len(model.weights)
    57
    >>> model.weights[56]
    <tf.Variable 'cifar10_convnet/linear/b:0' shape=(10,) dtype=float32, numpy=
    array([-0.2734375 , -1.46875   ,  0.484375  ,  1.2265625 ,  0.53515625,
            0.96875   ,  0.3671875 ,  0.02282715, -0.7265625 , -1.078125  ],
          dtype=float32)>
    >>> model.weights[56].name
    'cifar10_convnet/linear/b:0'
    

    注意上面的 weights 变量。 KerasLayer 也有一个 get_weights() 函数。输出差异如下。基本上前者是TF-Variable类型,后者是numpy数组。

    >>> len(model.get_weights())
    57
    >>> model.get_weights()[56]
    array([-0.2734375 , -1.46875   ,  0.484375  ,  1.2265625 ,  0.53515625,
            0.96875   ,  0.3671875 ,  0.02282715, -0.7265625 , -1.078125  ],
          dtype=float32)
    

    例如,要获取所有层的名称,只需运行:

    layers = model.weights
    [ layers[i].name for i in range( len(layers) ) ]
    

    我的输出提示:

    'cifar10_convnet/conv_net_2d/conv_2d_0/w:0',

    'cifar10_convnet/conv_net_2d/conv_2d_0/b:0',

    'cifar10_convnet/conv_net_2d/batch_norm_0/moving_mean:0',

    'cifar10_convnet/conv_net_2d/batch_norm_0/moving_variance:0'

    请注意,权重、偏差、均值、方差等都在输出中作为层单独列出。


    1. AutoTrackable 对象中的图层

    这适用于低级 TF2 API 用户。

    >>> import tensorflow_hub as hub
    >>> model = hub.load("https://tfhub.dev/deepmind/ganeval-cifar10-convnet/1")
    >>> model
    <tensorflow.python.training.tracking.tracking.AutoTrackable object at 0x7f95943ec410>
    >>> len(model.variables)
    57
    >>> model.variables[56]
    <tf.Variable 'cifar10_convnet/linear/b:0' shape=(10,) dtype=float32, numpy=
    array([-0.2734375 , -1.46875   ,  0.484375  ,  1.2265625 ,  0.53515625,
            0.96875   ,  0.3671875 ,  0.02282715, -0.7265625 , -1.078125  ],
          dtype=float32)>
    

    在此 API 中使用“variables”而不是“weights”。

    【讨论】:

    • 我可以单独冻结这些重量吗?
    【解决方案2】:

    我昨天遇到了和你一样的问题,但幸运的是,我找到了两种解决问题的方法。

    1.base_model = tf.keras.applications.MobileNetV2(input_shape=IMG_SHAPE,
                                                   include_top=False,
                                                   weights='imagenet'
                                                   )
    base_model.trainable = False
    global_average_layer = tf.keras.layers.GlobalAveragePooling2D()
    prediction_layer = tf.keras.layers.Dense(59)
    model = tf.keras.Sequential([
      base_model,
      global_average_layer,
      prediction_layer
    ])
    model.summary()
    ....
    fine_tune_at =100
    for layer in base_model.layers[:fine_tune_at]:
      layer.trainable =  False
    

    将“tf.keras.applications”与“.layers”一起使用

    2.参考tensorflow文档:https://tensorflow.google.cn/hub/tf2_saved_model?hl=en

    base_model = hub.KerasLayer(feature_extractor_url,
                                         trainable=True,
                                         input_shape=(224,224,3))
    

    model.summary() 型号:“sequential_2”


    图层(类型)输出形状参数#

    keras_layer_1 (KerasLayer) (无, 1024) 3228864


    dense_2(密集)(无,59)60475

    总参数:3,289,339 可训练参数:3,267,451 不可训练参数:21,888

    希望我的回答对你有帮助

    【讨论】:

    • 这与他的问题无关。您只是将 keras 层放入全局模型并为全局模型执行模型摘要。他想要的是访问模型中心中的层。
    【解决方案3】:

    加载到 hub.KerasLayer 中的 SavedModel 的内部结构是不可访问的。对于这种详细程度,您将不得不转向 EfficientNet 源代码。

    【讨论】:

      猜你喜欢
      • 2019-09-12
      • 1970-01-01
      • 1970-01-01
      • 2012-12-01
      • 2021-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多