Tensorflow 2.0 中 KerasLayer 的 TimeDistributed

Posted

技术标签:

【中文标题】Tensorflow 2.0 中 KerasLayer 的 TimeDistributed【英文标题】:TimeDistributed of a KerasLayer in Tensorflow 2.0 【发布时间】:2020-05-15 03:13:27 【问题描述】:

我正在尝试使用来自 tensorflow-hub 的预训练模型构建 CNN + RNN:

base_model = hub.KerasLayer('https://tfhub.dev/google/imagenet/resnet_v2_50/feature_vector/4', input_shape=(244, 244, 3)
base_model.trainable = False

model = Sequential()
model.add(TimeDistributed(base_model, input_shape=(15, 244, 244, 3)))
model.add(LSTM(512))
model.add(Dense(256, activation='relu'))
model.add(Dense(3, activation='softmax'))

adam = Adam(learning_rate=learning_rate)
model.compile(loss='categorical_crossentropy' , optimizer=adam , metrics=['accuracy'])
model.summary()

这是我得到的:

2020-01-29 16:1

6:37.585888: I tensorflow/core/platform/profile_utils/cpu_utils.cc:94] CPU Frequency: 2494000000 Hz
2020-01-29 16:16:37.586205: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x3b553f0 executing computations on platform Host. Devices:
2020-01-29 16:16:37.586231: I tensorflow/compiler/xla/service/service.cc:175]   StreamExecutor device (0): Host, Default Version
Traceback (most recent call last):
  File "./RNN.py", line 45, in <module>
    model.add(TimeDistributed(base_model, input_shape=(None, 244, 244, 3)))
  File "/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/training/tracking/base.py", line 457, in _method_wrapper
    result = method(self, *args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/keras/engine/sequential.py", line 178, in add
    layer(x)
  File "/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/keras/engine/base_layer.py", line 842, in __call__
    outputs = call_fn(cast_inputs, *args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/keras/layers/wrappers.py", line 256, in call
    output_shape = self.compute_output_shape(input_shape).as_list()
  File "/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/keras/layers/wrappers.py", line 210, in compute_output_shape
    child_output_shape = self.layer.compute_output_shape(child_input_shape)
  File "/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/keras/engine/base_layer.py", line 639, in compute_output_shape
    raise NotImplementedError
NotImplementedError

有什么建议吗? 是否可以将 KerasLayer 转换为 Conv2D、...层?

【问题讨论】:

【参考方案1】:

如果有人遇到这个问题,正如@josef 提到的,问题是compute_output_shape 没有实现。您可以通过指定图层的输出形状来解决这个问题:

extractor = tfhub.KerasLayer("https://tfhub.dev/google/imagenet/mobilenet_v2_100_224/feature_vector/4",
                              input_shape=(IMG_SIZE, IMG_SIZE, CHANNELS),
                              output_shape=(EXTRACTOR_SIZE),
                              trainable=False)
    
model.add(keras.layers.Lambda(lambda x: extractor(x)))

如您所见,我还必须将层包裹在 Lambda 函数内,因为看起来您不能将 KerasLayer 直接包裹在 TimeDistributed 层内。

在代码中,EXTRACTOR_SIZE1280,但它是特定于 MobileNet 的。

这个解决方法对我有用。

【讨论】:

【参考方案2】:

查看我的回答here。抛出错误是因为它无法计算输出形状,您可以通过手动实现compute_output_shape 来解决您的问题。

【讨论】:

【参考方案3】:

您似乎不能使用TimeDistributed 层来解决这个问题。但是,由于您不希望 Resnet 进行训练而只需要输出,因此您可以执行以下操作来避开 TimeDistributed 层。

代替model.add(TimeDistributed(base_model, input_shape=(15, 244, 244, 3))),做

选项 1

# 2048 is the output size
model.add(
    Lambda(
        lambda x: tf.reshape(base_model(tf.reshape(x, [-1, 244, 244,3])),[-1, 15, 2048])
    , input_shape=(15, 244, 244, 3))
)

选项 2

如果您不想过多依赖输出形状(但这会牺牲性能)。

model.add(
    Lambda(
        lambda x: tf.stack([base_model(xx) for xx in tf.unstack(x, axis=1) ], axis=1)
    , input_shape=(15, 244, 244, 3))
)

【讨论】:

我认为 TimeDistributed 和 LSTM 层是 nedded,因为我有 15 帧的序列要分类。我注意到,如果我将 KerasLayer 用于 Tensorflow Hub 的预训练模型,它会给我这个错误,如果我从 tf.keras.applications.ResNet50 定义一个 ResNet50,它不会给我任何错误。有什么区别?我不明白 您的KerasLayer 不需要经过TimeDistributed 层。它所做的只是为每个图像提供一个特征向量,并且它没有经过优化(图层被冻结)。对于 Resnet 部分,无论是否处理数据都没有关系。 而对于不同的tf_hubtf.keras.applications 不同。 tf.keras.applications 中的模型很好地集成到 tf.keras 操作中。而tf_hub 可能不会。 好的,谢谢你的解释。所以你不可能使用预训练的网络将学习转移到 CNN+RNN 卷积层? @NickF_93 不幸的是我没有办法。我遇到了和你一样的错误,无法解决。

以上是关于Tensorflow 2.0 中 KerasLayer 的 TimeDistributed的主要内容,如果未能解决你的问题,请参考以下文章

官方解读:TensorFlow 2.0中即将到来的所有新特性

如何在 Tensorflow-2.0 中绘制 tf.keras 模型?

在基础 Tensorflow 2.0 中运行简单回归

警告:tensorflow:`write_grads` 将在 TensorFlow 2.0 中忽略`TensorBoard` 回调

翻译: Keras 标准化:TensorFlow 2.0 中高级 API 指南

在 Tensorflow 2.0 中使用 GradientTape() 和 jacobian() 时出错