本文档介绍了 RetinaNet 对象检测模型的实现。您可以在 GitHub 上找到相关代码。
以下说明假设您已熟悉如何在 Cloud TPU 上运行模型。如果您刚接触 Cloud TPU,则可以参阅快速入门获取基本介绍。
如果您计划在 TPU Pod 切片上训练,请参阅在 TPU Pod 上训练 了解 Pod 切片所需的参数更改。
目标
- 准备 COCO 数据集
- 创建 Cloud Storage 存储分区以保存数据集和模型输出
- 设置 TPU 资源以进行训练和评估
- 在单个 Cloud TPU 或 Cloud TPU Pod 上运行训练和评估
费用
在本文档中,您将使用 Google Cloud 的以下收费组件:
- Compute Engine
- Cloud TPU
- Cloud Storage
您可使用价格计算器根据您的预计使用情况来估算费用。
准备工作
在开始学习本教程之前,请检查您的 Google Cloud 项目是否已正确设置。
- 登录您的 Google Cloud 账号。如果您是 Google Cloud 新手,请创建一个账号来评估我们的产品在实际场景中的表现。新客户还可获享 $300 赠金,用于运行、测试和部署工作负载。
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
本演示使用 Google Cloud 的收费组件。请查看 Cloud TPU 价格页面估算您的费用。
准备 COCO 数据集
本教程使用 COCO 数据集。Cloud Storage 存储桶上的数据集需要采用 TFRecord 格式以用于训练。
如果您已在 Cloud Storage 存储桶上准备好 COCO 数据集,该存储桶位于您将用于训练模型的可用区中,则可以直接进行单设备训练。 否则,请按照以下步骤准备数据集。
打开一个 Cloud Shell 窗口。
在 Cloud Shell 中,为您的项目配置
gcloud
ID。export PROJECT_ID=project-id gcloud config set project ${PROJECT_ID}
在 Cloud Shell 中,使用以下命令创建 Cloud Storage 存储桶:
gcloud storage buckets create gs://bucket-name --project=${PROJECT_ID} --location=us-central2
创建一个 Compute Engine 虚拟机,以下载并预处理数据集。如需了解详情,请参阅创建和启动 Compute Engine 实例。
$ gcloud compute instances create vm-name \ --zone=us-central2-b \ --image-family=ubuntu-2204-lts \ --image-project=ubuntu-os-cloud \ --machine-type=n1-standard-16 \ --boot-disk-size=300GB
使用 SSH 连接到 Compute Engine 虚拟机:
$ gcloud compute ssh vm-name --zone=us-central2-b
连接到虚拟机后,shell 提示符会从
username@projectname
更改为username@vm-name
。设置两个变量,一个用于先前创建的存储桶,另一个用于保存存储桶中的训练数据 (
DATA_DIR
) 的目录。(vm)$ export STORAGE_BUCKET=gs://bucket-name
(vm)$ export DATA_DIR=${STORAGE_BUCKET}/coco
安装预处理数据所需的软件包。
(vm)$ sudo apt-get update && \ sudo apt-get install python3-pip && \ sudo apt-get install -y python3-tk && \ pip3 install --user Cython matplotlib opencv-python-headless pyyaml Pillow numpy absl-py tensorflow && \ pip3 install --user "git+https://github.com/cocodataset/cocoapi#egg=pycocotools&subdirectory=PythonAPI"
运行
download_and_preprocess_coco.sh
脚本,将 COCO 数据集转换为训练应用所需的一组 TFRecord 文件 (*.tfrecord
)。(vm)$ git clone https://github.com/tensorflow/tpu.git (vm)$ sudo bash tpu/tools/datasets/download_and_preprocess_coco.sh ./data/dir/coco
这会安装所需的库,然后运行预处理脚本。它会在您的本地数据目录中输出
*.tfrecord
文件。COCO 下载和转换脚本大约需要 1 小时才能完成。将数据复制到 Cloud Storage 存储桶。
将数据转换为 TFRecord 格式后,从本地存储空间复制数据 Cloud Storage 存储桶。您还必须复制注释文件。这些文件有助于验证模型的 性能
(vm)$ gcloud storage cp ./data/dir/coco/*.tfrecord ${DATA_DIR} (vm)$ gcloud storage cp ./data/dir/coco/raw-data/annotations/*.json ${DATA_DIR}
与 Compute Engine 虚拟机断开连接:
(vm)$ exit
您的提示符现在应为
username@projectname
,表明您位于 Cloud Shell 中。删除您的 Compute Engine 虚拟机:
$ gcloud compute instances delete vm-name \ --zone=us-central2-b
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
使用您的凭据进行 Google Cloud 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 存储分区:
gcloud storage buckets create gs://bucket-name --project=${PROJECT_ID} --location=europe-west4
此 Cloud Storage 存储分区存储您用于训练模型的数据和训练结果。本教程中使用的
gcloud
命令会为您设置 TPU,还会为在上一步中设置的 Cloud TPU 服务账号设置默认权限。如果您需要更精细的权限,请查看访问级层权限。
设置并启动 Cloud TPU
使用
gcloud
命令启动 Compute Engine 虚拟机和 Cloud TPU。$ gcloud compute tpus tpu-vm create retinanet-tutorial \ --zone=europe-west4-a \ --accelerator-type=v3-8 \ --version=tpu-vm-tf-2.17.0-pjrt
命令标志说明
如需详细了解
gcloud
命令,请参阅 gcloud 参考文档。使用 SSH 连接到 Compute Engine 实例。连接到网络后 您的 Shell 提示符会从
username@projectname
更改为username@vm-name
:gcloud compute tpus tpu-vm ssh retinanet-tutorial --zone=europe-west4-a
安装另外的软件包
RetinaNet 训练应用需要几个额外的软件包。 请立即安装:
(vm)$ sudo apt-get install -y python3-tk (vm)$ pip3 install --user Cython matplotlib opencv-python-headless pyyaml Pillow (vm)$ pip3 install --user 'git+https://github.com/cocodataset/cocoapi#egg=pycocotools&subdirectory=PythonAPI'
安装 TensorFlow 要求。
(vm)$ pip3 install -r /usr/share/tpu/models/official/requirements.txt
设置 Cloud TPU 名称变量。
(vm)$ export TPU_NAME=local
为数据和模型目录添加环境变量。
(vm)$ export STORAGE_BUCKET=gs://bucket-name (vm)$ export DATA_DIR=${STORAGE_BUCKET}/coco (vm)$ export MODEL_DIR=${STORAGE_BUCKET}/retinanet-train (vm)$ export PYTHONPATH="${PWD}/models:${PYTHONPATH}"
创建 TPU 时,如果您将
--version
参数设置为以-pjrt
时,请设置以下环境变量以启用 PJRT 运行时:(vm)$ export NEXT_PLUGGABLE_DEVICE_USE_C_API=true (vm)$ export TF_PLUGGABLE_DEVICE_LIBRARY_PATH=/lib/libtpu.so
切换至存储模型的目录。
(vm)$ cd /usr/share/tpu/models/official/legacy/detection
单个 Cloud TPU 设备训练
以下训练脚本在 Cloud TPU v3-8 上运行。您也可以在 Cloud TPU v2-8 上运行,但这将需要更长的时间。
以下示例脚本仅有 10 个训练步骤,并且在 v3-8 TPU 上的运行时间不超过 5 分钟。要训练收敛,大约需要 22500 在 Cloud TPU v3-8 TPU 上运行大约 1 1/2 小时。
设置以下环境变量:
(vm)$ export RESNET_CHECKPOINT=gs://cloud-tpu-checkpoints/retinanet/resnet50-checkpoint-2018-02-07 (vm)$ export TRAIN_FILE_PATTERN=${DATA_DIR}/train-* (vm)$ export EVAL_FILE_PATTERN=${DATA_DIR}/val-* (vm)$ export VAL_JSON_FILE=${DATA_DIR}/instances_val2017.json
运行训练脚本:
(vm)$ python3 main.py \ --strategy_type=tpu \ --tpu=${TPU_NAME} \ --model_dir=${MODEL_DIR} \ --mode="train" \ --params_override="{ type: retinanet, train: { total_steps: 10, checkpoint: { path: ${RESNET_CHECKPOINT}, prefix: resnet50/ }, train_file_pattern: ${TRAIN_FILE_PATTERN} }, eval: { val_json_file: ${VAL_JSON_FILE}, eval_file_pattern: ${EVAL_FILE_PATTERN}, eval_samples: 5000 } }"
命令标志说明
strategy_type
- 如需在 TPU 上训练 RetinaNet 模型,您必须设置
将
distribution_strategy
更改为tpu
。 tpu
- Cloud TPU 的名称。您可以使用
TPU_NAME
环境变量。 model_dir
- 在训练期间存储检查点和摘要的 Cloud Storage 存储分区。您可以使用现有文件夹加载根据相同大小和 TensorFlow 版本的先前生成 TPU 创建的检查点。
mode
- 将此值设置为
train
以训练模型,或设置为eval
以评估模型。 params_override
- 一个 JSON 字符串,会替换默认脚本参数。有关
如需了解脚本参数,请参阅
/usr/share/models/official/legacy/detection/main.py
。
该模型将在 v3-8 TPU 上训练 10 个步骤,大约需要 5 分钟。训练完成后,您将看到类似于以下内容的输出:
Train Step: 10/10 / loss = { 'total_loss': 2.4581615924835205, 'cls_loss': 1.4098565578460693, 'box_loss': 0.012001709081232548, 'model_loss': 2.0099422931671143, 'l2_regularization_loss': 0.44821977615356445, 'learning_rate': 0.008165999 } / training metric = { 'total_loss': 2.4581615924835205, 'cls_loss': 1.4098565578460693, 'box_loss': 0.012001709081232548, 'model_loss': 2.0099422931671143, 'l2_regularization_loss': 0.44821977615356445, 'learning_rate': 0.008165999 }
单个 Cloud TPU 设备评估
以下过程使用 COCO 评估数据。大约需要 10 分钟 在 v3-8 TPU 上运行评估步骤。
设置以下环境变量:
(vm)$ export EVAL_SAMPLES=5000
运行评估脚本:
(vm)$ python3 main.py \ --strategy_type=tpu \ --tpu=${TPU_NAME} \ --model_dir=${MODEL_DIR} \ --checkpoint_path=${MODEL_DIR} \ --mode=eval_once \ --params_override="{ type: retinanet, eval: { val_json_file: ${VAL_JSON_FILE}, eval_file_pattern: ${EVAL_FILE_PATTERN}, eval_samples: ${EVAL_SAMPLES} } }"
命令标志说明
strategy_type
- 要使用的分布策略。
tpu
或multi_worker_gpu
。 tpu
- Cloud TPU 的名称。这是使用
TPU_NAME
环境变量设置的。 model_dir
- 检查点和摘要所在的 Cloud Storage 存储桶 存储的数据。您可以使用现有文件夹加载之前的内容 在相同大小的 TPU 上创建的检查点 版本。
mode
train
、eval
或train_and_eval
之一。params_override
- 一个 JSON 字符串,会替换默认脚本参数。有关
脚本参数的详细信息,请参阅
/usr/share/models/official/legacy/detection/main.py
。
在评估结束时,您会在控制台中看到类似如下内容的信息:
Accumulating evaluation results... DONE (t=7.66s). Average Precision (AP) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.000 Average Precision (AP) @[ IoU=0.50 | area= all | maxDets=100 ] = 0.000 Average Precision (AP) @[ IoU=0.75 | area= all | maxDets=100 ] = 0.000 Average Precision (AP) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.000 Average Precision (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.000 Average Precision (AP) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.000 Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 1 ] = 0.000 Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 10 ] = 0.000 Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.000 Average Recall (AR) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.000 Average Recall (AR) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.000 Average Recall (AR) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.000
您现已完成单设备训练和评估。请按照以下步骤删除当前的单设备 TPU 资源。
与 Compute Engine 实例断开连接:
(vm)$ exit
您的提示符现在应为
username@projectname
,表明您位于 Cloud Shell 中。删除 TPU 资源。
$ gcloud compute tpus tpu-vm delete retinanet-tutorial \ --zone=europe-west4-a
命令标志说明
zone
- 您的 Cloud TPU 所在的可用区。
使用 Cloud TPU Pod 扩缩模型
在 Cloud TPU Pod 上训练模型可能需要进行一些更改 添加到训练脚本中。如需了解详情,请参阅在 TPU Pod 上运行训练。
在 TPU Pod 上训练 Retinanet
打开一个 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
使用您的 Google Cloud 凭据。为 Cloud TPU 项目创建服务账号。
通过服务账号,Cloud TPU 服务可以访问其他 Google Cloud 服务。
gcloud beta services identity create --service tpu.googleapis.com --project $PROJECT_ID
该命令将返回以下格式的 Cloud TPU 服务账号:
service-PROJECT_NUMBER@cloud-tpu.iam.gserviceaccount.com
使用以下命令创建 Cloud Storage 存储桶,或使用您之前为项目创建的存储桶。
在以下命令中,将 europe-west4 替换为 将用于运行训练的区域。 将 bucket-name 替换为您要分配给存储桶的名称。
gcloud storage buckets create gs://bucket-name \ --project=${PROJECT_ID} \ --location=europe-west4
此 Cloud Storage 存储分区存储您用于训练模型的数据和训练结果。本教程中使用的
gcloud
命令会设置 您在 Cloud TPU 和 Cloud TPU 中 上一步。如果需要更精细的权限,请查看 访问权限级别权限。存储桶位置必须与您的 TPU 资源位于同一区域。
如果您之前准备好了 COCO 数据集并将其移动到了存储空间, 您可以再次将其用于 Pod 训练。如果您尚未准备好 COCO 数据集,请立即准备并返回此处设置训练。
设置并启动 Cloud TPU Pod
本教程指定 v3-32 Pod。如需了解其他 Pod 选项,请参阅 TPU 版本。
使用
gcloud compute tpus tpu-vm
命令启动 TPU 虚拟机 Pod。本教程指定 v3-32 Pod。如需了解其他 Pod 选项,请参阅可用的 TPU 类型页面。$ gcloud compute tpus tpu-vm create retinanet-tutorial \ --zone=europe-west4-a \ --accelerator-type=v3-32 \ --version=tpu-vm-tf-2.17.0-pod-pjrt
使用 SSH 连接到 TPU 虚拟机实例。连接到虚拟机后 shell 提示符从
username@projectname
更改为username@vm-name
:gcloud compute tpus tpu-vm ssh retinanet-tutorial --zone=europe-west4-a
设置 Cloud TPU 名称变量。
(vm)$ export TPU_NAME=retinanet-tutorial
设置 Cloud Storage 存储分区变量
设置以下环境变量,将 bucket-name 替换为 Cloud Storage 存储分区的名称:
(vm)$ export STORAGE_BUCKET=gs://bucket-name
(vm)$ export MODEL_DIR=${STORAGE_BUCKET}/retinanet-train (vm)$ export DATA_DIR=${STORAGE_BUCKET}/coco
训练应用应该能够访问 Cloud Storage 中的训练数据。在训练期间,训练应用还会使用您的 Cloud Storage 存储分区来存储检查点。
安装另外的软件包
RetinaNet 训练应用需要几个额外的软件包。立即安装:
(vm)$ sudo apt-get install -y python3-tk (vm)$ pip3 install --user Cython matplotlib opencv-python-headless pyyaml Pillow (vm)$ pip3 install --user 'git+https://github.com/cocodataset/cocoapi#egg=pycocotools&subdirectory=PythonAPI'
安装 TensorFlow 要求。
(vm)$ pip3 install -r /usr/share/tpu/models/official/requirements.txt
设置一些所需的环境变量:
(vm)$ export RESNET_PRETRAIN_DIR=gs://cloud-tpu-checkpoints/retinanet/resnet50-checkpoint-2018-02-07 (vm)$ export TRAIN_FILE_PATTERN=${DATA_DIR}/train-* (vm)$ export EVAL_FILE_PATTERN=${DATA_DIR}/val-* (vm)$ export VAL_JSON_FILE=${DATA_DIR}/instances_val2017.json (vm)$ export PYTHONPATH="${PWD}/models:${PYTHONPATH}" (vm)$ export TPU_LOAD_LIBRARY=0
切换至存储模型的目录。
(vm)$ cd /usr/share/tpu/models/official/legacy/detection
训练模型
(vm)$ python3 main.py \ --strategy_type=tpu \ --tpu=${TPU_NAME} \ --model_dir=${MODEL_DIR} \ --mode=train \ --model=retinanet \ --params_override="{architecture: {use_bfloat16: true}, eval: {batch_size: 40, eval_file_pattern: ${EVAL_FILE_PATTERN}, val_json_file: ${VAL_JSON_FILE}}, postprocess: {pre_nms_num_boxes: 1000}, predict: {batch_size: 40}, train: {batch_size: 256, checkpoint: {path: ${RESNET_PRETRAIN_DIR}, prefix: resnet50/}, iterations_per_loop: 5000, total_steps: 5625, train_file_pattern: ${TRAIN_FILE_PATTERN}, } }"
命令标志说明
tpu
- TPU 的名称。
model_dir
- 用于指定在模型训练期间存储检查点和摘要的目录。如果指定的文件夹不存在,此程序会自行创建相应文件夹。使用 Cloud TPU 时,
model_dir
必须是 Cloud Storage 路径 (gs://...
)。您可以重复使用 一个现有的文件夹,用于加载当前检查点数据并存储 其他检查点(只要先前的检查点已创建) 相同大小的 Cloud TPU 和 TensorFlow 版本。 params_override
- 一个 JSON 字符串,会替换默认脚本参数。有关
如需了解脚本参数,请参阅
/usr/share/tpu/models/official/legacy/detection/main.py
。
此过程基于 COCO 数据集训练模型,完成 5625 个训练步骤。此训练在 v3-32 TPU 上大约需要 20 分钟。训练完成后,系统将显示如下所示的消息:
训练完成后,系统将显示如下所示的消息:
Train Step: 5625/5625 / loss = {'total_loss': 0.730501651763916, 'cls_loss': 0.3229793608188629, 'box_loss': 0.003082591574639082, 'model_loss': 0.4771089553833008, 'l2_regularization_loss': 0.2533927261829376, 'learning_rate': 0.08} / training metric = {'total_loss': 0.730501651763916, 'cls_loss': 0.3229793608188629, 'box_loss': 0.003082591574639082, 'model_loss': 0.4771089553833008, 'l2_regularization_loss': 0.2533927261829376, 'learning_rate': 0.08}
清理
为避免因本教程中使用的资源导致您的 Google Cloud 账号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。
与 Compute Engine 虚拟机断开连接:
(vm)$ exit
您的提示符现在应为
username@projectname
,表明您位于 Cloud Shell 中。删除您的 Cloud TPU 和 Compute Engine 资源。
$ gcloud compute tpus tpu-vm delete retinanet-tutorial \ --zone=europe-west4-a
通过运行
gcloud compute tpus tpu-vm list
验证资源是否已删除。删除操作可能需要几分钟时间才能完成。如下所示的响应表明实例已成功删除。$ gcloud compute tpus tpu-vm list --zone=europe-west4-a
Listed 0 items.
删除 Cloud Storage 存储分区。将 bucket-name 替换为您的 Cloud Storage 存储桶的名称。
使用 gcloud CLI 删除 Cloud Storage 存储桶,如以下示例所示。将 bucket-name 替换为您的 Cloud Storage 存储分区的名称。
$ gcloud storage rm gs://bucket-name --recursive
后续步骤
TensorFlow Cloud TPU 教程通常使用示例数据集来训练模型。此训练的结果不能用于推断。接收者 使用模型进行推理,可以在公开可用的 或您自己的数据集。在 Cloud TPU 上训练的 TensorFlow 模型通常要求数据集采用 TFRecord 格式。
您可以使用数据集转换工具示例将图片分类数据集转换为 TFRecord 格式。如果您未使用图片分类模型,则必须自行将数据集转换为 TFRecord 格式。如需了解详情,请参阅 TFRecord 和 tf.Example。
超参数调节
如需使用数据集提升模型的性能,您可以调节模型的超参数。您可以在 GitHub 上寻找所有 TPU 支持模型通用的超参数的相关信息。如需了解特定于模型的超参数,请参阅源代码 每个代码 模型。如需详细了解超参数调优,请参阅概览 超参数调优 和 Tune 超参数。
推断
训练模型后,您可以使用该模型进行推理(也称为预测)。您可以使用 Cloud TPU 推断转换器 工具来准备和优化 在 Cloud TPU v5e 上用于推理的 TensorFlow 模型。如需详细了解 Cloud TPU v5e 上的推理,请参阅 Cloud TPU v5e 推理简介。
使用其他图片大小进行训练
您可以使用更大的骨干网(例如 ResNet-101, )。更大的输入图片和更强大的骨干网将生成耗时更长但更精确的模型。
使用其他基础
或者,您也可以探索如何使用自己的数据集预训练 ResNet 模型 并将其用作 RetinaNet 模型的基础。再多进行一些工作,您还可以使用替代骨干网来替换掉 ResNet。最后,如果您有兴趣实现自己的对象检测模型,则可以基于该骨干网进行进一步的实验。