首页 > 解决方案 > 理解 hub.KerasLayer 的 input_shape 参数

问题描述

迁移学习完成后,可以使用 tf hub 中的模型。像 MobilNetV2 或 Inception。这些模型需要输入,即一定大小的图像。因此,在应用模型之前,必须将图像调整为这个大小。在本教程中,使用以下内容:

feature_extractor_url = "https://tfhub.dev/google/tf2-preview/mobilenet_v2/feature_vector/2" 

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

在此示例中,图像之前已经调整为 224,224。我想知道input_shape=(224,224,3). 在本教程中,预训练模型没有使用 hub-KerasLayer 加载,而是使用

base_model = tf.keras.applications.MobileNetV2(input_shape=IMG_SHAPE,
                                               include_top=False,
                                               weights='imagenet')

IMG_SHAPE 在哪里

IMG_SHAPE = (IMG_SIZE, IMG_SIZE, 3)

img_size 是 160。所以这里的 input_shape 是 input_shape=(160,160,3)。

现在回到:

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

我想知道 input_shape 参数到底告诉我什么或做了什么?所以我这里不需要输入 224,224 对吧?我可以输入另一个尺寸,比如 160,因为我的图像被调整到这个尺寸?所以 MobilNetV2 确实期望 224,224,但是使用此选项我可以指定其他内容吗?因为tf.keras.applications.MobileNetV2我找到了准确解释它的文档:

可选的形状元组,如果您想使用输入图像分辨率不是 (224, 224, 3) 的模型,请指定。它应该正好有 3 个输入通道(224、224、3)。如果您想从 input_tensor 推断 input_shape,也可以省略此选项。如果您选择同时包含 input_tensor 和 input_shape,那么如果它们匹配,则将使用 input_shape,如果形状不匹配,则我们将抛出错误。例如 (160, 160, 3) 将是一个有效值。

因此,当我将图像大小调整为 300,300 并且我想使用 MobileNetV2 时,我可以使用以下代码:

 feature_extractor_url = "https://tfhub.dev/google/tf2-preview/mobilenet_v2/feature_vector/2" 
    
    feature_extractor_layer = hub.KerasLayer(feature_extractor_url,
                                             input_shape=(300,300,3))

还是我必须将大小调整为 224,224 并在此处输入 224,224?

当我检查初始实现时,图像被调整为 299,299,然后使用以下代码:

IMAGE_RES = 299

feature_extractor = hub.KerasLayer(URL,
  input_shape=(IMAGE_RES, IMAGE_RES, 3),
  trainable=False)

是否有必要将其精确到 299?或者我也可以调整到另一个大小,比如 250 并将其作为输入:

   IMAGE_RES = 250

feature_extractor = hub.KerasLayer(URL,
  input_shape=(IMAGE_RES, IMAGE_RES, 3),
  trainable=False)

因此,预训练模型确实期望某个固定大小,并且存在这个 input_shape 参数是为了使其灵活,以防用户想要使用其他大小,对吧?但是,为什么所有这些示例都会调整到模型假设的大小呢?我也可以这样做到另一个尺寸,对吧?因此,在所有示例中,它都表示模型期望这一点,我以这样的方式理解它,因此我们必须调整大小以完全符合模型的期望。但是 input_shape 参数是完全存在的,以使其灵活,这样我就不必调整到模型所期望的大小,而只需调整到我想要的任何大小,并使用 input_shape 参数告诉模型?如上面提到的 160 图像大小的示例。或者这只是可能的,以防我使用tf.keras.applications.MobileNetV2加载预训练模型,但使用时hub.KerasLayer我不能这样做?

标签: tensorflowkerastensorflow-hub

解决方案


这是一个很好的观察。

TLDR , differentInput Shapes可以与参数一起传递,Models但是当我们使用参数时,这是不可能的,当我们使用时。tf.keras.applicationsinclude_top = Falsetf.keras.applicationsinclude_top = TrueModelsTensorflow Hub

详细说明

这个TensorFlow Hub 文档状态

> The height and width dimensions are fixed to the expected size of
> input images. (Future work may remove that restriction for fully
> convolutional modules.)

这就是原因,如果我们传递的Image Shape不是预期形状,它会引发错误,

 Expected these arguments to match one of the following 4 option(s):
    
    Option 1:
      Positional arguments (4 total):
        * TensorSpec(shape=(None, 224, 224, 3), dtype=tf.float32, name='inputs')
        * True
        * False
        * TensorSpec(shape=(), dtype=tf.float32, name='batch_norm_momentum')
      Keyword arguments: {}
    
    Option 2:
      Positional arguments (4 total):
        * TensorSpec(shape=(None, 224, 224, 3), dtype=tf.float32, name='inputs')
        * True
        * True
        * TensorSpec(shape=(), dtype=tf.float32, name='batch_norm_momentum')
      Keyword arguments: {}
    
    Option 3:
      Positional arguments (4 total):
        * TensorSpec(shape=(None, 224, 224, 3), dtype=tf.float32, name='inputs')
        * False
        * True
        * TensorSpec(shape=(), dtype=tf.float32, name='batch_norm_momentum')
      Keyword arguments: {}
    
    Option 4:
      Positional arguments (4 total):
        * TensorSpec(shape=(None, 224, 224, 3), dtype=tf.float32, name='inputs')
        * False
        * False
        * TensorSpec(shape=(), dtype=tf.float32, name='batch_norm_momentum')
      Keyword arguments: {}

类似地,当我们在参数中Input Shape使用Pre-Trained Modelsof时通过 different , (包括顶部的密集层),它会引发错误,tf.keras.applicationsinclude_top = True

ValueError: When setting `include_top=True` and loading `imagenet` 
weights, `input_shape` should be (224, 224, 3).

但是如果我们设置参数的值,include_top = False在使用Pre-Trained Modelsfromtf.keras.applications时,theInput_Shape可以是灵活的,即对于 MobileNetV2,我们可以传递列表中的任何形状,[96, 128, 160, 192, 224]) 并且对于像ResNetor这样的模型VGGNet,我们可以传递任何Input Shape


推荐阅读