政安晨的个人主页:政安晨
欢迎 👍点赞✍评论⭐收藏
收录专栏: TensorFlow与Keras机器学习实战
希望政安晨的博客能够对您有所裨益,如有不足之处,欢迎在评论区提出指正!
本文目标:
使用 EfficientNet 和在图像网络上预先训练好的权重进行斯坦福狗分类。
简介:什么是 EfficientNet
EfficientNet 由 Tan 和 Le 于 2019 年首次提出,是效率最高的模型之一(即推理所需的 FLOPS 最低),在图像网和普通图像分类迁移学习任务中都达到了最先进的精度。
最小的基础模型与 MnasNet 相似,后者用更小的模型达到了接近一流水平。
通过引入一种启发式方法来扩展模型,EfficientNet 提供了一个模型系列(B0 到 B7),在各种规模上很好地结合了效率和准确性。这种缩放启发式方法(复合缩放,详见谭和乐,2019 年)允许以效率为导向的基础模型(B0)超越各种规模的模型,同时避免对超参数进行广泛的网格搜索。
该模型应用了各种增强方案和半监督学习方法,以进一步提高模型的图像网络性能。模型的这些扩展可以通过更新权重来使用,而无需改变模型架构。
效能网络的 B0 至 B7 变体
根据论文,人们可能会认为 EfficientNet 是一个连续的模型族,可以通过任意选择论文公式(3)中的缩放因子来创建。然而,分辨率、深度和宽度的选择也受到很多因素的限制:
分辨率:不能被 8、16 等整除的分辨率会导致某些层的边界附近出现零填充,从而浪费计算资源。这尤其适用于模型的较小变体,因此 B0 和 B1 的输入分辨率分别选为 224 和 240。
深度和宽度:高效网络的构件要求通道大小为 8 的倍数。
资源限制:当深度和宽度仍可增加时,内存限制可能会对分辨率造成瓶颈。在这种情况下,增加深度和/或宽度但保持分辨率仍可提高性能。
因此,每个 EfficientNet 模型变体的深度、宽度和分辨率都是人工挑选的,并已证明能产生良好效果,尽管它们可能与复合缩放公式有很大偏差。因此,keras 实现(详见下文)只提供这 8 个模型(B0 至 B7),而不允许任意选择宽度/深度/分辨率参数。
EfficientNet 的 Keras 实现
自 Keras v2.3 起,EfficientNet B0 至 B7 的实现已随 Keras 一同发布。要使用 EfficientNetB0 对 ImageNet 中的 1000 类图像进行分类,请运行如下:
from tensorflow.keras.applications import EfficientNetB0
model = EfficientNetB0(weights='imagenet')
该模型需要输入形状为 (224, 224, 3) 的图像,输入数据的范围应为 [0, 255]。归一化是模型的一部分。
由于在 ImageNet 上训练 EfficientNet 需要耗费大量资源和若干技术,而模型架构本身并不包含这些资源和技术。因此,Keras 实现默认加载通过 AutoAugment 训练获得的预训练权重。
对于 B0 到 B7 基本模型,输入形状是不同的。下面列出了每种型号的预期输入形状:
当模型用于迁移学习时,Keras 实现提供了移除顶层的选项:
model = EfficientNetB0(include_top=False, weights='imagenet')
此选项不包括最后的密集层,该层将倒数第二层的 1280 个特征转化为 1000 个 ImageNet 类别的预测。用自定义层代替顶层,可以在迁移学习工作流中使用 EfficientNet 作为特征提取器。
模型构造函数中另一个值得注意的参数是 drop_connect_rate,用于控制随机深度的丢失率。该参数可在微调中切换额外的正则化,但不会影响加载权重。例如,如果需要更强的正则化,可以尝试:
model = EfficientNetB0(weights='imagenet', drop_connect_rate=0.4)
默认值为 0.2。
示例:斯坦福狗的 EfficientNetB0。
效能网络能够胜任各种图像分类任务。这使它成为迁移学习的良好模型。作为端到端的示例,我们将展示在斯坦福 Dogs 数据集上使用预训练的 EfficientNetB0 的情况。
import numpy as np
import tensorflow_datasets as tfds
import tensorflow as tf # For tf.data
import matplotlib.pyplot as plt
import keras
from keras import layers
from keras.applications import EfficientNetB0
# IMG_SIZE is determined by EfficientNet model choice
IMG_SIZE = 224
BATCH_SIZE = 64
加载数据
这里我们从 tensorflow_datasets(以下简称 TFDS)中加载数据。斯坦福狗数据集在 TFDS 中以 stanford_dogs 的形式提供。该数据集包含 20,580 张属于 120 个狗品种类别的图像(12,000 张用于训练,8,580 张用于测试)。
只需更改下面的数据集名称,您也可以在 TFDS 中的其他数据集(如 cifar10、cifar100、food101 等)上使用本笔记本。当图像远小于 EfficientNet 输入的大小时,我们可以简单地对输入图像进行升采样。Tan 和 Le(2019 年)的研究表明,即使输入图像仍然很小,提高分辨率后的迁移学习效果也会更好。
dataset_name = "stanford_dogs"
(ds_train, ds_test), ds_info = tfds.load(
dataset_name, split=["train", "test"], with_info=True, as_supervised=True
)
NUM_CLASSES = ds_info.features["label"].num_classes
当数据集包含不同大小的图像时,我们需要将它们调整为共享大小。斯坦福 Dogs 数据集仅包含大小至少为 200x200 像素的图像。在此,我们将图像大小调整为效能网络所需的输入大小。
size = (IMG_SIZE, IMG_SIZE)
ds_train = ds_train.map(lambda image, label: (tf.image.resize(image, size), label))
ds_test = ds_test.map(lambda image, label: (tf.image.resize(image, size), label))
数据可视化
以下代码显示了前 9 幅图像及其标签。
def format_label(label):
string_label = label_info.int2str(label)
return string_label.split("-")[1]
label_info = ds_info.features["label"]
for i, (image, label) in enumerate(ds_train.take(9)):
ax = plt.subplot(3, 3, i + 1)
plt.imshow(image.numpy().astype("uint8"))
plt.title("{}".format(format_label(label)))
plt.axis("off")
数据扩增
我们可以使用预处理层应用程序接口进行图像增强。
img_augmentation_layers = [
layers.RandomRotation(factor=0.15),
layers.RandomTranslation(height_factor=0.1, width_factor=0.1),
layers.RandomFlip(),
layers.RandomContrast(factor=0.1),
]
def img_augmentation(images):
for layer in img_augmentation_layers:
images = layer(images)
return images
这个序列模型对象既可以作为我们稍后构建的模型的一部分,也可以作为在将数据输入模型之前对其进行预处理的函数。将其作为函数使用可以轻松实现增强图像的可视化。在这里,我们绘制了给定图形的 9 个增强结果示例。
for image, label in ds_train.take(1):
for i in range(9):
ax = plt.subplot(3, 3, i + 1)
aug_img = img_augmentation(np.expand_dims(image.numpy(), axis=0))
aug_img = np.array(aug_img)
plt.imshow(aug_img[0].astype("uint8"))
plt.title("{}".format(format_label(label)))
plt.axis("off")
准备输入
确认输入数据和增强功能正常运行后,我们就准备数据集进行训练。将输入数据调整为统一的 IMG_SIZE。将标签放入单击(又称分类)编码。对数据集进行批处理。
注意:在某些情况下,预取和 AUTOTUNE 可能会提高性能,但这取决于所使用的环境和特定数据集。
# One-hot / categorical encoding
def input_preprocess_train(image, label):
image = img_augmentation(image)
label = tf.one_hot(label, NUM_CLASSES)
return image, label
def input_preprocess_test(image, label):
label = tf.one_hot(label, NUM_CLASSES)
return image, label
ds_train = ds_train.map(input_preprocess_train, num_parallel_calls=tf.data.AUTOTUNE)
ds_train = ds_train.batch(batch_size=BATCH_SIZE, drop_remainder=True)
ds_train = ds_train.prefetch(tf.data.AUTOTUNE)
ds_test = ds_test.map(input_preprocess_test, num_parallel_calls=tf.data.AUTOTUNE)
ds_test = ds_test.batch(batch_size=BATCH_SIZE, drop_remainder=True)
从零开始训练模型
我们构建了一个有 120 个输出类的 EfficientNetB0,并从头开始初始化:
注意:准确率的提高将非常缓慢,并可能出现过拟合。
model = EfficientNetB0(
include_top=True,
weights=None,
classes=NUM_CLASSES,
input_shape=(IMG_SIZE, IMG_SIZE, 3),
)
model.compile(optimizer="adam", loss="categorical_crossentropy", metrics=["accuracy"])
model.summary()
epochs = 40 # @param {type: "slider", min:10, max:100}
hist = model.fit(ds_train, epochs=epochs, validation_data=ds_test)
Model: "efficientnetb0"
┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┓ ┃ Layer (type) ┃ Output Shape ┃ Param # ┃ Connected to ┃ ┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━┩ │ input_layer │ (None, 224, 224, │ 0 │ - │ │ (InputLayer) │ 3) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ rescaling │ (None, 224, 224, │ 0 │ input_layer[0][0] │ │ (Rescaling) │ 3) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ normalization │ (None, 224, 224, │ 7 │ rescaling[0][0] │ │ (Normalization) │ 3) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ stem_conv_pad │ (None, 225, 225, │ 0 │ normalization[0][0] │ │ (ZeroPadding2D) │ 3) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ stem_conv (Conv2D) │ (None, 112, 112, │ 864 │ stem_conv_pad[0][0] │ │ │ 32) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ stem_bn │ (None, 112, 112, │ 128 │ stem_conv[0][0] │ │ (BatchNormalizatio… │ 32) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ stem_activation │ (None, 112, 112, │ 0 │ stem_bn[0][0] │ │ (Activation) │ 32) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block1a_dwconv │ (None, 112, 112, │ 288 │ stem_activation[0][… │ │ (DepthwiseConv2D) │ 32) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block1a_bn │ (None, 112, 112, │ 128 │ block1a_dwconv[0][0] │ │ (BatchNormalizatio… │ 32) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block1a_activation │ (None, 112, 112, │ 0 │ block1a_bn[0][0] │ │ (Activation) │ 32) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block1a_se_squeeze │ (None, 32) │ 0 │ block1a_activation[… │ │ (GlobalAveragePool… │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block1a_se_reshape │ (None, 1, 1, 32) │ 0 │ block1a_se_squeeze[… │ │ (Reshape) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block1a_se_reduce │ (None, 1, 1, 8) │ 264 │ block1a_se_reshape[… │ │ (Conv2D) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block1a_se_expand │ (None, 1, 1, 32) │ 288 │ block1a_se_reduce[0… │ │ (Conv2D) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block1a_se_excite │ (None, 112, 112, │ 0 │ block1a_activation[… │ │ (Multiply) │ 32) │ │ block1a_se_expand[0… │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block1a_project_co… │ (None, 112, 112, │ 512 │ block1a_se_excite[0… │ │ (Conv2D) │ 16) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block1a_project_bn │ (None, 112, 112, │ 64 │ block1a_project_con… │ │ (BatchNormalizatio… │ 16) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block2a_expand_conv │ (None, 112, 112, │ 1,536 │ block1a_project_bn[… │ │ (Conv2D) │ 96) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block2a_expand_bn │ (None, 112, 112, │ 384 │ block2a_expand_conv… │ │ (BatchNormalizatio… │ 96) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block2a_expand_act… │ (None, 112, 112, │ 0 │ block2a_expand_bn[0… │ │ (Activation) │ 96) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block2a_dwconv_pad │ (None, 113, 113, │ 0 │ block2a_expand_acti… │ │ (ZeroPadding2D) │ 96) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block2a_dwconv │ (None, 56, 56, │ 864 │ block2a_dwconv_pad[… │ │ (DepthwiseConv2D) │ 96) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block2a_bn │ (None, 56, 56, │ 384 │ block2a_dwconv[0][0] │ │ (BatchNormalizatio… │ 96) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block2a_activation │ (None, 56, 56, │ 0 │ block2a_bn[0][0] │ │ (Activation) │ 96) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block2a_se_squeeze │ (None, 96) │ 0 │ block2a_activation[… │ │ (GlobalAveragePool… │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block2a_se_reshape │ (None, 1, 1, 96) │ 0 │ block2a_se_squeeze[… │ │ (Reshape) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block2a_se_reduce │ (None, 1, 1, 4) │ 388 │ block2a_se_reshape[… │ │ (Conv2D) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block2a_se_expand │ (None, 1, 1, 96) │ 480 │ block2a_se_reduce[0… │ │ (Conv2D) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block2a_se_excite │ (None, 56, 56, │ 0 │ block2a_activation[… │ │ (Multiply) │ 96) │ │ block2a_se_expand[0… │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block2a_project_co… │ (None, 56, 56, │ 2,304 │ block2a_se_excite[0… │ │ (Conv2D) │ 24) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block2a_project_bn │ (None, 56, 56, │ 96 │ block2a_project_con… │ │ (BatchNormalizatio… │ 24) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block2b_expand_conv │ (None, 56, 56, │ 3,456 │ block2a_project_bn[… │ │ (Conv2D) │ 144) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block2b_expand_bn │ (None, 56, 56, │ 576 │ block2b_expand_conv… │ │ (BatchNormalizatio… │ 144) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block2b_expand_act… │ (None, 56, 56, │ 0 │ block2b_expand_bn[0… │ │ (Activation) │ 144) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block2b_dwconv │ (None, 56, 56, │ 1,296 │ block2b_expand_acti… │ │ (DepthwiseConv2D) │ 144) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block2b_bn │ (None, 56, 56, │ 576 │ block2b_dwconv[0][0] │ │ (BatchNormalizatio… │ 144) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block2b_activation │ (None, 56, 56, │ 0 │ block2b_bn[0][0] │ │ (Activation) │ 144) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block2b_se_squeeze │ (None, 144) │ 0 │ block2b_activation[… │ │ (GlobalAveragePool… │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block2b_se_reshape │ (None, 1, 1, 144) │ 0 │ block2b_se_squeeze[… │ │ (Reshape) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block2b_se_reduce │ (None, 1, 1, 6) │ 870 │ block2b_se_reshape[… │ │ (Conv2D) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block2b_se_expand │ (None, 1, 1, 144) │ 1,008 │ block2b_se_reduce[0… │ │ (Conv2D) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block2b_se_excite │ (None, 56, 56, │ 0 │ block2b_activation[… │ │ (Multiply) │ 144) │ │ block2b_se_expand[0… │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block2b_project_co… │ (None, 56, 56, │ 3,456 │ block2b_se_excite[0… │ │ (Conv2D) │ 24) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block2b_project_bn │ (None, 56, 56, │ 96 │ block2b_project_con… │ │ (BatchNormalizatio… │ 24) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block2b_drop │ (None, 56, 56, │ 0 │ block2b_project_bn[… │ │ (Dropout) │ 24) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block2b_add (Add) │ (None, 56, 56, │ 0 │ block2b_drop[0][0], │ │ │ 24) │ │ block2a_project_bn[… │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block3a_expand_conv │ (None, 56, 56, │ 3,456 │ block2b_add[0][0] │ │ (Conv2D) │ 144) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block3a_expand_bn │ (None, 56, 56, │ 576 │ block3a_expand_conv… │ │ (BatchNormalizatio… │ 144) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block3a_expand_act… │ (None, 56, 56, │ 0 │ block3a_expand_bn[0… │ │ (Activation) │ 144) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block3a_dwconv_pad │ (None, 59, 59, │ 0 │ block3a_expand_acti… │ │ (ZeroPadding2D) │ 144) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block3a_dwconv │ (None, 28, 28, │ 3,600 │ block3a_dwconv_pad[… │ │ (DepthwiseConv2D) │ 144) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block3a_bn │ (None, 28, 28, │ 576 │ block3a_dwconv[0][0] │ │ (BatchNormalizatio… │ 144) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block3a_activation │ (None, 28, 28, │ 0 │ block3a_bn[0][0] │ │ (Activation) │ 144) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block3a_se_squeeze │ (None, 144) │ 0 │ block3a_activation[… │ │ (GlobalAveragePool… │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block3a_se_reshape │ (None, 1, 1, 144) │ 0 │ block3a_se_squeeze[… │ │ (Reshape) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block3a_se_reduce │ (None, 1, 1, 6) │ 870 │ block3a_se_reshape[… │ │ (Conv2D) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block3a_se_expand │ (None, 1, 1, 144) │ 1,008 │ block3a_se_reduce[0… │ │ (Conv2D) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block3a_se_excite │ (None, 28, 28, │ 0 │ block3a_activation[… │ │ (Multiply) │ 144) │ │ block3a_se_expand[0… │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block3a_project_co… │ (None, 28, 28, │ 5,760 │ block3a_se_excite[0… │ │ (Conv2D) │ 40) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block3a_project_bn │ (None, 28, 28, │ 160 │ block3a_project_con… │ │ (BatchNormalizatio… │ 40) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block3b_expand_conv │ (None, 28, 28, │ 9,600 │ block3a_project_bn[… │ │ (Conv2D) │ 240) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block3b_expand_bn │ (None, 28, 28, │ 960 │ block3b_expand_conv… │ │ (BatchNormalizatio… │ 240) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block3b_expand_act… │ (None, 28, 28, │ 0 │ block3b_expand_bn[0… │ │ (Activation) │ 240) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block3b_dwconv │ (None, 28, 28, │ 6,000 │ block3b_expand_acti… │ │ (DepthwiseConv2D) │ 240) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block3b_bn │ (None, 28, 28, │ 960 │ block3b_dwconv[0][0] │ │ (BatchNormalizatio… │ 240) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block3b_activation │ (None, 28, 28, │ 0 │ block3b_bn[0][0] │ │ (Activation) │ 240) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block3b_se_squeeze │ (None, 240) │ 0 │ block3b_activation[… │ │ (GlobalAveragePool… │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block3b_se_reshape │ (None, 1, 1, 240) │ 0 │ block3b_se_squeeze[… │ │ (Reshape) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block3b_se_reduce │ (None, 1, 1, 10) │ 2,410 │ block3b_se_reshape[… │ │ (Conv2D) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block3b_se_expand │ (None, 1, 1, 240) │ 2,640 │ block3b_se_reduce[0… │ │ (Conv2D) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block3b_se_excite │ (None, 28, 28, │ 0 │ block3b_activation[… │ │ (Multiply) │ 240) │ │ block3b_se_expand[0… │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block3b_project_co… │ (None, 28, 28, │ 9,600 │ block3b_se_excite[0… │ │ (Conv2D) │ 40) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block3b_project_bn │ (None, 28, 28, │ 160 │ block3b_project_con… │ │ (BatchNormalizatio… │ 40) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block3b_drop │ (None, 28, 28, │ 0 │ block3b_project_bn[… │ │ (Dropout) │ 40) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block3b_add (Add) │ (None, 28, 28, │ 0 │ block3b_drop[0][0], │ │ │ 40) │ │ block3a_project_bn[… │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4a_expand_conv │ (None, 28, 28, │ 9,600 │ block3b_add[0][0] │ │ (Conv2D) │ 240) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4a_expand_bn │ (None, 28, 28, │ 960 │ block4a_expand_conv… │ │ (BatchNormalizatio… │ 240) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4a_expand_act… │ (None, 28, 28, │ 0 │ block4a_expand_bn[0… │ │ (Activation) │ 240) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4a_dwconv_pad │ (None, 29, 29, │ 0 │ block4a_expand_acti… │ │ (ZeroPadding2D) │ 240) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4a_dwconv │ (None, 14, 14, │ 2,160 │ block4a_dwconv_pad[… │ │ (DepthwiseConv2D) │ 240) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4a_bn │ (None, 14, 14, │ 960 │ block4a_dwconv[0][0] │ │ (BatchNormalizatio… │ 240) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4a_activation │ (None, 14, 14, │ 0 │ block4a_bn[0][0] │ │ (Activation) │ 240) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4a_se_squeeze │ (None, 240) │ 0 │ block4a_activation[… │ │ (GlobalAveragePool… │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4a_se_reshape │ (None, 1, 1, 240) │ 0 │ block4a_se_squeeze[… │ │ (Reshape) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4a_se_reduce │ (None, 1, 1, 10) │ 2,410 │ block4a_se_reshape[… │ │ (Conv2D) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4a_se_expand │ (None, 1, 1, 240) │ 2,640 │ block4a_se_reduce[0… │ │ (Conv2D) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4a_se_excite │ (None, 14, 14, │ 0 │ block4a_activation[… │ │ (Multiply) │ 240) │ │ block4a_se_expand[0… │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4a_project_co… │ (None, 14, 14, │ 19,200 │ block4a_se_excite[0… │ │ (Conv2D) │ 80) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4a_project_bn │ (None, 14, 14, │ 320 │ block4a_project_con… │ │ (BatchNormalizatio… │ 80) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4b_expand_conv │ (None, 14, 14, │ 38,400 │ block4a_project_bn[… │ │ (Conv2D) │ 480) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4b_expand_bn │ (None, 14, 14, │ 1,920 │ block4b_expand_conv… │ │ (BatchNormalizatio… │ 480) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4b_expand_act… │ (None, 14, 14, │ 0 │ block4b_expand_bn[0… │ │ (Activation) │ 480) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4b_dwconv │ (None, 14, 14, │ 4,320 │ block4b_expand_acti… │ │ (DepthwiseConv2D) │ 480) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4b_bn │ (None, 14, 14, │ 1,920 │ block4b_dwconv[0][0] │ │ (BatchNormalizatio… │ 480) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4b_activation │ (None, 14, 14, │ 0 │ block4b_bn[0][0] │ │ (Activation) │ 480) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4b_se_squeeze │ (None, 480) │ 0 │ block4b_activation[… │ │ (GlobalAveragePool… │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4b_se_reshape │ (None, 1, 1, 480) │ 0 │ block4b_se_squeeze[… │ │ (Reshape) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4b_se_reduce │ (None, 1, 1, 20) │ 9,620 │ block4b_se_reshape[… │ │ (Conv2D) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4b_se_expand │ (None, 1, 1, 480) │ 10,080 │ block4b_se_reduce[0… │ │ (Conv2D) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4b_se_excite │ (None, 14, 14, │ 0 │ block4b_activation[… │ │ (Multiply) │ 480) │ │ block4b_se_expand[0… │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4b_project_co… │ (None, 14, 14, │ 38,400 │ block4b_se_excite[0… │ │ (Conv2D) │ 80) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4b_project_bn │ (None, 14, 14, │ 320 │ block4b_project_con… │ │ (BatchNormalizatio… │ 80) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4b_drop │ (None, 14, 14, │ 0 │ block4b_project_bn[… │ │ (Dropout) │ 80) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4b_add (Add) │ (None, 14, 14, │ 0 │ block4b_drop[0][0], │ │ │ 80) │ │ block4a_project_bn[… │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4c_expand_conv │ (None, 14, 14, │ 38,400 │ block4b_add[0][0] │ │ (Conv2D) │ 480) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4c_expand_bn │ (None, 14, 14, │ 1,920 │ block4c_expand_conv… │ │ (BatchNormalizatio… │ 480) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4c_expand_act… │ (None, 14, 14, │ 0 │ block4c_expand_bn[0… │ │ (Activation) │ 480) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4c_dwconv │ (None, 14, 14, │ 4,320 │ block4c_expand_acti… │ │ (DepthwiseConv2D) │ 480) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4c_bn │ (None, 14, 14, │ 1,920 │ block4c_dwconv[0][0] │ │ (BatchNormalizatio… │ 480) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4c_activation │ (None, 14, 14, │ 0 │ block4c_bn[0][0] │ │ (Activation) │ 480) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4c_se_squeeze │ (None, 480) │ 0 │ block4c_activation[… │ │ (GlobalAveragePool… │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4c_se_reshape │ (None, 1, 1, 480) │ 0 │ block4c_se_squeeze[… │ │ (Reshape) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4c_se_reduce │ (None, 1, 1, 20) │ 9,620 │ block4c_se_reshape[… │ │ (Conv2D) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4c_se_expand │ (None, 1, 1, 480) │ 10,080 │ block4c_se_reduce[0… │ │ (Conv2D) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4c_se_excite │ (None, 14, 14, │ 0 │ block4c_activation[… │ │ (Multiply) │ 480) │ │ block4c_se_expand[0… │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4c_project_co… │ (None, 14, 14, │ 38,400 │ block4c_se_excite[0… │ │ (Conv2D) │ 80) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4c_project_bn │ (None, 14, 14, │ 320 │ block4c_project_con… │ │ (BatchNormalizatio… │ 80) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4c_drop │ (None, 14, 14, │ 0 │ block4c_project_bn[… │ │ (Dropout) │ 80) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block4c_add (Add) │ (None, 14, 14, │ 0 │ block4c_drop[0][0], │ │ │ 80) │ │ block4b_add[0][0] │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5a_expand_conv │ (None, 14, 14, │ 38,400 │ block4c_add[0][0] │ │ (Conv2D) │ 480) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5a_expand_bn │ (None, 14, 14, │ 1,920 │ block5a_expand_conv… │ │ (BatchNormalizatio… │ 480) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5a_expand_act… │ (None, 14, 14, │ 0 │ block5a_expand_bn[0… │ │ (Activation) │ 480) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5a_dwconv │ (None, 14, 14, │ 12,000 │ block5a_expand_acti… │ │ (DepthwiseConv2D) │ 480) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5a_bn │ (None, 14, 14, │ 1,920 │ block5a_dwconv[0][0] │ │ (BatchNormalizatio… │ 480) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5a_activation │ (None, 14, 14, │ 0 │ block5a_bn[0][0] │ │ (Activation) │ 480) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5a_se_squeeze │ (None, 480) │ 0 │ block5a_activation[… │ │ (GlobalAveragePool… │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5a_se_reshape │ (None, 1, 1, 480) │ 0 │ block5a_se_squeeze[… │ │ (Reshape) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5a_se_reduce │ (None, 1, 1, 20) │ 9,620 │ block5a_se_reshape[… │ │ (Conv2D) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5a_se_expand │ (None, 1, 1, 480) │ 10,080 │ block5a_se_reduce[0… │ │ (Conv2D) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5a_se_excite │ (None, 14, 14, │ 0 │ block5a_activation[… │ │ (Multiply) │ 480) │ │ block5a_se_expand[0… │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5a_project_co… │ (None, 14, 14, │ 53,760 │ block5a_se_excite[0… │ │ (Conv2D) │ 112) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5a_project_bn │ (None, 14, 14, │ 448 │ block5a_project_con… │ │ (BatchNormalizatio… │ 112) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5b_expand_conv │ (None, 14, 14, │ 75,264 │ block5a_project_bn[… │ │ (Conv2D) │ 672) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5b_expand_bn │ (None, 14, 14, │ 2,688 │ block5b_expand_conv… │ │ (BatchNormalizatio… │ 672) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5b_expand_act… │ (None, 14, 14, │ 0 │ block5b_expand_bn[0… │ │ (Activation) │ 672) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5b_dwconv │ (None, 14, 14, │ 16,800 │ block5b_expand_acti… │ │ (DepthwiseConv2D) │ 672) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5b_bn │ (None, 14, 14, │ 2,688 │ block5b_dwconv[0][0] │ │ (BatchNormalizatio… │ 672) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5b_activation │ (None, 14, 14, │ 0 │ block5b_bn[0][0] │ │ (Activation) │ 672) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5b_se_squeeze │ (None, 672) │ 0 │ block5b_activation[… │ │ (GlobalAveragePool… │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5b_se_reshape │ (None, 1, 1, 672) │ 0 │ block5b_se_squeeze[… │ │ (Reshape) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5b_se_reduce │ (None, 1, 1, 28) │ 18,844 │ block5b_se_reshape[… │ │ (Conv2D) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5b_se_expand │ (None, 1, 1, 672) │ 19,488 │ block5b_se_reduce[0… │ │ (Conv2D) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5b_se_excite │ (None, 14, 14, │ 0 │ block5b_activation[… │ │ (Multiply) │ 672) │ │ block5b_se_expand[0… │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5b_project_co… │ (None, 14, 14, │ 75,264 │ block5b_se_excite[0… │ │ (Conv2D) │ 112) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5b_project_bn │ (None, 14, 14, │ 448 │ block5b_project_con… │ │ (BatchNormalizatio… │ 112) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5b_drop │ (None, 14, 14, │ 0 │ block5b_project_bn[… │ │ (Dropout) │ 112) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5b_add (Add) │ (None, 14, 14, │ 0 │ block5b_drop[0][0], │ │ │ 112) │ │ block5a_project_bn[… │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5c_expand_conv │ (None, 14, 14, │ 75,264 │ block5b_add[0][0] │ │ (Conv2D) │ 672) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5c_expand_bn │ (None, 14, 14, │ 2,688 │ block5c_expand_conv… │ │ (BatchNormalizatio… │ 672) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5c_expand_act… │ (None, 14, 14, │ 0 │ block5c_expand_bn[0… │ │ (Activation) │ 672) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5c_dwconv │ (None, 14, 14, │ 16,800 │ block5c_expand_acti… │ │ (DepthwiseConv2D) │ 672) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5c_bn │ (None, 14, 14, │ 2,688 │ block5c_dwconv[0][0] │ │ (BatchNormalizatio… │ 672) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5c_activation │ (None, 14, 14, │ 0 │ block5c_bn[0][0] │ │ (Activation) │ 672) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5c_se_squeeze │ (None, 672) │ 0 │ block5c_activation[… │ │ (GlobalAveragePool… │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5c_se_reshape │ (None, 1, 1, 672) │ 0 │ block5c_se_squeeze[… │ │ (Reshape) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5c_se_reduce │ (None, 1, 1, 28) │ 18,844 │ block5c_se_reshape[… │ │ (Conv2D) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5c_se_expand │ (None, 1, 1, 672) │ 19,488 │ block5c_se_reduce[0… │ │ (Conv2D) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5c_se_excite │ (None, 14, 14, │ 0 │ block5c_activation[… │ │ (Multiply) │ 672) │ │ block5c_se_expand[0… │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5c_project_co… │ (None, 14, 14, │ 75,264 │ block5c_se_excite[0… │ │ (Conv2D) │ 112) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5c_project_bn │ (None, 14, 14, │ 448 │ block5c_project_con… │ │ (BatchNormalizatio… │ 112) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5c_drop │ (None, 14, 14, │ 0 │ block5c_project_bn[… │ │ (Dropout) │ 112) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block5c_add (Add) │ (None, 14, 14, │ 0 │ block5c_drop[0][0], │ │ │ 112) │ │ block5b_add[0][0] │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6a_expand_conv │ (None, 14, 14, │ 75,264 │ block5c_add[0][0] │ │ (Conv2D) │ 672) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6a_expand_bn │ (None, 14, 14, │ 2,688 │ block6a_expand_conv… │ │ (BatchNormalizatio… │ 672) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6a_expand_act… │ (None, 14, 14, │ 0 │ block6a_expand_bn[0… │ │ (Activation) │ 672) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6a_dwconv_pad │ (None, 17, 17, │ 0 │ block6a_expand_acti… │ │ (ZeroPadding2D) │ 672) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6a_dwconv │ (None, 7, 7, 672) │ 16,800 │ block6a_dwconv_pad[… │ │ (DepthwiseConv2D) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6a_bn │ (None, 7, 7, 672) │ 2,688 │ block6a_dwconv[0][0] │ │ (BatchNormalizatio… │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6a_activation │ (None, 7, 7, 672) │ 0 │ block6a_bn[0][0] │ │ (Activation) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6a_se_squeeze │ (None, 672) │ 0 │ block6a_activation[… │ │ (GlobalAveragePool… │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6a_se_reshape │ (None, 1, 1, 672) │ 0 │ block6a_se_squeeze[… │ │ (Reshape) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6a_se_reduce │ (None, 1, 1, 28) │ 18,844 │ block6a_se_reshape[… │ │ (Conv2D) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6a_se_expand │ (None, 1, 1, 672) │ 19,488 │ block6a_se_reduce[0… │ │ (Conv2D) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6a_se_excite │ (None, 7, 7, 672) │ 0 │ block6a_activation[… │ │ (Multiply) │ │ │ block6a_se_expand[0… │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6a_project_co… │ (None, 7, 7, 192) │ 129,024 │ block6a_se_excite[0… │ │ (Conv2D) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6a_project_bn │ (None, 7, 7, 192) │ 768 │ block6a_project_con… │ │ (BatchNormalizatio… │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6b_expand_conv │ (None, 7, 7, │ 221,184 │ block6a_project_bn[… │ │ (Conv2D) │ 1152) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6b_expand_bn │ (None, 7, 7, │ 4,608 │ block6b_expand_conv… │ │ (BatchNormalizatio… │ 1152) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6b_expand_act… │ (None, 7, 7, │ 0 │ block6b_expand_bn[0… │ │ (Activation) │ 1152) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6b_dwconv │ (None, 7, 7, │ 28,800 │ block6b_expand_acti… │ │ (DepthwiseConv2D) │ 1152) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6b_bn │ (None, 7, 7, │ 4,608 │ block6b_dwconv[0][0] │ │ (BatchNormalizatio… │ 1152) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6b_activation │ (None, 7, 7, │ 0 │ block6b_bn[0][0] │ │ (Activation) │ 1152) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6b_se_squeeze │ (None, 1152) │ 0 │ block6b_activation[… │ │ (GlobalAveragePool… │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6b_se_reshape │ (None, 1, 1, │ 0 │ block6b_se_squeeze[… │ │ (Reshape) │ 1152) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6b_se_reduce │ (None, 1, 1, 48) │ 55,344 │ block6b_se_reshape[… │ │ (Conv2D) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6b_se_expand │ (None, 1, 1, │ 56,448 │ block6b_se_reduce[0… │ │ (Conv2D) │ 1152) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6b_se_excite │ (None, 7, 7, │ 0 │ block6b_activation[… │ │ (Multiply) │ 1152) │ │ block6b_se_expand[0… │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6b_project_co… │ (None, 7, 7, 192) │ 221,184 │ block6b_se_excite[0… │ │ (Conv2D) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6b_project_bn │ (None, 7, 7, 192) │ 768 │ block6b_project_con… │ │ (BatchNormalizatio… │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6b_drop │ (None, 7, 7, 192) │ 0 │ block6b_project_bn[… │ │ (Dropout) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6b_add (Add) │ (None, 7, 7, 192) │ 0 │ block6b_drop[0][0], │ │ │ │ │ block6a_project_bn[… │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6c_expand_conv │ (None, 7, 7, │ 221,184 │ block6b_add[0][0] │ │ (Conv2D) │ 1152) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6c_expand_bn │ (None, 7, 7, │ 4,608 │ block6c_expand_conv… │ │ (BatchNormalizatio… │ 1152) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6c_expand_act… │ (None, 7, 7, │ 0 │ block6c_expand_bn[0… │ │ (Activation) │ 1152) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6c_dwconv │ (None, 7, 7, │ 28,800 │ block6c_expand_acti… │ │ (DepthwiseConv2D) │ 1152) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6c_bn │ (None, 7, 7, │ 4,608 │ block6c_dwconv[0][0] │ │ (BatchNormalizatio… │ 1152) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6c_activation │ (None, 7, 7, │ 0 │ block6c_bn[0][0] │ │ (Activation) │ 1152) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6c_se_squeeze │ (None, 1152) │ 0 │ block6c_activation[… │ │ (GlobalAveragePool… │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6c_se_reshape │ (None, 1, 1, │ 0 │ block6c_se_squeeze[… │ │ (Reshape) │ 1152) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6c_se_reduce │ (None, 1, 1, 48) │ 55,344 │ block6c_se_reshape[… │ │ (Conv2D) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6c_se_expand │ (None, 1, 1, │ 56,448 │ block6c_se_reduce[0… │ │ (Conv2D) │ 1152) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6c_se_excite │ (None, 7, 7, │ 0 │ block6c_activation[… │ │ (Multiply) │ 1152) │ │ block6c_se_expand[0… │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6c_project_co… │ (None, 7, 7, 192) │ 221,184 │ block6c_se_excite[0… │ │ (Conv2D) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6c_project_bn │ (None, 7, 7, 192) │ 768 │ block6c_project_con… │ │ (BatchNormalizatio… │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6c_drop │ (None, 7, 7, 192) │ 0 │ block6c_project_bn[… │ │ (Dropout) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6c_add (Add) │ (None, 7, 7, 192) │ 0 │ block6c_drop[0][0], │ │ │ │ │ block6b_add[0][0] │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6d_expand_conv │ (None, 7, 7, │ 221,184 │ block6c_add[0][0] │ │ (Conv2D) │ 1152) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6d_expand_bn │ (None, 7, 7, │ 4,608 │ block6d_expand_conv… │ │ (BatchNormalizatio… │ 1152) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6d_expand_act… │ (None, 7, 7, │ 0 │ block6d_expand_bn[0… │ │ (Activation) │ 1152) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6d_dwconv │ (None, 7, 7, │ 28,800 │ block6d_expand_acti… │ │ (DepthwiseConv2D) │ 1152) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6d_bn │ (None, 7, 7, │ 4,608 │ block6d_dwconv[0][0] │ │ (BatchNormalizatio… │ 1152) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6d_activation │ (None, 7, 7, │ 0 │ block6d_bn[0][0] │ │ (Activation) │ 1152) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6d_se_squeeze │ (None, 1152) │ 0 │ block6d_activation[… │ │ (GlobalAveragePool… │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6d_se_reshape │ (None, 1, 1, │ 0 │ block6d_se_squeeze[… │ │ (Reshape) │ 1152) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6d_se_reduce │ (None, 1, 1, 48) │ 55,344 │ block6d_se_reshape[… │ │ (Conv2D) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6d_se_expand │ (None, 1, 1, │ 56,448 │ block6d_se_reduce[0… │ │ (Conv2D) │ 1152) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6d_se_excite │ (None, 7, 7, │ 0 │ block6d_activation[… │ │ (Multiply) │ 1152) │ │ block6d_se_expand[0… │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6d_project_co… │ (None, 7, 7, 192) │ 221,184 │ block6d_se_excite[0… │ │ (Conv2D) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6d_project_bn │ (None, 7, 7, 192) │ 768 │ block6d_project_con… │ │ (BatchNormalizatio… │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6d_drop │ (None, 7, 7, 192) │ 0 │ block6d_project_bn[… │ │ (Dropout) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block6d_add (Add) │ (None, 7, 7, 192) │ 0 │ block6d_drop[0][0], │ │ │ │ │ block6c_add[0][0] │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block7a_expand_conv │ (None, 7, 7, │ 221,184 │ block6d_add[0][0] │ │ (Conv2D) │ 1152) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block7a_expand_bn │ (None, 7, 7, │ 4,608 │ block7a_expand_conv… │ │ (BatchNormalizatio… │ 1152) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block7a_expand_act… │ (None, 7, 7, │ 0 │ block7a_expand_bn[0… │ │ (Activation) │ 1152) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block7a_dwconv │ (None, 7, 7, │ 10,368 │ block7a_expand_acti… │ │ (DepthwiseConv2D) │ 1152) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block7a_bn │ (None, 7, 7, │ 4,608 │ block7a_dwconv[0][0] │ │ (BatchNormalizatio… │ 1152) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block7a_activation │ (None, 7, 7, │ 0 │ block7a_bn[0][0] │ │ (Activation) │ 1152) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block7a_se_squeeze │ (None, 1152) │ 0 │ block7a_activation[… │ │ (GlobalAveragePool… │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block7a_se_reshape │ (None, 1, 1, │ 0 │ block7a_se_squeeze[… │ │ (Reshape) │ 1152) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block7a_se_reduce │ (None, 1, 1, 48) │ 55,344 │ block7a_se_reshape[… │ │ (Conv2D) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block7a_se_expand │ (None, 1, 1, │ 56,448 │ block7a_se_reduce[0… │ │ (Conv2D) │ 1152) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block7a_se_excite │ (None, 7, 7, │ 0 │ block7a_activation[… │ │ (Multiply) │ 1152) │ │ block7a_se_expand[0… │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block7a_project_co… │ (None, 7, 7, 320) │ 368,640 │ block7a_se_excite[0… │ │ (Conv2D) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ block7a_project_bn │ (None, 7, 7, 320) │ 1,280 │ block7a_project_con… │ │ (BatchNormalizatio… │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ top_conv (Conv2D) │ (None, 7, 7, │ 409,600 │ block7a_project_bn[… │ │ │ 1280) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ top_bn │ (None, 7, 7, │ 5,120 │ top_conv[0][0] │ │ (BatchNormalizatio… │ 1280) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ top_activation │ (None, 7, 7, │ 0 │ top_bn[0][0] │ │ (Activation) │ 1280) │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ avg_pool │ (None, 1280) │ 0 │ top_activation[0][0] │ │ (GlobalAveragePool… │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ top_dropout │ (None, 1280) │ 0 │ avg_pool[0][0] │ │ (Dropout) │ │ │ │ ├─────────────────────┼───────────────────┼─────────┼──────────────────────┤ │ predictions (Dense) │ (None, 120) │ 153,720 │ top_dropout[0][0] │ └─────────────────────┴───────────────────┴─────────┴──────────────────────┘
Total params: 4,203,291 (16.03 MB) Trainable params: 4,161,268 (15.87 MB) Non-trainable params: 42,023 (164.16 KB)
Epoch 1/40 1/187 [37m━━━━━━━━━━━━━━━━━━━━ 5:30:13 107s/step - accuracy: 0.0000e+00 - loss: 5.1065 WARNING: All log messages before absl::InitializeLog() is called are written to STDERR I0000 00:00:1700241724.682725 1549299 device_compiler.h:187] Compiled cluster using XLA! This line is logged at most once for the lifetime of the process. 187/187 ━━━━━━━━━━━━━━━━━━━━ 200s 501ms/step - accuracy: 0.0097 - loss: 5.0567 - val_accuracy: 0.0100 - val_loss: 4.9278 Epoch 2/40 187/187 ━━━━━━━━━━━━━━━━━━━━ 95s 507ms/step - accuracy: 0.0214 - loss: 4.6918 - val_accuracy: 0.0141 - val_loss: 5.5380 Epoch 3/40 187/187 ━━━━━━━━━━━━━━━━━━━━ 89s 474ms/step - accuracy: 0.0298 - loss: 4.4749 - val_accuracy: 0.0375 - val_loss: 4.4576 Epoch 4/40 187/187 ━━━━━━━━━━━━━━━━━━━━ 90s 479ms/step - accuracy: 0.0423 - loss: 4.3206 - val_accuracy: 0.0391 - val_loss: 4.9898 Epoch 5/40 187/187 ━━━━━━━━━━━━━━━━━━━━ 89s 473ms/step - accuracy: 0.0458 - loss: 4.2312 - val_accuracy: 0.0416 - val_loss: 4.3210 Epoch 6/40 187/187 ━━━━━━━━━━━━━━━━━━━━ 141s 470ms/step - accuracy: 0.0579 - loss: 4.1162 - val_accuracy: 0.0540 - val_loss: 4.3371 Epoch 7/40 187/187 ━━━━━━━━━━━━━━━━━━━━ 89s 476ms/step - accuracy: 0.0679 - loss: 4.0150 - val_accuracy: 0.0786 - val_loss: 3.9759 Epoch 8/40 187/187 ━━━━━━━━━━━━━━━━━━━━ 89s 477ms/step - accuracy: 0.0828 - loss: 3.9147 - val_accuracy: 0.0651 - val_loss: 4.1641 Epoch 9/40 187/187 ━━━━━━━━━━━━━━━━━━━━ 142s 475ms/step - accuracy: 0.0932 - loss: 3.8297 - val_accuracy: 0.0928 - val_loss: 3.8985 Epoch 10/40 187/187 ━━━━━━━━━━━━━━━━━━━━ 88s 472ms/step - accuracy: 0.1092 - loss: 3.7321 - val_accuracy: 0.0946 - val_loss: 3.8618 Epoch 11/40 187/187 ━━━━━━━━━━━━━━━━━━━━ 89s 476ms/step - accuracy: 0.1245 - loss: 3.6451 - val_accuracy: 0.0880 - val_loss: 3.9584 Epoch 12/40 187/187 ━━━━━━━━━━━━━━━━━━━━ 92s 493ms/step - accuracy: 0.1457 - loss: 3.5514 - val_accuracy: 0.1096 - val_loss: 3.8184 Epoch 13/40 187/187 ━━━━━━━━━━━━━━━━━━━━ 88s 471ms/step - accuracy: 0.1606 - loss: 3.4654 - val_accuracy: 0.1118 - val_loss: 3.8059 Epoch 14/40 187/187 ━━━━━━━━━━━━━━━━━━━━ 87s 464ms/step - accuracy: 0.1660 - loss: 3.3826 - val_accuracy: 0.1472 - val_loss: 3.5726 Epoch 15/40 187/187 ━━━━━━━━━━━━━━━━━━━━ 146s 485ms/step - accuracy: 0.1815 - loss: 3.2935 - val_accuracy: 0.1154 - val_loss: 3.8134 Epoch 16/40 187/187 ━━━━━━━━━━━━━━━━━━━━ 87s 466ms/step - accuracy: 0.1942 - loss: 3.2218 - val_accuracy: 0.1540 - val_loss: 3.5051 Epoch 17/40 187/187 ━━━━━━━━━━━━━━━━━━━━ 88s 471ms/step - accuracy: 0.2131 - loss: 3.1427 - val_accuracy: 0.1381 - val_loss: 3.7206 Epoch 18/40 187/187 ━━━━━━━━━━━━━━━━━━━━ 87s 467ms/step - accuracy: 0.2264 - loss: 3.0461 - val_accuracy: 0.1707 - val_loss: 3.4122 Epoch 19/40 187/187 ━━━━━━━━━━━━━━━━━━━━ 88s 470ms/step - accuracy: 0.2401 - loss: 2.9821 - val_accuracy: 0.1515 - val_loss: 3.6481 Epoch 20/40 187/187 ━━━━━━━━━━━━━━━━━━━━ 88s 469ms/step - accuracy: 0.2613 - loss: 2.8815 - val_accuracy: 0.1783 - val_loss: 3.4767 Epoch 21/40 187/187 ━━━━━━━━━━━━━━━━━━━━ 91s 485ms/step - accuracy: 0.2741 - loss: 2.8102 - val_accuracy: 0.1927 - val_loss: 3.3183 Epoch 22/40 187/187 ━━━━━━━━━━━━━━━━━━━━ 90s 477ms/step - accuracy: 0.2892 - loss: 2.7408 - val_accuracy: 0.1859 - val_loss: 3.4887 Epoch 23/40 187/187 ━━━━━━━━━━━━━━━━━━━━ 91s 485ms/step - accuracy: 0.3093 - loss: 2.6526 - val_accuracy: 0.1924 - val_loss: 3.4622 Epoch 24/40 187/187 ━━━━━━━━━━━━━━━━━━━━ 92s 491ms/step - accuracy: 0.3201 - loss: 2.5750 - val_accuracy: 0.2253 - val_loss: 3.1873 Epoch 25/40 187/187 ━━━━━━━━━━━━━━━━━━━━ 95s 508ms/step - accuracy: 0.3280 - loss: 2.5150 - val_accuracy: 0.2148 - val_loss: 3.3391 Epoch 26/40 187/187 ━━━━━━━━━━━━━━━━━━━━ 92s 490ms/step - accuracy: 0.3465 - loss: 2.4402 - val_accuracy: 0.2270 - val_loss: 3.2679 Epoch 27/40 187/187 ━━━━━━━━━━━━━━━━━━━━ 93s 494ms/step - accuracy: 0.3735 - loss: 2.3199 - val_accuracy: 0.2080 - val_loss: 3.5687 Epoch 28/40 187/187 ━━━━━━━━━━━━━━━━━━━━ 89s 476ms/step - accuracy: 0.3837 - loss: 2.2645 - val_accuracy: 0.2374 - val_loss: 3.3592 Epoch 29/40 187/187 ━━━━━━━━━━━━━━━━━━━━ 142s 474ms/step - accuracy: 0.3962 - loss: 2.2110 - val_accuracy: 0.2008 - val_loss: 3.6071 Epoch 30/40 187/187 ━━━━━━━━━━━━━━━━━━━━ 87s 466ms/step - accuracy: 0.4175 - loss: 2.1086 - val_accuracy: 0.2302 - val_loss: 3.4161 Epoch 31/40 187/187 ━━━━━━━━━━━━━━━━━━━━ 87s 465ms/step - accuracy: 0.4359 - loss: 2.0610 - val_accuracy: 0.2231 - val_loss: 3.5957 Epoch 32/40 187/187 ━━━━━━━━━━━━━━━━━━━━ 148s 498ms/step - accuracy: 0.4463 - loss: 1.9866 - val_accuracy: 0.2234 - val_loss: 3.7263 Epoch 33/40 187/187 ━━━━━━━━━━━━━━━━━━━━ 92s 489ms/step - accuracy: 0.4613 - loss: 1.8821 - val_accuracy: 0.2239 - val_loss: 3.6929 Epoch 34/40 187/187 ━━━━━━━━━━━━━━━━━━━━ 139s 475ms/step - accuracy: 0.4925 - loss: 1.7858 - val_accuracy: 0.2238 - val_loss: 3.8351 Epoch 35/40 187/187 ━━━━━━━━━━━━━━━━━━━━ 91s 485ms/step - accuracy: 0.5105 - loss: 1.7074 - val_accuracy: 0.1930 - val_loss: 4.1941 Epoch 36/40 187/187 ━━━━━━━━━━━━━━━━━━━━ 140s 474ms/step - accuracy: 0.5334 - loss: 1.6256 - val_accuracy: 0.2098 - val_loss: 4.1464 Epoch 37/40 187/187 ━━━━━━━━━━━━━━━━━━━━ 87s 464ms/step - accuracy: 0.5504 - loss: 1.5603 - val_accuracy: 0.2306 - val_loss: 4.0215 Epoch 38/40 187/187 ━━━━━━━━━━━━━━━━━━━━ 90s 480ms/step - accuracy: 0.5736 - loss: 1.4419 - val_accuracy: 0.2240 - val_loss: 4.1604 Epoch 39/40 187/187 ━━━━━━━━━━━━━━━━━━━━ 91s 486ms/step - accuracy: 0.6025 - loss: 1.3612 - val_accuracy: 0.2344 - val_loss: 4.0505 Epoch 40/40 187/187 ━━━━━━━━━━━━━━━━━━━━ 89s 474ms/step - accuracy: 0.6199 - loss: 1.2889 - val_accuracy: 0.2151 - val_loss: 4.3660
训练模型的速度相对较快。这听起来似乎很容易,只需在任何数据集上从头开始训练 EfficientNet 即可。但是,在较小的数据集(尤其是像 CIFAR-100 这样分辨率较低的数据集)上训练 EfficientNet 会面临过度拟合的巨大挑战。
因此,从头开始训练需要非常谨慎地选择超参数,而且很难找到合适的正则化。这对资源的要求也更高。绘制训练和验证精度图可以清楚地看出,验证精度停滞在一个较低的值上。
import matplotlib.pyplot as plt
def plot_hist(hist):
plt.plot(hist.history["accuracy"])
plt.plot(hist.history["val_accuracy"])
plt.title("model accuracy")
plt.ylabel("accuracy")
plt.xlabel("epoch")
plt.legend(["train", "validation"], loc="upper left")
plt.show()
plot_hist(hist)
从预先训练的权重进行迁移学习
在这里,我们使用预先训练好的 ImageNet 权重对模型进行初始化,然后在我们自己的数据集上对其进行微调。
def build_model(num_classes):
inputs = layers.Input(shape=(IMG_SIZE, IMG_SIZE, 3))
model = EfficientNetB0(include_top=False, input_tensor=inputs, weights="imagenet")
# Freeze the pretrained weights
model.trainable = False
# Rebuild top
x = layers.GlobalAveragePooling2D(name="avg_pool")(model.output)
x = layers.BatchNormalization()(x)
top_dropout_rate = 0.2
x = layers.Dropout(top_dropout_rate, name="top_dropout")(x)
outputs = layers.Dense(num_classes, activation="softmax", name="pred")(x)
# Compile
model = keras.Model(inputs, outputs, name="EfficientNet")
optimizer = keras.optimizers.Adam(learning_rate=1e-2)
model.compile(
optimizer=optimizer, loss="categorical_crossentropy", metrics=["accuracy"]
)
return model
迁移学习的第一步是冻结所有层,只训练顶层。在这一步中,可以使用相对较大的学习率(1e-2)。需要注意的是,验证精度和损失通常会好于训练精度和损失。这是因为正则化很强,只会抑制训练时的指标。
需要注意的是,根据学习率的选择,收敛可能需要多达 50 个历元。如果不应用图像增强层,验证准确率可能只能达到 ~60%。
Epoch 1/25
187/187 ━━━━━━━━━━━━━━━━━━━━ 108s 432ms/step - accuracy: 0.2654 - loss: 4.3710 - val_accuracy: 0.6888 - val_loss: 1.0875
Epoch 2/25
187/187 ━━━━━━━━━━━━━━━━━━━━ 119s 412ms/step - accuracy: 0.4863 - loss: 2.0996 - val_accuracy: 0.7282 - val_loss: 0.9072
Epoch 3/25
187/187 ━━━━━━━━━━━━━━━━━━━━ 78s 416ms/step - accuracy: 0.5422 - loss: 1.7120 - val_accuracy: 0.7411 - val_loss: 0.8574
Epoch 4/25
187/187 ━━━━━━━━━━━━━━━━━━━━ 77s 412ms/step - accuracy: 0.5509 - loss: 1.6472 - val_accuracy: 0.7451 - val_loss: 0.8457
Epoch 5/25
187/187 ━━━━━━━━━━━━━━━━━━━━ 81s 431ms/step - accuracy: 0.5744 - loss: 1.5373 - val_accuracy: 0.7424 - val_loss: 0.8649
Epoch 6/25
187/187 ━━━━━━━━━━━━━━━━━━━━ 78s 417ms/step - accuracy: 0.5715 - loss: 1.5595 - val_accuracy: 0.7374 - val_loss: 0.8736
Epoch 7/25
187/187 ━━━━━━━━━━━━━━━━━━━━ 81s 432ms/step - accuracy: 0.5802 - loss: 1.5045 - val_accuracy: 0.7430 - val_loss: 0.8675
Epoch 8/25
187/187 ━━━━━━━━━━━━━━━━━━━━ 77s 411ms/step - accuracy: 0.5839 - loss: 1.4972 - val_accuracy: 0.7392 - val_loss: 0.8647
Epoch 9/25
187/187 ━━━━━━━━━━━━━━━━━━━━ 77s 411ms/step - accuracy: 0.5929 - loss: 1.4699 - val_accuracy: 0.7508 - val_loss: 0.8634
Epoch 10/25
187/187 ━━━━━━━━━━━━━━━━━━━━ 82s 437ms/step - accuracy: 0.6040 - loss: 1.4442 - val_accuracy: 0.7520 - val_loss: 0.8480
Epoch 11/25
187/187 ━━━━━━━━━━━━━━━━━━━━ 78s 416ms/step - accuracy: 0.5972 - loss: 1.4626 - val_accuracy: 0.7379 - val_loss: 0.8879
Epoch 12/25
187/187 ━━━━━━━━━━━━━━━━━━━━ 79s 421ms/step - accuracy: 0.5965 - loss: 1.4700 - val_accuracy: 0.7383 - val_loss: 0.9409
Epoch 13/25
187/187 ━━━━━━━━━━━━━━━━━━━━ 82s 420ms/step - accuracy: 0.6034 - loss: 1.4533 - val_accuracy: 0.7474 - val_loss: 0.8922
Epoch 14/25
187/187 ━━━━━━━━━━━━━━━━━━━━ 81s 435ms/step - accuracy: 0.6053 - loss: 1.4170 - val_accuracy: 0.7416 - val_loss: 0.9119
Epoch 15/25
187/187 ━━━━━━━━━━━━━━━━━━━━ 77s 411ms/step - accuracy: 0.6059 - loss: 1.4125 - val_accuracy: 0.7406 - val_loss: 0.9205
Epoch 16/25
187/187 ━━━━━━━━━━━━━━━━━━━━ 82s 438ms/step - accuracy: 0.5979 - loss: 1.4554 - val_accuracy: 0.7392 - val_loss: 0.9120
Epoch 17/25
187/187 ━━━━━━━━━━━━━━━━━━━━ 77s 411ms/step - accuracy: 0.6081 - loss: 1.4089 - val_accuracy: 0.7423 - val_loss: 0.9305
Epoch 18/25
187/187 ━━━━━━━━━━━━━━━━━━━━ 82s 436ms/step - accuracy: 0.6041 - loss: 1.4390 - val_accuracy: 0.7380 - val_loss: 0.9644
Epoch 19/25
187/187 ━━━━━━━━━━━━━━━━━━━━ 79s 417ms/step - accuracy: 0.6018 - loss: 1.4324 - val_accuracy: 0.7439 - val_loss: 0.9129
Epoch 20/25
187/187 ━━━━━━━━━━━━━━━━━━━━ 81s 430ms/step - accuracy: 0.6057 - loss: 1.4342 - val_accuracy: 0.7305 - val_loss: 0.9463
Epoch 21/25
187/187 ━━━━━━━━━━━━━━━━━━━━ 77s 410ms/step - accuracy: 0.6209 - loss: 1.3824 - val_accuracy: 0.7410 - val_loss: 0.9503
Epoch 22/25
187/187 ━━━━━━━━━━━━━━━━━━━━ 78s 419ms/step - accuracy: 0.6170 - loss: 1.4246 - val_accuracy: 0.7336 - val_loss: 0.9606
Epoch 23/25
187/187 ━━━━━━━━━━━━━━━━━━━━ 85s 455ms/step - accuracy: 0.6153 - loss: 1.4009 - val_accuracy: 0.7334 - val_loss: 0.9520
Epoch 24/25
187/187 ━━━━━━━━━━━━━━━━━━━━ 82s 438ms/step - accuracy: 0.6051 - loss: 1.4343 - val_accuracy: 0.7435 - val_loss: 0.9403
Epoch 25/25
187/187 ━━━━━━━━━━━━━━━━━━━━ 138s 416ms/step - accuracy: 0.6065 - loss: 1.4131 - val_accuracy: 0.7456 - val_loss: 0.9307
第二步是解冻一些层,并使用较小的学习率来拟合模型。在本例中,我们展示了所有层的解冻情况,但根据具体的数据集,可能只需要解冻所有层中的一部分。
当使用预训练模型进行特征提取的效果足够好时,这一步骤对验证准确率的提升非常有限。在我们的案例中,由于 ImageNet 预训练已经让模型接触了大量的狗,所以我们只看到了很小的改进。
另一方面,当我们在与 ImageNet 有较大差异的数据集上使用预训练的权重时,这一微调步骤可能会非常关键,因为特征提取器也需要进行相当大的调整。如果选择 CIFAR-100 数据集,就可以证明这种情况,在 EfficientNetB0 上,微调可以将验证准确率提高约 10%,达到 80%。
关于冻结/解冻模型的附带说明:设置模型的可训练属性会同时将属于该模型的所有层设置为相同的可训练属性。只有当层本身和包含该层的模型都是可训练的,每一层才是可训练的。因此,当我们需要部分冻结/解冻模型时,需要确保模型的可训练属性设置为 True。
def unfreeze_model(model):
# We unfreeze the top 20 layers while leaving BatchNorm layers frozen
for layer in model.layers[-20:]:
if not isinstance(layer, layers.BatchNormalization):
layer.trainable = True
optimizer = keras.optimizers.Adam(learning_rate=1e-5)
model.compile(
optimizer=optimizer, loss="categorical_crossentropy", metrics=["accuracy"]
)
unfreeze_model(model)
epochs = 4 # @param {type: "slider", min:4, max:10}
hist = model.fit(ds_train, epochs=epochs, validation_data=ds_test)
plot_hist(hist)
Epoch 1/4
187/187 ━━━━━━━━━━━━━━━━━━━━ 111s 442ms/step - accuracy: 0.6310 - loss: 1.3425 - val_accuracy: 0.7565 - val_loss: 0.8874
Epoch 2/4
187/187 ━━━━━━━━━━━━━━━━━━━━ 77s 413ms/step - accuracy: 0.6518 - loss: 1.2755 - val_accuracy: 0.7635 - val_loss: 0.8588
Epoch 3/4
187/187 ━━━━━━━━━━━━━━━━━━━━ 82s 437ms/step - accuracy: 0.6491 - loss: 1.2426 - val_accuracy: 0.7663 - val_loss: 0.8419
Epoch 4/4
187/187 ━━━━━━━━━━━━━━━━━━━━ 79s 419ms/step - accuracy: 0.6625 - loss: 1.1775 - val_accuracy: 0.7701 - val_loss: 0.8284
微调 EfficientNet 的技巧
关于解冻层:
批量归一化层需要保持冻结状态(更多详情)。如果这些层也被转为可训练层,解冻后的第一个历时将大大降低准确率。
在某些情况下,只打开部分层而不是全部解冻可能会有好处。在使用 B7 等大型模型时,这将大大加快微调速度。
每个块都需要全部打开或关闭。这是因为架构中包含了每个区块从第一层到最后一层的快捷方式。不尊重区块也会大大损害最终性能。
使用效能网的其他一些提示:
较大的 EfficientNet 变体并不能保证性能的提高,尤其是对于数据较少或类别较少的任务。在这种情况下,选择的 EfficientNet 变体越大,调整超参数就越困难。
EMA(指数移动平均值)对于从头开始训练 EfficientNet 非常有帮助,但对于迁移学习就没那么有用了。
不要使用原始论文中的 RMSprop 设置来进行迁移学习。对于迁移学习来说,动量和学习率都太高。它很容易破坏预训练的权重,并造成损失。一个快速的检查方法是,在同一 epoch 之后,看看损失(作为分类交叉熵)是否明显大于 log(NUM_CLASSES)。如果是,则说明初始学习率/动量过高。
较小的批次规模有利于验证准确性,这可能是由于有效提供了正则化。