【问题标题】:Layers to be used after using a pretrained model: When to add GlobalAveragePooling2D()使用预训练模型后要使用的层:何时添加 GlobalAveragePooling2D()
【发布时间】:2020-11-02 21:31:44
【问题描述】:

我正在使用预训练模型对图像进行分类。我的问题是在我的模型中使用预训练模型结构后,我必须添加什么样的层,resp。为什么这两个实现不同。具体来说:

考虑两个示例,一个使用猫和狗数据集:

可以在here 找到一个实现。关键是基础模型:

# Create the base model from the pre-trained model MobileNet V2
base_model = tf.keras.applications.MobileNetV2(input_shape=IMG_SHAPE,
                                               include_top=False,
                                               weights='imagenet')
base_model.trainable = False

被冻结并添加了 GlobalAveragePooling2D(),然后添加了最终的 tf.keras.layers.Dense(1)。所以模型结构如下:

model = tf.keras.Sequential([
  base_model,
  global_average_layer,
  prediction_layer
])

相当于:

model = tf.keras.Sequential([
  base_model,
  tf.keras.layers.GlobalAveragePooling2D()
  tf.keras.layers.Dense(1)
])

所以他们之前不仅添加了最终的dense(1) 层,还添加了GlobalAveragePooling2D() 层。

另一个使用 tf flowers 数据集:

在这个implementation 中是不同的。未添加 GlobalAveragePooling2D()。

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))
feature_extractor_layer.trainable = False

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

其中 image_data.num_classes 为 5 代表不同的花卉分类。所以在这个例子中没有添加 GlobalAveragePooling2D() 层。

我不明白这一点。为什么这不一样?何时添加 GlobalAveragePooling2D() 或不?还有什么更好/我应该怎么做?

我不确定原因是否是因为在一种情况下数据集猫和狗是二元分类,而在另一种情况下是多类分类问题。或者不同之处在于,在一种情况下,tf.keras.applications.MobileNetV2 用于加载 MobileNetV2,而在另一种实现中,hub.KerasLayer 用于获取特征提取器。当我在第一个实现中检查模型时:

可以看到最后一层是relu激活层。

当我检查 feature_extractor 时:

model = tf.keras.Sequential([
  feature_extractor,
  tf.keras.layers.Dense(1)
])

model.summary()

我得到了输出:

所以也许原因也是我不明白tf.keras.applications.MobileNetV2hub.KerasLayer 之间的区别。 hub.KerasLayer 只是给了我特征提取器。我知道这一点,但我仍然认为我没有得到这两种方法之间的区别。

我无法检查 feature_extractor 本身的层。所以 feature_extractor.summary() 或 feature_extractor.layers 不起作用。我如何在这里检查图层?我怎么知道我是否应该添加 GlobalAveragePooling2D?

【问题讨论】:

    标签: python tensorflow keras transfer-learning tensorflow-hub


    【解决方案1】:

    我认为模型输出的差异 “https://tfhub.dev/google/tf2-preview/mobilenet_v2/feature_vector/2”的输出是一维向量*batch_size,你不能应用Conv2D。

    tf.keras.applications.MobileNetV2 的输出可能更复杂,因此您有更多的能力来转换一个。

    【讨论】:

      【解决方案2】:

      假设有一个模型采用 [1, 208, 208, 3] 图像,并且有 6 个带有内核 [2, 2, 2, 2, 2, 7] 的池化层,这将导致图像 [ 1, 1, 1, 2048] 用于最后一个卷积层中的 2048 个过滤器。注意,最后一个池化层如何接受 [1, 7, 7, 2048] 输入

      如果我们放宽输入图像的约束(这通常是目标检测模型的情况),那么在相同大小的池化层集合之后,图像 [1, 104, 208, 3] 将产生 pre-last-pooling 输出[1, 4, 7, 2024] 和 [1, 256, 408, 3] 将产生 [1, 8, 13, 2048]。该映射将具有与原始 [1, 7, 7, 2048] 大致相同的信息量,但原始池化层不会产生具有 [1, 1, 1, N] 的特征列。这就是我们切换到全局池化层的原因。

      简而言之,如果我们对输入图像大小没有严格限制(并且不将图像大小调整为模型中的第一个操作),则全局池化层很重要。

      【讨论】:

      • 不,这是不正确的。在这两种情况下,图像大小都会调整大小。 tf.image.resize(image, (IMG_SIZE, IMG_SIZE)) 和另一个例子中的 target_size=IMAGE_SHAPE。
      猜你喜欢
      • 2018-05-05
      • 2017-08-19
      • 1970-01-01
      • 1970-01-01
      • 2021-10-07
      • 1970-01-01
      • 2021-09-29
      • 2022-08-10
      • 1970-01-01
      相关资源
      最近更新 更多