《Keras3通过使用 EfficientNet 进行微调进行图像分类》:此文为AI自动翻译

Keras3通过使用 EfficientNet 进行微调进行图像分类

作者: Yixing Fu
创建日期: 2020/06/30
最后修改时间: 2023/07/10
描述: 使用在 imagenet 上预先训练的权重的 EfficientNet 进行 Stanford Dogs 分类。

(i) 此示例使用 Keras 3

 在 Colab 中查看 •

 GitHub 源


简介:什么是 EfficientNet

EfficientNet 于 2019 年在 Tan 和 Le中首次推出,是最有效的模型之一(即需要最少的 FLOPS 进行推理) 在两者上都达到了最先进的精度 ImageNet 和常见的图像分类迁移学习任务。

最小的基本模型类似于 MnasNet,它 以明显较小的模型达到接近 SOTA。通过引入启发式方式 扩展模型时,EfficientNet 提供了一系列模型(B0 到 B7),这些模型表示 在各种秤上将效率和准确性良好结合。这样的缩放 启发式方法(化合物缩放,详细信息参见 Tan 和 Le,2019 年)允许 以效率为导向的基础模型 (B0) 在各种规模上超越模型,同时避免 超参数的广泛网格搜索。

该模型的最新更新摘要可在此处获得,其中各种 增强方案和半监督学习方法进一步应用于 提高模型的 ImageNet 性能。可以使用模型的这些扩展 在不更改模型架构的情况下更新权重。


EfficientNet 的 B0 到 B7 变体

(本节提供了有关 “compound scaling” 的一些详细信息,可以跳过 如果您只对使用模型感兴趣)

根据原始论文,人们可能有 印象中 EfficientNet 是由任意 选择 中的比例因子作为论文的方程 (3)。然而,分辨率的选择, 深度和宽度也受到许多因素的限制:

  • 分辨率:不能被 8、16 等整除的分辨率会导致边界附近出现零填充 浪费计算资源的层。这尤其适用于较小的 变体,因此 B0 和 B1 的输入分辨率选择为 224 和 240.
  • 深度和宽度:EfficientNet 的构建块要求通道大小 8 的倍数。
  • 资源限制:当深度 宽度仍然可以增加。在这种情况下,增加深度和/或 width 但保持分辨率仍可以提高性能。

因此,EfficientNet 模型的每个变体的深度、宽度和分辨率 经过精心挑选并被证明会产生良好的结果,尽管它们可能会显着 off 从 compound scaling 公式中。 因此,keras 实现(详见下文)仅提供这 8 个模型,即 B0 到 B7、 而不是允许任意选择宽度/深度/分辨率参数。


EfficientNet 的 Keras 实现

自 v2.3 起,Keras 随附了 EfficientNet B0 到 B7 的实现。自 使用 EfficientNetB0 对 ImageNet 中的 1000 类图像进行分类,运行:

from tensorflow.keras.applications import EfficientNetB0
model = EfficientNetB0(weights='imagenet')

此模型采用 shape 为 的输入图像,并且输入数据应位于 范围。归一化作为模型的一部分包含在内。(224, 224, 3)[0, 255]

因为在 ImageNet 上训练 EfficientNet 需要大量的资源,并且 不属于模型架构本身的几种技术。因此,Keras 默认情况下,implementation 会加载通过使用 AutoAugment 进行训练而获得的预训练权重。

对于 B0 到 B7 基础模型,输入形状不同。下面是输入形状的列表 每个模型的预期值:

基本模型 分辨率
高效网 B0 224
高效网 B1 240
高效网络 B2 260
高效网络 B3 300
高效网络 B4 380
高效网络 B5 456
高效网络 B6 528
高效网 B7 600

当模型用于迁移学习时,Keras 实现 提供删除顶部图层的选项:

model = EfficientNetB0(include_top=False, weights='imagenet')

此选项不包括将 1280 个要素置于倒数第二个图层的最后一个图层 层转换为 1000 个 ImageNet 类的预测。将顶层替换为自定义图层 layers 允许在迁移学习工作流程中使用 EfficientNet 作为特征提取器。Dense

模型构造函数中值得注意的另一个参数是哪些控件 负责随机深度的 dropout 率。 此参数用作微调中额外正则化的切换,但不用作 影响加载的权重。例如,当需要更强的正则化时,请尝试:drop_connect_rate

model = EfficientNetB0(weights='imagenet', drop_connect_rate=0.4)

默认值为 0.2。


示例:Stanford Dogs 的 EfficientNetB0。

EfficientNet 能够执行广泛的图像分类任务。 这使其成为迁移学习的良好模型。 作为端到端示例,我们将展示在 Stanford 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)加载数据。 Stanford Dogs 数据集在 TFDS 作为 stanford_dogs。 它包含 20,580 张图像,属于 120 个犬种类别 (12000 个用于训练,8580 个用于测试)。

通过简单地更改以下内容,您也可以尝试使用这款笔记本 TFDS 中的其他数据集,例如 cifar10cifar100food101、 等。当图像远小于 EfficientNet 输入的大小时, 我们可以简单地对输入图像进行上采样。Tan 和 Le,2019 年已经表明,迁移学习 即使输入图像仍然很小,结果也更适合提高分辨率。dataset_name

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

当数据集包含不同大小的图像时,我们需要将它们的大小调整为 共享大小。Stanford Dogs 数据集仅包含至少 200x200 的图像 pixels 的大小。在这里,我们将图像大小调整为 EfficientNet 所需的输入大小。

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")

PNG 格式

数据增强

我们可以使用预处理层 API 进行图像增广。

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 个示例 的增强结果。Sequential

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")

PNG 格式

准备输入

一旦我们验证了输入数据和增强工作正常, 我们准备用于训练的数据集。输入数据的大小将调整为 uniform 。标签放入 one-hot (又名 categorical) 编码。数据集已批处理。IMG_SIZE

注意:在某些情况下可能会有所改善 性能,但取决于环境和使用的特定数据集。 有关数据管道性能的更多信息,请参阅本指南prefetchAUTOTUNE

# 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",<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

空云风语

人工智能,深度学习,神经网络

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值