在 Cloud TPU 上运行 Inception

本教程介绍如何在 Cloud TPU 上训练 Inception 模型。

免责声明

本教程使用第三方数据集。Google 不对此数据集的有效性或任何其他方面提供任何表示、担保或其他保证。

模型说明

Inception v3 是一种广泛使用的图片识别模型,可以实现非常高的准确率。该模型是数年来多位研究人员提出的诸多想法积淀的成果。它以 Szegedy 等人发表的《Rethinking the Inception Architecture for Computer Vision》原创性论文为理论依据。

该模型由对称构件和不对称构件组成,包括:

  • 卷积
  • 平均池化
  • 最大池化
  • concat
  • 丢包
  • 全连接层

损失是通过 Softmax 计算的。

下图概括显示了该模型:

图片

您可以在 GitHub 上详细了解该模型。

该模型是使用高级 Estimator API 构建的。

此 API 通过封装大多数低级函数极大地简化了模型创建,使用户可以专注于模型开发,而非关注负责运行的底层硬件的内部工作。

准备工作

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

  1. 登录您的 Google 帐号。

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

  2. 选择或创建 Google Cloud Platform 项目。

    转到“管理资源”页面

  3. 确保您的 Google Cloud Platform 项目已启用结算功能。

    了解如何启用结算功能

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

设置资源

本部分介绍如何针对教程设置 Cloud Storage 存储、虚拟机和 Cloud TPU 资源。

创建 Cloud Storage 存储分区

您需要一个 Cloud Storage 存储分区来存储用于训练模型的数据和训练结果。本教程中使用的 ctpu up 工具会为 Cloud TPU 服务帐号设置默认权限。如果您需要更精细的权限,请查看访问级层权限

您创建的存储分区必须与您的虚拟机 (VM) 和 Cloud TPU 设备或 Cloud TPU 切片(多台 TPU 设备)位于同一区域

  1. 转到 GCP Console 上的 Cloud Storage 页面。

    转到“Cloud Storage”页面

  2. 创建一个新的存储分区,并指定以下选项:

    • 您选择的唯一名称。
    • 默认存储类别:Regional
    • 位置:如果要使用 Cloud TPU 设备,请接受默认值。如果要使用 Cloud TPU Pod 切片,则必须指定一个提供 Cloud TPU Pod 的区域

使用 ctpu 工具

本部分演示如何使用 Cloud TPU 预配工具 (ctpu) 来创建和管理 Cloud TPU 项目资源。这些资源由具有相同名称的虚拟机和 Cloud TPU 资源组成。这些资源必须与您刚创建的存储分区位于同一区域/地区中。

您还可以使用 gcloud 命令或通过 Cloud Console 来设置虚拟机和 TPU 资源。请参阅管理虚拟机和 TPU 资源页面,了解设置和管理 Compute Engine 虚拟机与 Cloud TPU 资源的所有方法。

