在 Cloud TPU 上训练 ShapeMask (TF 2.x)

本文档演示如何使用 Cloud TPU 和 COCO 数据集运行 ShapeMask 模型。

以下说明假设您已熟悉如何在 Cloud TPU 上运行模型。如果您刚接触 Cloud TPU,则可以参阅快速入门获取基本介绍。

如果您计划在 TPU Pod 切片上训练,请参阅在 TPU Pod 上训练,以了解 Pod 切片所需的参数更改。

目标

  • 创建 Cloud Storage 存储分区以保存数据集和模型输出
  • 准备 COCO 数据集
  • 设置 Compute Engine 虚拟机和 Cloud TPU 节点以进行训练和评估
  • 在单个 Cloud TPU 或 Cloud TPU Pod 上运行训练和评估

费用

本教程使用 Google Cloud 的以下收费组件:

  • Compute Engine
  • Cloud TPU
  • Cloud Storage

请使用价格计算器根据您的预计使用情况来估算费用。 Google Cloud 新用户可能有资格申请免费试用

准备工作

在开始学习本教程之前,请检查您的 Google Cloud 项目是否已正确设置。

  1. 登录您的 Google 帐号。

    如果您还没有 Google 帐号,请注册新帐号

  2. 在 Google Cloud Console 的项目选择器页面上,选择或创建一个 Google Cloud 项目。

    转到项目选择器页面

  3. 确保您的 Cloud 项目已启用结算功能。 了解如何确认您的项目是否已启用结算功能

  4. 本演示使用 Google Cloud 的收费组件。请查看 Cloud TPU 价格页面估算您的费用。请务必在使用完您创建的资源以后清理这些资源,以免产生不必要的费用。

如果您计划在 TPU Pod 切片上训练,请参阅在 TPU Pod 上训练,以了解 Pod 切片所需的参数更改。

设置资源

本部分介绍如何为此教程设置 Cloud Storage、虚拟机和 Cloud TPU 资源。

  1. 打开一个 Cloud Shell 窗口。

    打开 Cloud Shell

  2. 为项目 ID 创建一个变量。

    export PROJECT_ID=project-id
    
  3. 配置 gcloud 命令行工具,以使用要在其中创建 Cloud TPU 的项目。

    gcloud config set project ${PROJECT_ID}
    

    当您第一次在新的 Cloud Shell 虚拟机中运行此命令时,系统会显示 Authorize Cloud Shell 页面。点击页面底部的 Authorize 以允许 gcloud 使用您的凭据进行 GCP API 调用。

  4. 为 Cloud TPU 项目创建服务帐号。

    gcloud beta services identity create --service tpu.googleapis.com --project $PROJECT_ID
    

    该命令将返回以下格式的 Cloud TPU 服务帐号:

    service-PROJECT_NUMBER@cloud-tpu.iam.gserviceaccount.com
    

  5. 使用以下命令创建 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 节点位于特定地区,即区域内的细分。

  6. 启动 Compute Engine 虚拟机实例。

    $ gcloud compute tpus execution-groups create \
     --vm-only \
     --name=shapemask-tutorial \
     --zone=europe-west4-a \
     --disk-size=300 \
     --machine-type=n1-standard-16 \
     --tf-version=2.4.1
    

    命令标志说明

    vm-only
    仅创建虚拟机。默认情况下,gcloud compute tpus execution-groups 命令会同时创建虚拟机和 Cloud TPU。
    name
    要创建的 Cloud TPU 的名称。
    zone
    拟在其中创建 Cloud TPU 的区域
    disk-size
    gcloud compute tpus execution-groups 命令创建的虚拟机的硬盘大小(以 GB 为单位)。
    machine-type
    要创建的 Compute Engine 虚拟机的机器类型
    tf-version
    在虚拟机上安装的 Tensorflow gcloud compute tpus execution-groups 的版本。

    如需详细了解 gcloud 命令,请参阅 gcloud 参考文档

  7. 此时会显示您指定的配置。输入 y 批准或输入 n 取消。

    gcloud compute tpus execution-groups 命令执行完毕后,验证 shell 提示符已从 username@projectname 更改为 username@vm-name。 此变化表明您现已登录 Compute Engine 虚拟机。

    gcloud compute ssh shapemask-tutorial --zone=europe-west4-a
    

    继续按照这些说明操作,在 Compute Engine 实例中运行以 (vm)$ 开头的每个命令。

  8. 创建环境变量以存储您的 Cloud Storage 存储分区位置。

    (vm)$ export STORAGE_BUCKET=gs://bucket-name
    
  9. 为数据目录创建环境变量。

    (vm)$ export DATA_DIR=${STORAGE_BUCKET}/coco
    
  10. 克隆 tpu 代码库。

    (vm)$ git clone -b shapemask https://github.com/tensorflow/tpu/
    
  11. 安装预处理数据所需的软件包。

    (vm)$ sudo apt-get install -y python3-tk && \
      pip3 install --user Cython matplotlib opencv-python-headless pyyaml Pillow && \
      pip3 install --user "git+https://github.com/cocodataset/cocoapi#egg=pycocotools&subdirectory=PythonAPI"
    

