本教程介绍如何使用 tf.distribute.TPUStrategy
在 Cloud TPU 上训练 Keras EfficientNet 模型。
如果您不熟悉 Cloud TPU,强烈建议您查看快速入门以了解如何创建 Cloud TPU 和 Compute Engine 虚拟机。
目标
- 创建 Cloud Storage 存储分区以保存数据集和模型输出。
- 准备与 ImageNet 数据集类似的 fake_imagenet 数据集。
- 运行训练作业。
- 验证输出结果。
费用
本教程使用 Google Cloud 的以下收费组件:- Compute Engine
- Cloud TPU
- Cloud Storage
请使用价格计算器根据您的预计使用情况来估算费用。 Google Cloud 新用户可能有资格申请免费试用。
准备工作
在开始学习本教程之前,请检查您的 Google Cloud 项目是否已正确设置。
-
登录您的 Google 帐号。
如果您还没有 Google 帐号,请注册新帐号。
-
在 Google Cloud Console 的项目选择器页面上,选择或创建一个 Google Cloud 项目。
-
确保您的 Cloud 项目已启用结算功能。 了解如何确认您的项目是否已启用结算功能。
本演示使用 Google Cloud 的收费组件。请查看 Cloud TPU 价格页面估算您的费用。请务必在使用完您创建的资源以后清理这些资源,以免产生不必要的费用。
设置资源
本部分介绍如何为教程设置 Cloud Storage 存储空间、虚拟机和 Cloud TPU 资源。
打开一个 Cloud Shell 窗口。
为项目 ID 创建一个变量。
export PROJECT_ID=project-id
配置
gcloud
命令行工具,以使用要在其中创建 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 服务帐号设置默认权限。如果您需要更精细的权限,请查看访问级层权限。
存储分区位置必须要与 Compute Engine(虚拟机)和 Cloud TPU 节点位于同一地区。
使用
gcloud compute tpus execution-groups
命令启动 Compute Engine 虚拟机和 Cloud TPU。gcloud compute tpus execution-groups create \ --name=efficientnet-tutorial \ --zone=europe-west4-a \ --disk-size=300 \ --machine-type=n1-standard-16 \ --tf-version=2.4.1 \ --accelerator-type=v3-8
如需详细了解 gcloud
命令,请参阅 gcloud 参考文档。
当 gcloud compute tpus execution-groups
命令执行完毕后,验证 shell 提示符已从 username@projectname
更改为 username@vm-name
。此变化表明您现已登录 Compute Engine 虚拟机。
gcloud compute ssh efficientnet-tutorial --zone=europe-west4-a
设置 Cloud Storage 存储分区变量
设置以下环境变量,将 bucket-name 替换为 Cloud Storage 存储分区的名称:
(vm)$ export STORAGE_BUCKET=gs://bucket-name
(vm)$ export MODEL_DIR=${STORAGE_BUCKET}/efficientnet-2x (vm)$ export DATA_DIR=gs://cloud-tpu-test-datasets/fake_imagenet
训练应用应该能够访问 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)$ export TPU_NAME=efficientnet-tutorial
EfficientNet 训练脚本需要额外的软件包。请立即安装:
(vm)$ sudo pip3 install tensorflow-addons (vm)$ sudo pip3 install tensorflow-model-optimization>=0.1.3
使用以下命令将顶级
/models
文件夹添加到 Python 路径:(vm)$ export PYTHONPATH="${PYTHONPATH}:/usr/share/models/"
EfficientNet 模型已预安装在您的 Compute Engine 虚拟机上。
导航到该目录:
(vm)$ cd /usr/share/models/official/vision/image_classification/
运行训练脚本。使用一个 false_imagenet 数据集并用一个周期训练 EfficientNet。
(vm)$ python3 classifier_trainer.py \ --mode=train_and_eval \ --model_type=efficientnet \ --dataset=imagenet \ --tpu=${TPU_NAME} \ --data_dir=${DATA_DIR} \ --model_dir=${MODEL_DIR} \ --config_file=configs/examples/efficientnet/imagenet/efficientnet-b0-tpu.yaml \ --params_override="train.epochs=1, train_dataset.builder=records, validation_dataset.builder=records"
命令标志说明
mode
train
、eval
或train_and_eval
之一。model_type
- 模型的类型。例如
efficientnet
。 dataset
- 数据集的名称。例如
imagenet
。 tpu
- 用于运行训练或评估的 Cloud TPU 的名称。
data_dir
- 用于指定训练输入的 Cloud Storage 路径。在此示例中,该路径设置为 fake_imagenet 数据集。
model_dir
- 在模型训练期间存储检查点和摘要的 Cloud Storage 路径。您可以重复使用现有的文件夹来加载当前检查点数据和存储其他检查点,只要先前的检查点是使用相同大小的 Cloud TPU 和相同 TensorFlow 版本创建的即可。
config_file
- 包含预训练 EfficientNet 模型的 json 文件的路径。此文件包含模型架构。
params_override
- 一个 JSON 字符串,会替换默认脚本参数。如需详细了解脚本参数,请参阅
/usr/share/models/official/vision/detection/main.py
。
EfficientNet 1 周期的训练将在 10 分钟内在 v3-8 Cloud TPU 节点上完成。训练脚本完成后,系统将显示如下所示的输出:
Run stats: { 'accuracy_top_1': 0.0010172526817768812, 'eval_loss': 7.104171276092529, 'loss': 7.113735675811768, 'training_accuracy_top_1': 0.0009773431811481714, 'step_timestamp_log': [ 'BatchTimestamp<batch_index: 0, timestamp: 1604960724.2224622>', 'BatchTimestamp<batch_index: 1251, timestamp: 1604961281.3745298>' ], 'train_finish_time': 1604961342.6359076, 'avg_exp_per_second': 2071.493269569079 }
要训练 EfficientNet 收敛,请运行 90 个周期,如以下脚本所示。训练和评估是一起完成的。每个周期都有 1251 个步骤,总计 112590 个训练步骤和 48 个评估步骤。
(vm)$ python3 classifier_trainer.py \
--mode=train_and_eval \
--model_type=efficientnet \
--dataset=imagenet \
--tpu=${TPU_NAME} \
--data_dir=${DATA_DIR} \
--model_dir=${MODEL_DIR} \
--config_file=configs/examples/efficientnet/imagenet/efficientnet-b0-tpu.yaml \
--params_override="train_dataset.builder=records, validation_dataset.builder=records"
命令标志说明
mode
train
、eval
或train_and_eval
之一。model_type
- 模型的类型。例如,
efficientnet
等。 dataset
- 数据集的名称。例如
imagenet
。 tpu
- 用于运行训练或评估的 Cloud TPU 的名称。
data_dir
- 用于指定训练输入的 Cloud Storage 路径。在此示例中,该路径设置为 fake_imagenet 数据集。
model_dir
- 在模型训练期间存储检查点和摘要的 Cloud Storage 路径。您可以重复使用现有的文件夹来加载先前生成检查点以及存储其他检查点,只要先前的检查点是使用相同大小的 Cloud TPU 和相同 TensorFlow 版本创建的即可。
config_file
- 包含预训练 EfficientNet 模型的 JSON 文件的路径。此文件包含模型架构。
params_override
- 一个 JSON 字符串,会替换默认脚本参数。如需详细了解脚本参数,请参阅
/usr/share/models/official/vision/detection/main.py
。
由于训练和评估是利用 fake_imagenet 数据集完成的,因此输出结果不会反映实际输出,实际输出在利用实际数据集执行训练和评估时才会出现。
此时,您可以结束本教程并清理 GCP 资源,也可以进一步了解如何在 Cloud TPU Pod 上运行模型。
使用 Cloud TPU Pod 扩缩模型
您可以使用 Cloud TPU Pod 扩缩模型,以便更快获得结果。这一完全受支持的 EfficientNet 模型可与以下 Pod 切片配合使用:
- v2-32
- v3-32
借助 Cloud TPU Pod,训练和评估可同时完成。
使用 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 --name=efficientnet-tutorial \ --accelerator-type=v3-32 \ --zone=europe-west4-a \ --tf-version=2.4.1 \ --tpu-only
命令标志说明
gcloud compute ssh efficientnet-tutorial --zone=europe-west4-a
更新
MODEL_DIR
目录用于存储 Cloud TPU Pod 训练数据。(vm)$ export MODEL_DIR=${STORAGE_BUCKET}/efficientnet-2x-pod
定义您的 Cloud TPU 名称。
(vm)$ export TPU_NAME=efficientnet-tutorial
导航到模型目录:
(vm)$ cd /usr/share/models/official/vision/image_classification/
训练模型。
(vm)$ python3 classifier_trainer.py \ --mode=train_and_eval \ --model_type=efficientnet \ --dataset=imagenet \ --tpu=${TPU_NAME} \ --data_dir=${DATA_DIR} \ --model_dir=${MODEL_DIR} \ --config_file=configs/examples/efficientnet/imagenet/efficientnet-b0-tpu.yaml \ --params_override="train.epochs=1, train_dataset.builder=records, validation_dataset.builder=records"
命令标志说明
mode
- 设置为
train_and_eval
时,此脚本会训练和评估模型。设置为export_only
时,此脚本会导出已保存的模型。 model_type
- 模型的类型。例如,
efficientnet
等。 dataset
- 数据集的名称。例如
imagenet
。 tpu
- 使用 TPU_NAME 变量中指定的名称。
data_dir
- 用于指定训练输入的 Cloud Storage 路径。在此示例中,该路径设置为 fake_imagenet 数据集。
model_dir
- 在模型训练期间存储检查点和摘要的 Cloud Storage 路径。您可以重复使用现有的文件夹来加载先前生成检查点以及存储其他检查点,只要先前的检查点是使用相同大小的 Cloud TPU 和相同 TensorFlow 版本创建的即可。
config_file
- 包含预训练 EfficientNet 模型的 json 文件的路径。此文件包含模型架构。
params_override
- 一个 JSON 字符串,会替换默认脚本参数。如需详细了解脚本参数,请参阅
/usr/share/models/official/vision/detection/main.py
。
该程序将基于 fake_imagenet 数据集对模型进行 1 个周期的训练(共 312 个训练步骤和 12 个评估步骤)。此训练在 v3-32 Cloud TPU 上大约需要 2 分钟。训练和评估完成后,系统将显示类似如下内容的消息:
Run stats: { 'accuracy_top_1': 0.0009969075908884406, 'eval_loss': 7.105168342590332, 'loss': 7.114983081817627, 'training_accuracy_top_1': 0.0010031675919890404, 'step_timestamp_log': [ 'BatchTimestamp<batch_index: 0, timestamp: 1605041621.4997303>', 'BatchTimestamp<batch_index: 312, timestamp: 1605041970.8633356>' ], 'train_finish_time': 1605042032.2274444, 'avg_exp_per_second': 3111.5120716536226 }
清理
为避免因本教程中使用的资源导致您的 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
后续步骤
在本教程中,您已使用示例数据集训练 EfficientNet 模型。此训练的结果(在大多数情况下)不能用于推断。要使用模型进行推断,您可以在公开提供的数据集或您自己的数据集上训练数据。在 Cloud TPU 上训练的模型要求数据集采用 TFRecord 格式。
您可以使用数据集转换工具示例将图片分类数据集转换为 TFRecord 格式。如果您未使用图片分类模型,则必须自行将数据集转换为 TFRecord 格式。如需了解详情,请参阅 TFRecord 和 tf.Example
超参数调节
如需使用数据集提升模型的性能,您可以调节模型的超参数。您可以在 GitHub 上寻找所有 TPU 支持模型通用的超参数的相关信息。您可以在每个模型的源代码中寻找模型专用超参数的相关信息。如需详细了解超参数调节,请参阅超参数调节概览、使用超参数调节服务和调节超参数。
推理
训练模型后,您可以使用该模型进行推断(也称为预测)。AI Platform 是一款基于云的解决方案,用于开发、训练和部署机器学习模型。部署模型后,您可以使用 AI Platform Prediction 服务。
遵循数据集转换教程,了解如何使用自己的数据替代 fake_imagenet 或 ImageNet 数据集来进行训练和评估。该教程介绍了如何使用图片分类数据转换器示例脚本,将用于图片分类的原始数据集转换为 Cloud TPU Tensorflow 模型可用的 TFRecord。
运行 Cloud TPU colab,演示如何使用您自己的图片数据运行图片分类模型。
浏览其他 Cloud TPU 教程。
学习 TensorBoard 中 TPU 监控工具的使用方法。