运行 ctpu up 以创建资源

  1. 打开一个 Cloud Shell 窗口。

    打开 Cloud Shell

  2. 运行 gcloud config set project <Your-Project> 以使用要在其中创建 Cloud TPU 的项目。

  3. 运行 ctpu up 以指定为 Cloud TPU 设备或 Pod 切片显示的标志。如需了解标志选项和说明,请参阅 CTPU 参考

  4. 设置 Cloud TPU 设备:

    $ ctpu up 

    系统会显示以下配置消息:

    ctpu will use the following configuration:
    
    Name: [your TPU's name]
    Zone: [your project's zone]
    GCP Project: [your project's name]
    TensorFlow Version: 1.14
    VM:
     Machine Type: [your machine type]
     Disk Size: [your disk size]
     Preemptible: [true or false]
    Cloud TPU:
     Size: [your TPU size]
     Preemptible: [true or false]
    
    OK to create your Cloud TPU resources with the above configuration? [Yn]:
    

    y 创建 Cloud TPU 资源。

ctpu up 命令会创建虚拟机和 Cloud TPU 服务。

在下面的内容中,前缀 (vm)$ 表示您应该在 Compute Engine 虚拟机实例上运行该命令。

验证您的 Compute Engine 虚拟机

ctpu up 命令执行完毕后,验证 shell 提示符是否已从 username@project 更改为 username@tpuname。此更改表明您现已登录 Compute Engine 虚拟机。

获取数据

设置以下环境变量,并将 YOUR-BUCKET-NAME 替换为您的 Cloud Storage 存储分区的名称:

(vm)$ export STORAGE_BUCKET=gs://YOUR-BUCKET-NAME

训练应用要求可在 Cloud Storage 中访问您的训练数据。在训练期间,训练应用还会使用您的 Cloud Storage 存储分区来存储检查点。

训练数据集

ImageNet 是一个图像数据库。数据库中的图像被整理为一个层次结构,该层次结构中的每个节点由成百上千个图像进行描述。

本教程使用演示版的完整 ImageNet 数据集,该数据集又称为“fake_imagenet”。此演示版本可用于测试本教程,节省了下载占用的存储空间和使用完整的 ImageNet 数据库运行模型所需的时间。以下是有关使用随机生成的虚构数据集测试该模型的说明。或者,您也可以使用完整的 ImageNet 数据集

下文所述的 DATA_DIR 环境变量用于指定要利用哪个数据集进行训练。

请注意,此虚构数据集仅用于了解如何使用 Cloud TPU 并验证端到端性能。准确率数字和保存的模型没有什么意义。

此虚构数据集位于 Cloud Storage 上的以下位置:

gs://cloud-tpu-test-datasets/fake_imagenet

(可选)设置 TensorBoard

TensorBoard 提供了一套工具,旨在直观地呈现 TensorFlow 数据。当用于监控时,TensorBoard 可以帮助识别处理过程中的瓶颈,并提出改进性能的方法。

如果此时不需要监控模型的输出,则可以跳过 TensorBoard 设置步骤。

如果想要监控模型的输出和性能,请参照设置 TensorBoard 指南。

运行模型

现在您可以使用 ImageNet 数据训练和评估 Inception v3 模型了。

Inception v3 模型已预安装到您的 Compute Engine 虚拟机上的 /usr/share/tpu/models/experimental/inception/ 目录中。

在以下步骤中,前缀 (vm)$ 表示您应该在 Compute Engine 虚拟机上运行该命令:

  1. 设置包含下列某个值的 DATA_DIR 环境变量:

    • 如果您使用的是虚构数据集:

      (vm)$ export DATA_DIR=gs://cloud-tpu-test-datasets/fake_imagenet
      
    • 如果您已将一组训练数据上传到您的 Cloud Storage 存储分区:

      (vm)$ export DATA_DIR=${STORAGE_BUCKET}/data
      
  2. 运行 Inception v3 模型:

    (vm)$ python /usr/share/tpu/models/experimental/inception/inception_v3.py \
        --tpu=$TPU_NAME \
        --learning_rate=0.165 \
        --train_steps=250000 \
        --iterations=500 \
        --use_tpu=True \
        --use_data=real \
        --mode=train_and_eval \
        --train_steps_per_eval=2000 \
        --data_dir=${DATA_DIR} \
        --model_dir=${STORAGE_BUCKET}/inception
    • --tpu 用于指定 Cloud TPU 的名称。请注意,ctpu 会将此名称以环境变量 (TPU_NAME) 的形式传递给 Compute Engine 虚拟机。
    • --use_data 用于指定此程序在训练期间必须使用哪种类型的数据(是虚构的还是真实的)。默认值为 fake(虚构数据)。
    • --data_dir 用于指定训练输入的 Cloud Storage 路径。如果您使用的是虚构的数据,应用会忽略此参数。
    • --model_dir 用于指定在模型训练期间存储检查点和摘要的目录。如果指定的文件夹不存在,此程序会自行创建。使用 Cloud TPU 时,model_dir 必须是 Cloud Storage 路径 (gs://...)。您可以重复使用现有的文件夹来加载当前检查点数据和存储其他检查点。

预期结果

Inception v3 可对 299x299 图片执行操作。默认训练批量大小为 1024,即每次迭代处理其中 1024 个图片。

您可以使用 --mode 标志选择以下三种操作模式之一:train(训练)、eval(评估)和 train_and_eval(训练并评估)。

  • --mode=train--mode=eval 用于指定仅限训练的作业或仅限评估的作业。
  • --mode=train_and_eval 用于指定同时执行训练和评估的混合式作业。

仅限训练的作业会运行 train_steps 中定义的指定步数,并且可以遍历整个训练集(如果需要)。

Train_and_eval 作业会循环浏览训练和评估部分。每个训练周期都运行 train_steps_per_eval,然后运行评估作业(使用训练到当时的权重)。

训练周期数的计算方式是对 train_steps/train_steps_per_eval 向下取整(通过 floor 函数实现)。

floor(train_steps / train_steps_per_eval)

默认情况下,基于 Estimator API 的模型会报告每过特定步数的损失值。报告格式如下:

step = 15440, loss = 12.6237

讨论:专门针对 TPU 对模型进行修改

要使基于 Estimator API 的模型可在 TPU 上运行,仅需进行极少量的修改。此程序会导入以下库:

from google.third_party.tensorflow.contrib.tpu.python.tpu import tpu_config
from google.third_party.tensorflow.contrib.tpu.python.tpu import tpu_estimator
from google.third_party.tensorflow.contrib.tpu.python.tpu import tpu_optimizer

CrossShardOptimizer 函数会封装优化器,如下所示:

if FLAGS.use_tpu:
  optimizer = tpu_optimizer.CrossShardOptimizer(optimizer)

定义该模型的函数会使用以下命令返回 Estimator 规范:

return tpu_estimator.TPUEstimatorSpec(
    mode=mode, loss=loss, train_op=train_op, eval_metrics=eval_metrics)

main 函数使用以下方法定义了 Estimator 兼容配置:

run_config = tpu_config.RunConfig(
    master=tpu_grpc_url,
    evaluation_master=tpu_grpc_url,
    model_dir=FLAGS.model_dir,
    save_checkpoints_secs=FLAGS.save_checkpoints_secs,
    save_summary_steps=FLAGS.save_summary_steps,
    session_config=tf.ConfigProto(
        allow_soft_placement=True,
        log_device_placement=FLAGS.log_device_placement),
    tpu_config=tpu_config.TPUConfig(
        iterations_per_loop=iterations,
        num_shards=FLAGS.num_shards,
        per_host_input_for_training=per_host_input_for_training))

此程序使用此定义的配置和模型定义函数来创建 Estimator 对象:

inception_classifier = tpu_estimator.TPUEstimator(
    model_fn=inception_model_fn,
    use_tpu=FLAGS.use_tpu,
    config=run_config,
    params=params,
    train_batch_size=FLAGS.train_batch_size,
    eval_batch_size=eval_batch_size,
    batch_axis=(batch_axis, 0))

仅限训练的作业只调用 train 函数:

inception_classifier.train(
    input_fn=imagenet_train.input_fn, steps=FLAGS.train_steps)

仅限评估的作业会从可用检查点获取数据,并一直等到有新的检查点可用:

for checkpoint in get_next_checkpoint():
  eval_results = inception_classifier.evaluate(
      input_fn=imagenet_eval.input_fn,
      steps=eval_steps,
      hooks=eval_hooks,
      checkpoint_path=checkpoint)

当您选择选项 train_and_eval 时,训练和评估作业会并行运行。在评估过程中,会从最新的可用检查点加载可训练变量。训练和评估周期按标志中指定的方式重复:

for cycle in range(FLAGS.train_steps // FLAGS.train_steps_per_eval):
  inception_classifier.train(
      input_fn=imagenet_train.input_fn, steps=FLAGS.train_steps_per_eval)

  eval_results = inception_classifier.evaluate(
      input_fn=imagenet_eval.input_fn, steps=eval_steps, hooks=eval_hooks)

如果您使用 fake_dataset 训练模型,请继续进行清理

使用完整的 Imagenet 数据集

本教程使用演示版的完整 ImageNet 数据集,该数据集又称为 fake_imagenet。此演示版本可用于测试教程,同时降低通常与使用完整 ImageNet 数据集运行模型相关的存储空间和时间要求。如果要查看如何使用完整的 ImageNet 数据集运行模型,请按照这些说明进行操作。

您的本地计算机或虚拟机上需要具有大约 300GB 的可用空间才能使用完整的 ImageNet 数据集。如果你使用 ctpu up 来设置虚拟机,它会默认分配 250GB。您可以通过以下两种方式之一来增加虚拟机磁盘大小:

  • 使用要分配的大小(以 GB 为单位)在 ctpu up 命令行上指定 --disk-size-gb 标志。
  • 按照 Compute Engine 指南向您的虚拟机添加磁盘
    • 删除实例时设置为删除磁盘,以确保在您移除虚拟机后,相应磁盘也会一并移除。
    • 记下新磁盘的路径,例如 /mnt/disks/mnt-dir

下载并转换 ImageNet 数据:

  1. 注册一个 ImageNet 帐号。记住您在创建该帐号时使用的用户名和密码。

  2. 设置 DATA_DIR 环境变量来指向 Cloud Storage 存储分区上的一个路径:

    (vm)$ export DATA_DIR=${STORAGE_BUCKET}
    
  3. 从 GitHub 下载 imagenet_to_gcs.py 脚本:

    $ wget https://raw.githubusercontent.com/tensorflow/tpu/master/tools/datasets/imagenet_to_gcs.py
    
  4. 设置 SCRATCH_DIR 变量以包含该脚本的有效文件。此变量必须指定您的本地机器或 Compute Engine 虚拟机上位置。例如,在本地机器上:

    $ SCRATCH_DIR=./imagenet_tmp_files
    

    或者,如果您正在虚拟机上处理数据:

    (vm)$ SCRATCH_DIR=/mnt/disks/mnt-dir/imagenet_tmp_files
    
  5. 运行 imagenet_to_gcs.py 脚本以下载 ImageNet 数据、设置其数据格式并将其上传到存储分区。将 [USERNAME][PASSWORD] 替换为您用于创建 ImageNet 帐号的用户名和密码。

    $ pip install google-cloud-storage
    $ python imagenet_to_gcs.py \
      --project=$PROJECT \
      --gcs_output_path=$DATA_DIR \
      --local_scratch_dir=$SCRATCH_DIR \
      --imagenet_username=[USERNAME] \
      --imagenet_access_key=[PASSWORD]
    

或者,如果已下载 JPEG 格式的原始数据,则可以提供直接 raw_data_directory 路径。如果已提供用于训练或验证数据的原始数据目录,其格式应为:

训练子目录名称(例如,n03062245)是“WordNet ID”(wnid)。ImageNet APIsynset_labels.txt 文件中显示了 WordNet ID 与其相关联的验证标签之间的映射。此上下文中的同义词集是视觉上类似的一组图片。

注意:下载和预处理数据可能需要 10 小时或更长时间,具体取决于您的网络和计算机速度。请勿中断该脚本。

该脚本处理完毕后,系统将显示类似如下的消息:

2018-02-17 14:30:17.287989: Finished writing all 1281167 images in data set.

该脚本会生成一系列以下形式的目录(用于训练和验证):

${DATA_DIR}/train-00000-of-01024
${DATA_DIR}/train-00001-of-01024
 ...
${DATA_DIR}/train-01023-of-01024

${DATA_DIR}/validation-00000-of-00128
S{DATA_DIR}/validation-00001-of-00128
 ...
${DATA_DIR}/validation-00127-of-00128

将数据上传到您的 Cloud 存储分区后,请运行模型并设置 --data_dir=${DATA_DIR}

清理

为避免系统因本主题中使用的资源向您的 GCP 帐号收取费用,请执行以下操作:

  1. 与 Compute Engine 虚拟机断开连接:

    (vm)$ exit
    

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

  2. 在您的 Cloud Shell 中,使用您在设置 Cloud TPU 时所用的 --zone 标志运行 ctpu delete,以删除 Compute Engine 虚拟机和 Cloud TPU:

    $ ctpu delete [optional: --zone]
    
  3. 运行 ctpu status 确保未分配任何实例,以避免产生不必要的 TPU 使用费用。删除可能需要几分钟时间。如下所示的响应表明已不再有已分配的实例:

    2018/04/28 16:16:23 WARNING: Setting zone to "us-central1-b"
    No instances currently exist.
            Compute Engine VM:     --
            Cloud TPU:             --
    
  4. 如下所示运行 gsutil,将 YOUR-BUCKET-NAME 替换为您为本教程创建的 Cloud Storage 存储分区的名称:

    $ gsutil rm -r gs://YOUR-BUCKET-NAME
    

Inception v4

Inception v4 模型是一种深度神经网络模型,它使用 Inception v3 构件来实现比 Inception v3 更高的准确率。Szegedy 等人的《Inception-v4, Inception-ResNet and the Impact of Residual Connections on Learning》对此进行了介绍。

Inception v4 模型已预安装到您的 Compute Engine 虚拟机上的 /usr/share/tpu/models/experimental/inception/ 目录中。

在以下步骤中,前缀 (vm)$ 表示您应该在 Compute Engine 虚拟机上运行该命令:

  1. 如果您已在 Cloud Shell 标签页中运行了 TensorBoard,则需要另打开一个标签页。在 Cloud Shell 中打开另一个标签页,并在新 shell 中使用 ctpu 连接到您的 Compute Engine 虚拟机:

    $ ctpu up
  2. 设置包含下列某个值的 DATA_DIR 环境变量:

    • 如果您使用的是虚构数据集:

      (vm)$ export DATA_DIR=gs://cloud-tpu-test-datasets/fake_imagenet
      
    • 如果您已将一组训练数据上传到您的 Cloud Storage 存储分区:

      (vm)$ export DATA_DIR=${STORAGE_BUCKET}/data
      
  3. 运行 Inception v4 模型:

    (vm)$ python /usr/share/tpu/models/experimental/inception/inception_v4.py \
        --tpu=$TPU_NAME \
        --learning_rate=0.36 \
        --train_steps=1000000 \
        --iterations=500 \
        --use_tpu=True \
        --use_data=real \
        --train_batch_size=256 \
        --mode=train_and_eval \
        --train_steps_per_eval=2000 \
        --data_dir=${DATA_DIR} \
        --model_dir=${STORAGE_BUCKET}/inception
    • --tpu 用于指定 Cloud TPU 的名称。请注意,ctpu 会将此名称以环境变量 (TPU_NAME) 的形式传递给 Compute Engine 虚拟机。
    • --use_data 用于指定此程序在训练期间必须使用哪种类型的数据(是虚构的还是真实的)。默认值为 fake(虚构数据)。
    • --train_batch_size 将训练批量大小指定为 256。由于 Inception v4 模型大于 Inception v3 模型,因此它必须以更小的批量大小在每个 TPU 核心中运行。
    • --data_dir 用于指定训练输入的 Cloud Storage 路径。如果您使用的是虚构的数据,应用会忽略此参数。
    • --model_dir 用于指定在模型训练期间存储检查点和摘要的目录。如果指定的文件夹不存在,此程序会自行创建。使用 Cloud TPU 时,model_dir 必须是 Cloud Storage 路径 (gs://...)。您可以重复使用现有的文件夹来加载当前检查点数据和存储其他检查点。

后续步骤

此页内容是否有用?请给出您的反馈和评价:

发送以下问题的反馈:

此网页
Cloud TPU