准备 COCO 数据集

  1. 运行 download_and_preprocess_coco.sh 脚本,将 COCO 数据集转换为训练应用所需的一组 TFRecord (*.tfrecord)。

    (vm)$ sudo bash /usr/share/tpu/tools/datasets/download_and_preprocess_coco.sh ./data/dir/coco
    

    这会安装所需的库,然后运行预处理脚本。 它会向您的本地数据目录中输出很多 *.tfrecord 文件。

  2. 将数据转换为 TFRecord 后,使用 gsutil 命令将其从本地存储空间复制到 Cloud Storage 存储分区。您还必须复制注释文件。这些文件有助于验证模型的性能:

    (vm)$ gsutil -m cp ./data/dir/coco/*.tfrecord ${DATA_DIR}
    (vm)$ gsutil cp ./data/dir/coco/raw-data/annotations/*.json ${DATA_DIR}
    

设置并启动 Cloud TPU

  1. 使用 gcloud 命令启动 Cloud TPU 资源。

    (vm)$ gcloud compute tpus execution-groups create \
     --tpu-only \
     --accelerator-type=v3-8  \
     --name=shapemask-tutorial \
     --zone=europe-west4-a \
     --tf-version=2.4.1
    

    命令标志说明

    tpu-only
    创建 Cloud TPU,而不创建虚拟机。默认情况下,gcloud compute tpus execution-groups 命令会同时创建虚拟机和 Cloud TPU。
    tpu-size
    要创建的 Cloud TPU 的类型
    name
    要创建的 Cloud TPU 的名称。
    zone
    拟在其中创建 Cloud TPU 的区域
    tf-version
    在虚拟机上安装的 Tensorflow gcloud compute tpus execution-groups 的版本。
  2. 为您的 Cloud TPU 名称添加环境变量。

    (vm)$ export TPU_NAME=shapemask-tutorial
    
  3. 此时会显示您指定的配置。输入 y 批准或输入 n 取消。

    您会看到一条消息:Operation success; not ssh-ing to Compute Engine VM due to --tpu-only flag。由于您之前已完成 SSH 密钥传播,因此可以忽略此消息。

  4. 为您的 Cloud TPU 名称添加环境变量。

    (vm)$ export TPU_NAME=shapemask-tutorial
    

运行训练和评估

以下脚本在 v3-8 TPU 上运行一个示例训练,其中将仅训练 100 个步骤,完成大约需要 6 分钟。在 v3-8 TPU 上,训练到收敛需要大约 22500 个步骤和大约 6 小时。

  1. 添加一些必需的环境变量:

    (vm)$ export PYTHONPATH="${PYTHONPATH}:/usr/share/models"
    (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)$ export SHAPE_PRIOR_PATH=gs://cloud-tpu-checkpoints/shapemask/kmeans_class_priors_91x20x32x32.npy
    (vm)$ export MODEL_DIR=${STORAGE_BUCKET}/shapemask
    
  2. 运行以下脚本来训练 ShapeMask 模型:

    (vm)$ python3 /usr/share/models/official/vision/detection/main.py \
    --strategy_type=tpu \
    --tpu=${TPU_NAME} \
    --model_dir=${MODEL_DIR} \
    --mode=train \
    --model=shapemask \
    --params_override="{train: {total_steps: 100, learning_rate: {init_learning_rate: 0.08, learning_rate_levels: [0.008, 0.0008], learning_rate_steps: [15000, 20000], }, checkpoint: { path: ${RESNET_CHECKPOINT},prefix: resnet50}, train_file_pattern: ${TRAIN_FILE_PATTERN}}, shapemask_head: {use_category_for_mask: true, shape_prior_path: ${SHAPE_PRIOR_PATH}}, shapemask_parser: {output_size: [640, 640]}}"
    

    命令标志说明

    strategy_type
    要在 TPU 上训练 RetinaNet 模型,您必须将 distribution_strategy 设置为 tpu
    tpu
    Cloud TPU 的名称。这是使用 TPU_NAME 环境变量设置的。
    model_dir
    在训练期间存储检查点和摘要的 Cloud Storage 存储分区。您可以使用现有文件夹加载根据相同大小和 TensorFlow 版本的先前生成 TPU 创建的检查点。
    mode
    trainevaltrain_and_eval 之一。
    model
    要训练的模型。
    params_override
    一个 JSON 字符串,会替换默认脚本参数。如需详细了解脚本参数,请参阅 /usr/share/models/official/vision/detection/main.py

    训练脚本输出应如下所示:

    Train Step: 100/100  / loss = {
     'total_loss': 10.152124404907227,
     'loss': 10.152124404907227,
     'retinanet_cls_loss': 1.3409545421600342,
     'l2_regularization_loss': 4.6183762550354,
     'retinanet_box_loss': 0.012389584444463253,
     'shapemask_prior_loss': 0.183448925614357,
     'shapemask_coarse_mask_loss': 1.7648673057556152,
     'shapemask_fine_mask_loss': 1.790102243423462,
     'model_loss': 5.533748626708984,
     'learning_rate': 0.021359999
    }
    / training metric = {
    'total_loss': 10.152124404907227,
    'loss': 10.152124404907227,
    'retinanet_cls_loss': 1.3409545421600342,
    'l2_regularization_loss': 4.6183762550354,
    'retinanet_box_loss': 0.012389584444463253,
    'shapemask_prior_loss': 0.183448925614357,
    'shapemask_coarse_mask_loss': 1.7648673057556152,
    'shapemask_fine_mask_loss': 1.790102243423462,
    'model_loss': 5.533748626708984,
    'learning_rate': 0.021359999
    }
  3. 运行脚本以评估 ShapeMask 模型:

    (vm)$ python3 /usr/share/models/official/vision/detection/main.py \
    --strategy_type=tpu \
    --tpu=${TPU_NAME} \
    --model_dir=${MODEL_DIR} \
    --checkpoint_path=${MODEL_DIR} \
    --mode=eval_once \
    --model=shapemask \
    --params_override="{eval: { val_json_file: ${VAL_JSON_FILE}, eval_file_pattern: ${EVAL_FILE_PATTERN}, eval_samples: 5000 }, shapemask_head: {use_category_for_mask: true, shape_prior_path: ${SHAPE_PRIOR_PATH}}, shapemask_parser: {output_size: [640, 640]}}"
    

    命令标志说明

    strategy_type
    要在 TPU 上训练 RetinaNet 模型,您必须将 distribution_strategy 设置为 tpu
    tpu
    Cloud TPU 的名称。这是使用 TPU_NAME 环境变量设置的。
    model_dir
    在训练期间存储检查点和摘要的 Cloud Storage 存储分区。您可以使用现有文件夹加载根据相同大小和 TensorFlow 版本的先前生成 TPU 创建的检查点。
    mode
    trainevaltrain_and_eval 之一。
    model
    要训练的模型。
    params_override
    一个 JSON 字符串,会替换默认脚本参数。如需详细了解脚本参数,请参阅 /usr/share/models/official/vision/detection/main.py

评估脚本输出应如下所示:

756s 62ms/step
- loss: 0.4864
- accuracy: 0.8055
- val_loss: 0.3832
- val_accuracy: 0.8546

此时,您可以结束本教程并清理 GCP 资源,也可以进一步了解如何在 Cloud TPU Pod 上运行模型。

使用 Cloud TPU Pod 扩缩模型

您可以使用 Cloud TPU Pod 扩缩模型,以便更快获得结果。完全受支持的 Mask RCNN 模型可与以下 Pod 切片配合使用:

  • v2-32
  • v3-32

使用 Cloud TPU Pod 时,首先使用 Pod 训练模型,然后使用单台 Cloud TPU 设备评估模型。

使用 Cloud TPU Pod 进行训练

如果您已经删除了 Compute Engine 实例,请按照设置资源中的步骤创建一个新实例。

以下示例训练仅运行 20 个步骤,在 v3-32 TPU 节点上完成大约需要 10 分钟。在 v3-32 TPU Pod 上,训练到收敛需要大约 11250 个步骤和大约 2 小时。

  1. 删除为在单台设备上训练模型而创建的 Cloud TPU 资源。

    (vm)$ gcloud compute tpus execution-groups delete shapemask-tutorial \
      --zone=europe-west4-a \
      --tpu-only
  2. 运行 gcloud compute tpus execution-groups 命令,并使用 accelerator-type 参数指定要使用的 Pod 切片。例如,以下命令使用 v3-32 Pod 切片。

    (vm)$ gcloud compute tpus execution-groups  create --name=shapemask-tutorial \
      --accelerator-type=v3-32  \
      --zone=europe-west4-a \
      --tf-version=2.4.1 \
      --tpu-only
    

    命令标志说明

    name
    要创建的 Cloud TPU 的名称。
    accelerator-type
    要创建的 Cloud TPU 的类型
    zone
    拟在其中创建 Cloud TPU 的区域
    tf-version
    在虚拟机上安装的 Tensorflow gcloud 的版本。
    tpu-only
    仅创建 Cloud TPU。默认情况下,gcloud 命令会同时创建虚拟机和 Cloud TPU。
  3. 更新 TPU_NAME 和 MODEL_DIR 环境变量。

    (vm)$ export TPU_NAME=shapemask-tutorial
    (vm)$ export MODEL_DIR=${STORAGE_BUCKET}/shapemask-pods
    
  4. 启动训练脚本。

    (vm)$ python3 /usr/share/models/official/vision/detection/main.py \
    --strategy_type=tpu \
    --tpu=${TPU_NAME} \
    --model_dir=${MODEL_DIR} \
    --mode=train \
    --model=shapemask \
    --params_override="{train: { batch_size: 128, iterations_per_loop: 500, total_steps: 20, learning_rate: {'learning_rate_levels': [0.008, 0.0008],'learning_rate_steps': [10000, 13000]}, 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}},shapemask_head: {use_category_for_mask: true, shape_prior_path: ${SHAPE_PRIOR_PATH}}}"
    

    命令标志说明

    strategy_type
    要在 TPU 上训练 RetinaNet 模型,您必须将 distribution_strategy 设置为 tpu
    tpu
    Cloud TPU 的名称。这是使用 TPU_NAME 环境变量设置的。
    model_dir
    在训练期间存储检查点和摘要的 Cloud Storage 存储分区。您可以使用现有文件夹加载根据相同大小和 TensorFlow 版本的先前生成 TPU 创建的检查点。
    mode
    trainevaltrain_and_eval 之一。
    model
    要训练的模型。
    params_override
    一个 JSON 字符串,会替换默认脚本参数。如需详细了解脚本参数,请参阅 /usr/share/models/official/vision/detection/main.py

训练脚本输出应如下所示:

Train Step: 20/20  / loss = {
  'total_loss': 12.213006973266602,
  'loss': 12.213006973266602,
  'retinanet_cls_loss': 1.9299328327178955,
  'l2_regularization_loss': 4.628948211669922,
  'retinanet_box_loss': 0.016126759350299835,
  'shapemask_prior_loss': 0.16990719735622406,
  'shapemask_coarse_mask_loss': 3.688129425048828,
  'shapemask_fine_mask_loss': 1.1426670551300049,
  'model_loss': 7.584057807922363,
  'learning_rate': 0.009632
}
/ training metric = {
  'total_loss': 12.213006973266602,
  'loss': 12.213006973266602,
  'retinanet_cls_loss': 1.9299328327178955,
  'l2_regularization_loss': 4.628948211669922,
  'retinanet_box_loss': 0.016126759350299835,
  'shapemask_prior_loss': 0.16990719735622406,
  'shapemask_coarse_mask_loss': 3.688129425048828,
  'shapemask_fine_mask_loss': 1.1426670551300049,
  'model_loss': 7.584057807922363,
  'learning_rate': 0.009632
}

评估模型

在此步骤中,您将使用单个 Cloud TPU 节点针对 COCO 数据集评估上述经过训练的模型。此评估大约需要 20 分钟。

  1. 删除您为在 Pod 上训练模型而创建的 Cloud TPU 资源。

    (vm)$ gcloud compute tpus execution-groups delete shapemask-tutorial \
      --zone=europe-west4-a \
      --tpu-only
  2. 启动新的 TPU 设备来运行评估。

    (vm)$ gcloud compute tpus execution-groups create --tpu-only \
      --name=shapemask-tutorial \
      --accelerator-type=v3-8 \
      --zone=europe-west4-a \
      --tf-version=2.4.1 \
    
    

    命令标志说明

    tpu-only
    仅创建 Cloud TPU。默认情况下,gcloud 命令会同时创建虚拟机和 Cloud TPU。
    name
    要创建的 Cloud TPU 的名称。
    accelerator-type
    要创建的 Cloud TPU 的类型
    zone
    拟在其中创建 Cloud TPU 的区域
    tf-version
    在虚拟机上安装的 Tensorflow gcloud 的版本。
  3. 更新 TPU_NAME 环境变量。

    (vm)$ export TPU_NAME=shapemask-tutorial
    
  4. 开始评估。

    (vm)$ python3 /usr/share/models/official/vision/detection/main.py \
    --strategy_type=tpu \
    --tpu=shapemask-tutorial \
    --model_dir=${MODEL_DIR} \
    --checkpoint_path=${MODEL_DIR} \
    --mode=eval_once \
    --model=shapemask \
    --params_override="{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
    trainevaltrain_and_eval 之一。
    model
    要训练的模型。
    params_override
    一个 JSON 字符串,会替换默认脚本参数。如需详细了解脚本参数,请参阅 /usr/share/models/official/vision/detection/main.py

清理

为避免因本教程中使用的资源导致您的 Google Cloud 帐号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。

  1. 断开与 Compute Engine 实例的连接(如果您尚未这样做):

    (vm)$ exit
    

    您的提示符现在应为 username@projectname,表明您位于 Cloud Shell 中。

  2. 在您的 Cloud Shell 中,使用以下命令删除您的 Compute Engine 虚拟机和 Cloud TPU:

    $ gcloud compute tpus execution-groups delete shapemask-tutorial \
      --zone=europe-west4-a
    
  3. 通过运行 gcloud compute tpus execution-groups list 验证资源是否已删除。删除操作可能需要几分钟时间才能完成。如下所示的响应表明您的实例已成功删除。

    $ gcloud compute tpus execution-groups list \
     --zone=europe-west4-a
    

    您应该会看到如下所示的空白 TPU 列表:

       NAME             STATUS
    
  4. 使用 gsutil 删除 Cloud Storage 存储分区(如下所示)。将 bucket-name 替换为您的 Cloud Storage 存储分区的名称。

    $ gsutil rm -r gs://bucket-name
    

后续步骤

使用其他图像大小进行训练

您可以使用更大的神经网络(例如,ResNet-101 而不是 ResNet-50)进行探索。较大的输入图片和更强大的神经网络将生成耗时更长但更精确的模型。

使用其他基础

或者,您也可以探索如何利用自己的数据集预训练 ResNet 模型,并以此为基础训练 ShapeMask 模型。再进行一些工作,您就可以用新的神经网络来替换 ResNet。最后,如果您有兴趣实现自己的对象检测模型,则可以基于该骨干网进行进一步的实验。