EfficientNet 模型是一系列图像分类模型,可实现领先的准确率,同时比其他模型更小巧、更快速。EfficientNet-EdgeTpu 模型经过定制,可在 Google EdgeTPU 设备上高效运行。
本教程中的模型基于《EfficientNet:重新思考卷积神经网络的模型扩缩》。 研究人员开发了一种新技术来提高模型性能:使用一个简单而高效的复合系数仔细平衡网络深度、宽度与分辨率。
从 efficientnet-b0
到 efficientnet-b7
的模型系列可在 Google EdgeTPU 设备资源受限的情况下实现良好的图片分类准确率。
本教程中使用的 efficientnet-b0
模型对应最小的基本模型,而 efficientnet-b7
对应最强大、但需要大量计算的模型。本教程演示如何使用 TPUEstimator 训练模型。
目标
- 创建 Cloud Storage 存储分区以保存数据集和模型输出。
- 准备测试版 ImageNet 数据集,该数据集又称为 fake_imagenet 数据集。
- 运行训练作业。
- 验证输出结果。
费用
本教程使用 Google Cloud 的以下收费组件:
- Compute Engine
- Cloud TPU
- Cloud Storage
您可使用价格计算器根据您的预计使用情况来估算费用。
准备工作
在开始学习本教程之前,请检查您的 Google Cloud 项目是否已正确设置。
- 登录您的 Google Cloud 帐号。如果您是 Google Cloud 新手,请创建一个帐号来评估我们的产品在实际场景中的表现。新客户还可获享 $300 赠金,用于运行、测试和部署工作负载。
-
在 Google Cloud Console 中的项目选择器页面上,选择或创建一个 Google Cloud 项目。
-
确保您的 Cloud 项目已启用结算功能。了解如何检查项目是否已启用结算功能。
-
在 Google Cloud Console 中的项目选择器页面上,选择或创建一个 Google Cloud 项目。
-
确保您的 Cloud 项目已启用结算功能。了解如何检查项目是否已启用结算功能。
本演示使用 Google Cloud 的收费组件。请查看 Cloud TPU 价格页面估算您的费用。请务必在使用完您创建的资源以后清理这些资源,以免产生不必要的费用。
设置资源
本部分介绍如何为教程设置 Cloud Storage、虚拟机和 Cloud TPU 资源。
打开一个 Cloud Shell 窗口。
为项目 ID 创建一个变量。
export PROJECT_ID=project-id
配置 Google Cloud CLI 以使用要在其中创建 Cloud TPU 的项目。
gcloud config set project ${PROJECT_ID}
当您第一次在新的 Cloud Shell 虚拟机中运行此命令时,系统会显示
Authorize Cloud Shell
页面。点击页面底部的Authorize
以允许gcloud
使用您的凭据进行 GCP API 调用。为 Cloud TPU 项目创建服务帐号。
gcloud beta services identity create --service tpu.googleapis.com --project $PROJECT_ID
该命令将返回以下格式的 Cloud TPU 服务帐号:
service-PROJECT_NUMBER@cloud-tpu.iam.gserviceaccount.com
使用以下命令创建 Cloud Storage 存储分区:
gsutil mb -p ${PROJECT_ID} -c standard -l europe-west4 -b on gs://bucket-name
此 Cloud Storage 存储分区存储您用于训练模型的数据和训练结果。本教程中使用的
gcloud compute tpus execution-groups
命令会为 Cloud TPU 服务帐号设置默认权限。如果您需要更精细的权限,请查看访问级层权限。存储分区位置必须与虚拟机 (VM) 和 TPU 节点位于同一区域。虚拟机和 TPU 节点位于特定地区,即区域内的细分。
使用
gcloud compute tpus execution-groups
命令启动本教程所需的 Compute Engine 和 Cloud TPU 资源。gcloud compute tpus execution-groups create \ --vm-only \ --name=efficientnet-tutorial \ --zone=europe-west4-a \ --disk-size=300 \ --machine-type=n1-standard-8 \ --tf-version=1.15.5
命令标志说明
如需详细了解
gcloud
命令,请参阅 gcloud 参考文档。在出现提示时,按 y 创建 Cloud TPU 资源。
当
gcloud compute tpus execution-groups
命令执行完毕后,验证 shell 提示符已从username@projectname
更改为username@vm-name
。此变化表明您现已登录 Compute Engine 虚拟机。gcloud compute ssh efficientnet-tutorial --zone=europe-west4-a
从现在开始,前缀
(vm)$
表示您应该在 Compute Engine 虚拟机实例上运行该命令。
准备数据
设置以下环境变量,其中将 bucket-name 替换为 Cloud Storage 存储分区的名称:
为存储分区名称创建环境变量。将 bucket-name 替换为您的存储分区名称。
(vm)$ export STORAGE_BUCKET=gs://bucket-name
创建一些其他环境变量。
(vm)$ export MODEL_DIR=${STORAGE_BUCKET}/efficientnet (vm)$ export DATA_DIR=gs://cloud-tpu-test-datasets/fake_imagenet (vm)$ export TPU_NAME=efficientnet-tutorial (vm)$ export PYTHONPATH=$PYTHONPATH:/usr/share/tpu/models
训练应用应该能够访问 Cloud Storage 中的训练数据。在训练期间,训练应用还会使用您的 Cloud Storage 存储分区来存储检查点。
使用 fake_imagenet 来训练和评估 EfficientNet 模型
ImageNet 是一个图像数据库。数据库中的图片被整理为一个层次结构,该层次结构中的每个节点由成百上千个图片进行描述。
本教程使用演示版的完整 ImageNet 数据集,该数据集又称为 fake_imagenet。此演示版本可用于测试教程,同时降低通常与使用完整 ImageNet 数据库运行模型相关的存储和时间要求。
此 fake_imagenet 数据集位于 Cloud Storage 上的以下位置:
gs://cloud-tpu-test-datasets/fake_imagenet
此 fake_imagenet 数据集仅用于了解如何使用 Cloud TPU 并验证端到端性能。准确率数字和保存的模型并无实际意义。
如需了解如何下载和处理完整 ImageNet 数据集,请参阅下载、预处理和上传 ImageNet 数据集。
启动 Cloud TPU 资源。
(vm)$ gcloud compute tpus execution-groups create \ --tpu-only \ --name=efficientnet-tutorial \ --zone=europe-west4-a \ --disk-size=300 \ --machine-type=n1-standard-8 \ --tf-version=1.15.5
导航到模型目录:
(vm)$ cd /usr/share/tpu/models/official/efficientnet/
运行训练脚本。
(vm)$ python3 main.py \ --tpu=${TPU_NAME} \ --data_dir=${DATA_DIR} \ --model_dir=${MODEL_DIR} \ --model_name='efficientnet-b0' \ --skip_host_call=true \ --train_batch_size=2048 \ --train_steps=1000
命令标志说明
tpu
- 使用 TPU_NAME 变量中指定的名称。
data_dir
- 用于指定训练输入的 Cloud Storage 路径。在此示例中,该路径设置为 fake_imagenet 数据集。
model_dir
- 在模型训练期间存储检查点和总结的 Cloud Storage 路径。您可以重复使用现有的文件夹来加载之前生成的检查点和存储其他检查点,只要先前的检查点是使用相同大小的 Cloud TPU 和相同 Tensorflow 版本创建的即可。
model_name
- 要训练的模型的名称。例如
efficientnet
。 skip_host_call
- 设置为
true
可指示脚本跳过每个训练步骤中执行的host_call
。这通常用于生成训练总结(训练损失、学习速率等)。如果为skip_host_call=false
,则在host_call
函数运行缓慢且无法跟上 TPU 端计算的情况下,性能可能会降低。 train_batch_size
- 训练批次大小。
train_steps
- 用于训练的步骤数。 默认值为 218949 步,约为 350 个周期,批次大小为 2048。此标志应根据
train_batch_size
标志值进行调整。
这会对 EfficientNet 模型(efficientnet-b0
变体)仅训练 1000 步,因为它使用虚构的 ImageNet 数据集。使用完整的 ImageNet 数据集进行训练时,您可以使用以下命令训练到收敛:
(vm)$ python3 main.py \
--tpu=${TPU_NAME} \
--data_dir=${DATA_DIR} \
--model_dir=${MODEL_DIR} \
--model_name='efficientnet-b0' \
--skip_host_call=true \
--train_batch_size=2048 \
--train_steps=218948
这会将 EfficientNet 模型训练 350 个周期,并且要在处理一批数据之后进行评估。使用指定的标志,该模型应该会在大约 23 小时内完成训练。这些设置应该可以针对 ImageNet 验证数据集实现约 76.5% 的 top-1 准确率。最佳模型检查点和相应的评估结果位于模型目录中的 archive
文件夹中:${STORAGE_BUCKET}/efficientnet/archive
。
使用 Cloud TPU Pod 扩缩模型
您可以使用 Cloud TPU Pod 扩缩模型,以便更快获得结果。这一完全受支持的模型可与以下 Pod 切片配合使用:
- v2-32
- v3-32
使用 Cloud TPU Pod 时,首先使用 Pod 训练模型,然后使用单台 Cloud TPU 设备评估模型。
使用 Cloud TPU Pod 进行训练
删除为在单台设备上训练模型而创建的 Cloud TPU 资源。
(vm)$ gcloud compute tpus execution-groups delete efficientnet-tutorial \ --zone=europe-west4-a \ --tpu-only
运行
gcloud compute tpus execution-groups
命令,并使用accelerator-type
参数指定要使用的 Pod 切片。例如,以下命令使用 v3-32 Pod 切片。(vm)$ gcloud compute tpus execution-groups create --tpu-only \ --name=efficientnet-tutorial \ --zone=europe-west4-a \ --accelerator-type=v2-32 \ --tf-version=1.15.5
为 TPU 名称创建环境变量。
(vm)$ export TPU_NAME=efficientnet-tutorial
更新
MODEL_DIR
目录以存储训练数据。(vm)$ export MODEL_DIR=${STORAGE_BUCKET}/efficientnet-tutorial
训练模型。
(vm)$ python3 main.py \ --tpu=${TPU_NAME} \ --data_dir=${DATA_DIR} \ --model_dir=${MODEL_DIR} \ --model_name='efficientnet-b3' \ --skip_host_call=true \ --mode=train \ --train_steps=1000 \ --train_batch_size=4096 \ --iterations_per_loop=100
命令标志说明
tpu
- Cloud TPU 的名称。
data_dir
- 训练输入的 Cloud Storage 路径。在此示例中,该路径设置为 fake_imagenet 数据集。
model_dir
- 在模型训练期间存储检查点和总结的 Cloud Storage 路径。您可以重复使用现有的文件夹来加载之前生成的检查点和存储其他检查点,只要先前的检查点是使用相同大小的 Cloud TPU 和相同 Tensorflow 版本创建的即可。
model_name
- 要训练的模型的名称。
skip_host_call
- 设置为
true
可指示脚本跳过每个训练步骤中执行的host_call
。这通常用于生成训练总结(训练损失、学习速率等)。如果为skip_host_call=false
,则在host_call
函数运行缓慢且无法跟上 TPU 端计算的情况下,性能可能会降低。 mode
train_and_eval
、train
或eval
之一。train_and_eval
用于训练和评估模型。train
用于训练模型。eval
用于评估模型。train_steps
- 指定训练步数。
train_batch_size
- 训练批次大小。
iterations_per_loop
- 在将指标发送到 CPU 之前要在 TPU 上运行的训练步数。
此命令会对 EfficientNet 模型(efficientnet-b0
变体)仅训练 1000 步,因为它使用虚构的 ImageNet 数据集。使用完整的 ImageNet 数据集进行训练时,您可以使用以下命令训练到收敛:
(vm)$ python3 main.py \
--tpu=${TPU_NAME} \
--data_dir=${DATA_DIR} \
--model_dir=${MODEL_DIR} \
--model_name='efficientnet-b3' \
--skip_host_call=true \
--mode=train \
--train_steps=109474 \
--train_batch_size=4096 \
--iterations_per_loop=100
此命令会为 EfficientNet 模型(efficientnet-b3
变体)训练 350 个周期。该模型应该可以针对 ImageNet 开发数据集实现 81.1% 的准确率,训练完成时间约为 20 小时。最佳模型检查点和相应的评估结果位于模型目录中的 archive
文件夹中:${STORAGE_BUCKET}/efficientnet/archive
。
评估模型
在这组步骤中,您将使用 Cloud TPU 针对 fake_imagenet 验证数据评估上述经过训练的模型。
删除您为在 Pod 上训练模型而创建的 Cloud TPU 资源。
(vm)$ gcloud compute tpus execution-groups delete efficientnet-tutorial \ --tpu-only \ --zone=europe-west4-a
启动 v2-8 Cloud TPU 以运行评估。使用与 Compute Engine 虚拟机名称相同的名称,它应该仍在运行。
(vm)$ gcloud compute tpus execution-groups create --tpu-only \ --name=efficientnet-tutorial \ --accelerator-type=v2-8 \ --zone=europe-west4-a \ --tf-version=1.15.5
为 TPU 名称创建环境变量。
(vm)$ export TPU_NAME=efficientnet-tutorial
运行模型评估。这一次,添加
mode
标志并将其设置为eval
。(vm)$ python3 main.py \ --tpu=${TPU_NAME} \ --data_dir=${DATA_DIR} \ --model_dir=${MODEL_DIR} \ --model_name='efficientnet-b3' \ --skip_host_call=true \ --mode=eval
命令标志说明
tpu
- 使用 TPU_NAME 变量中指定的名称。
data_dir
- 用于指定训练输入的 Cloud Storage 路径。在此示例中,该路径设置为 fake_imagenet 数据集。
model_dir
- 在模型训练期间存储检查点和总结的 Cloud Storage 路径。您可以重复使用现有的文件夹来加载之前生成的检查点和存储其他检查点,只要先前的检查点是使用相同大小的 Cloud TPU 和相同 Tensorflow 版本创建的即可。
model_name
- 要训练的模型的名称。例如,
efficientnet
等。 skip_host_call
- 设置为
true
可指示脚本跳过每个训练步骤中执行的host_call
。这通常用于生成训练总结(训练损失、学习速率等)。如果为skip_host_call=false
,则在host_call
函数运行缓慢且无法跟上 TPU 端计算的情况下,性能可能会降低。 mode
- 设置为
train_and_eval
时,此脚本会训练和评估模型。设置为export_only
时,此脚本会导出已保存的模型。
这将生成如下所示的输出:
Eval results: { 'loss': 7.532023, 'top_1_accuracy': 0.0010172526, 'global_step': 100, 'top_5_accuracy': 0.005065918 } Elapsed seconds: 88
清理
为避免因本教程中使用的资源导致您的 Google Cloud 帐号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。
断开与 Compute Engine 实例的连接(如果您尚未这样做):
(vm)$ exit
您的提示符现在应为
username@projectname
,表明您位于 Cloud Shell 中。在您的 Cloud Shell 中,使用以下命令删除您的 Compute Engine 虚拟机和 Cloud TPU:
$ gcloud compute tpus execution-groups delete efficientnet-tutorial \ --zone=europe-west4-a
通过运行
gcloud compute tpus execution-groups list
验证资源是否已删除。删除操作可能需要几分钟时间才能完成。如下所示的响应表明实例已成功删除:$ gcloud compute tpus execution-groups list \ --zone=europe-west4-a
您应该会看到如下所示的空白 TPU 列表:
NAME STATUS
使用
gsutil
删除 Cloud Storage 存储分区,如下所示。将 bucket-name 替换为您的 Cloud Storage 存储分区的名称。$ gsutil rm -r gs://bucket-name
后续步骤
TensorFlow Cloud TPU 教程通常使用示例数据集来训练模型。此训练的结果无法用于推断。如需使用模型进行推理,您可以使用公开提供的数据集或您自己的数据集来训练模型。在 Cloud TPU 上训练的 TensorFlow 模型通常要求数据集采用 TFRecord 格式。
您可以使用数据集转换工具示例将图片分类数据集转换为 TFRecord 格式。如果您未使用图片分类模型,则必须自行将数据集转换为 TFRecord 格式。如需了解详情,请参阅 TFRecord 和 tf.Example。
超参数调节
如需使用数据集提升模型的性能,您可以调节模型的超参数。您可以在 GitHub 上寻找所有 TPU 支持模型通用的超参数的相关信息。您可以在每个模型的源代码中寻找模型专用超参数的相关信息。如需详细了解超参数调节,请参阅超参数调节概览、使用超参数调节服务和调节超参数。
推断
训练模型后,您可以使用该模型进行推断(也称为预测)。AI Platform 是一款基于云的解决方案,用于开发、训练和部署机器学习模型。部署模型后,您可以使用 AI Platform Prediction 服务。