使用 scikit-learn 和 XGBoost 训练机器学习模型

AI Platform 训练服务会管理云端计算资源,以训练模型。本页面介绍了如何在 AI Platform Training 中使用 scikit-learn 和 XGBoost 训练模型。

概览

在本教程中,您将使用 Iris 数据集训练一个简单的模型来预测花的种类。通过调整模型训练代码,您可以从 Cloud Storage 下载数据并将保存的模型文件上传到 Cloud Storage。然后,您就可以创建训练应用软件包并使用此软件包在 AI Platform Training 上运行训练作业。

如何在 AI Platform Training 上训练模型

完成初始设置过程后,您可以在 AI Platform Training 上训练模型,具体分为三个步骤:

  • 创建 Python 训练模块
    • 添加代码,以从 Cloud Storage 下载您的数据供 AI Platform Training 使用
    • 添加代码,以在 AI Platform Training 完成模型训练后,将模型导出并保存到 Cloud Storage
  • 准备训练应用软件包
  • 提交训练作业

初始设置过程包括:创建 Google Cloud 项目;启用结算功能和 API;设置 Cloud Storage 存储分区以便与 AI Platform Training 配合使用;在本地安装 scikit-learn 或 XGBoost。如果您已完成所有设置和安装步骤,请跳至创建模型训练代码

准备工作

完成以下步骤即可设置 GCP 账号、激活 AI Platform Training API,以及安装并激活 Cloud SDK。

设置 GCP 项目

  1. 登录您的 Google Cloud 账号。如果您是 Google Cloud 新手,请创建一个账号来评估我们的产品在实际场景中的表现。新客户还可获享 $300 赠金,用于运行、测试和部署工作负载。
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

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

  4. Enable the AI Platform Training & Prediction and Compute Engine APIs.

    Enable the APIs

  5. Install the Google Cloud CLI.
  6. To initialize the gcloud CLI, run the following command:

    gcloud init
  7. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

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

  9. Enable the AI Platform Training & Prediction and Compute Engine APIs.

    Enable the APIs

  10. Install the Google Cloud CLI.
  11. To initialize the gcloud CLI, run the following command:

    gcloud init

设置环境

请在以下选项中选择是在 macOS 本地设置环境,还是在 Cloud Shell 的远程环境中设置环境。

如果您是 macOS 用户,我们建议您按照下面的 MACOS 标签页中的说明设置环境。Cloud Shell 适用于 macOS、Linux 和 Windows 系统,在 CLOUD SHELL 标签页中提供。Cloud Shell 可帮助您快速体验 AI Platform Training,但不适用于持续性的开发工作。

macOS

  1. 检查 Python 的安装情况
    确认您是否已安装 Python;如有必要,请安装。

    python -V
  2. 检查 pip 的安装情况
    pip 是 Python 的软件包管理器,包含在当前版本的 Python 中。请运行 pip --version 来检查您是否已安装 pip。如果未安装,请了解如何安装 pip

    您可以使用以下命令升级 pip

    pip install -U pip

    如需了解详情,请参阅 pip 文档

  3. 安装 virtualenv
    virtualenv 是用于创建独立 Python 环境的工具。请运行 virtualenv --version 来检查您是否已安装 virtualenv。如果未安装,请安装 virtualenv

    pip install --user --upgrade virtualenv

    如需为本指南创建一个独立的开发环境,请在 virtualenv 中新建一个虚拟环境。例如,以下命令会激活名为 aip-env 的环境:

    virtualenv aip-env
    source aip-env/bin/activate
  4. 在本教程中,请在虚拟环境中运行其余命令。

    详细了解如何使用 virtualenv。如需退出 virtualenv,请运行 deactivate

Cloud Shell

  1. 打开 Google Cloud 控制台。

    Google Cloud 控制台

  2. 点击控制台窗口顶部的激活 Google Cloud Shell 按钮。

    激活 Google Cloud Shell

    一个 Cloud Shell 会话随即会在控制台底部的新框内打开,并显示命令行提示符。该 Shell 会话可能需要几秒钟来完成初始化。

    Cloud Shell 会话

    您的 Cloud Shell 会话已就绪,可以使用了。

  3. 配置 gcloud 命令行工具以使用您所选的项目。

    gcloud config set project [selected-project-id]

    其中,[selected-project-id] 是您的项目 ID。(忽略中括号)。

安装框架

macOS

在虚拟环境中,可以运行以下命令来安装 AI Platform Training 运行时版本 2.11 中使用的 scikit-learn、XGBoost、Pandas 版本:

(aip-env)$ pip install scikit-learn==1.0.2 xgboost==1.6.2 pandas==1.3.5

通过在上述命令中提供版本号,您可以确保虚拟环境中的依赖项与运行时版本中的依赖项相匹配。这有助于防止您的代码在 AI Platform Training 上运行时出现不符合预期的行为。

如需了解详情、安装选项和问题排查信息,请参阅每个框架的安装说明:

Cloud Shell

运行以下命令可安装 scikit-learn、XGBoost 和 pandas:

pip install --user scikit-learn xgboost pandas

如需了解详情、安装选项和问题排查信息,请参阅每个框架的安装说明:

设置 Cloud Storage 存储桶

您需要使用 Cloud Storage 存储桶来存储训练代码和依赖项。在本教程中,最简单的方法是使用 AI Platform Training 所用的项目中的专用 Cloud Storage 存储桶。

如果您使用其他项目中的存储桶,则必须确保您的 AI Platform Training 服务账号可以访问 Cloud Storage 中的训练代码和依赖项。如果没有适当的权限,您的训练作业就会失败。了解如何授予访问存储空间的权限

请确保在用于运行训练作业的同一区域中使用或设置存储桶。请参阅 AI Platform Training 服务的可用区域

本部分介绍如何创建新存储桶。您可以使用现有存储桶,但它所在区域必须与您计划运行 AI Platform 作业的区域相同。此外,如果该存储桶不属于您用于运行 AI Platform Training 的项目,则您必须明确向 AI Platform Training 服务账号授予访问权限

  1. 为新存储桶指定名称。该名称在 Cloud Storage 的所有存储桶中必须是唯一的。

    BUCKET_NAME="YOUR_BUCKET_NAME"

    例如,使用附加了 -aiplatform 的项目名称:

    PROJECT_ID=$(gcloud config list project --format "value(core.project)")
    BUCKET_NAME=${PROJECT_ID}-aiplatform
  2. 检查您创建的存储桶名称。

    echo $BUCKET_NAME
  3. 为您的存储桶选择一个区域,并设置 REGION 环境变量。

    使用您计划在其中运行 AI Platform Training 作业的区域。请参阅 AI Platform Training 服务的可用区域

    例如,以下代码会创建 REGION 并将其设置为 us-central1

    REGION=us-central1
  4. 创建新的存储分区:

    gcloud storage buckets create gs://$BUCKET_NAME --location=$REGION

创建 Python 训练模块

创建一个文件 (iris_training.py),向其中添加用于训练模型的代码。本部分介绍了训练代码各个部分的作用:

  • 设置和导入
  • 从 Cloud Storage 下载数据
  • 将数据加载到 Pandas 中
  • 训练并保存模型
  • 将保存的模型文件上传到 Cloud Storage

为方便起见,iris_training.py 的完整代码托管在 GitHub 上,方便您在本教程中使用:

设置

从 Python 和 scikit-learn/XGBoost 导入以下库。为 Cloud Storage 存储分区的名称设置变量。

scikit-learn

import datetime
import os
import subprocess
import sys
import pandas as pd
from sklearn import svm
from sklearn.externals import joblib

# Fill in your Cloud Storage bucket name
BUCKET_NAME = '<YOUR_BUCKET_NAME>'

XGBoost

import datetime
import os
import subprocess
import sys
import pandas as pd
import xgboost as xgb

# Fill in your Cloud Storage bucket name
BUCKET_NAME = '<YOUR_BUCKET_NAME>'

从 Cloud Storage 下载数据

在典型的开发过程中,您会将自己的数据上传到 Cloud Storage,以便 AI Platform Training 可以访问这些数据。本教程中的数据托管在公开的 Cloud Storage 存储分区中:gs://cloud-samples-data/ai-platform/iris/

以下代码使用 gsutil 下载数据,然后将数据从 gsutil 转移到 stdout

scikit-learn

iris_data_filename = 'iris_data.csv'
iris_target_filename = 'iris_target.csv'
data_dir = 'gs://cloud-samples-data/ml-engine/iris'

# gsutil outputs everything to stderr so we need to divert it to stdout.
subprocess.check_call(['gsutil', 'cp', os.path.join(data_dir,
                                                    iris_data_filename),
                       iris_data_filename], stderr=sys.stdout)
subprocess.check_call(['gsutil', 'cp', os.path.join(data_dir,
                                                    iris_target_filename),
                       iris_target_filename], stderr=sys.stdout)

XGBoost

iris_data_filename = 'iris_data.csv'
iris_target_filename = 'iris_target.csv'
data_dir = 'gs://cloud-samples-data/ai-platform/iris'

# gsutil outputs everything to stderr so we need to divert it to stdout.
subprocess.check_call(['gsutil', 'cp', os.path.join(data_dir,
                                                    iris_data_filename),
                       iris_data_filename], stderr=sys.stdout)
subprocess.check_call(['gsutil', 'cp', os.path.join(data_dir,
                                                    iris_target_filename),
                       iris_target_filename], stderr=sys.stdout)

将数据加载到 Pandas 中

使用 pandas 将数据加载到 NumPy 数组中,以使用 scikit-learn 或 XGBoost 进行训练。

scikit-learn

# Load data into pandas, then use `.values` to get NumPy arrays
iris_data = pd.read_csv(iris_data_filename).values
iris_target = pd.read_csv(iris_target_filename).values

# Convert one-column 2D array into 1D array for use with scikit-learn
iris_target = iris_target.reshape((iris_target.size,))

XGBoost

# Load data into pandas, then use `.values` to get NumPy arrays
iris_data = pd.read_csv(iris_data_filename).values
iris_target = pd.read_csv(iris_target_filename).values

# Convert one-column 2D array into 1D array for use with XGBoost
iris_target = iris_target.reshape((iris_target.size,))

训练和保存模型

为 AI Platform Training 创建训练模块,以运行训练作业。在本示例中,训练模块使用 Iris 训练数据(iris_datairis_target)训练模型,并将经过训练的模型导出到文件中,以保存该模型。如果您希望在训练后使用 AI Platform Prediction 获取在线预测结果,则必须根据用于导出模型的库来命名模型文件。如需了解详情,请参阅模型文件的命名要求

scikit-learn

您可以参照有关模型持久性的 scikit-learn 示例,训练并导出模型,如下所示:

# Train the model
classifier = svm.SVC(gamma='auto', verbose=True)
classifier.fit(iris_data, iris_target)

# Export the classifier to a file
model_filename = 'model.joblib'
joblib.dump(classifier, model_filename)

要导出模型,您还可以选择使用 pickle 库,如下所示:

import pickle
with open('model.pkl', 'wb') as model_file:
  pickle.dump(classifier, model_file)

XGBoost

您可以使用 Booster 对象的“save_model”方法导出模型。

# Load data into DMatrix object
dtrain = xgb.DMatrix(iris_data, label=iris_target)

# Train XGBoost model
bst = xgb.train({}, dtrain, 20)

# Export the classifier to a file
model_filename = 'model.bst'
bst.save_model(model_filename)

要导出模型,您还可以选择使用 pickle 库,如下所示:

import pickle
with open('model.pkl', 'wb') as model_file:
  pickle.dump(bst, model_file)

模型文件命名要求

对于在线预测,根据所使用的库,您保存并上传到 Cloud Storage 的模型文件必须命名为 model.pklmodel.joblibmodel.bst。此限制可确保在导入和导出模型时,AI Platform Prediction 均使用相同的模式重建模型。

如果您创建自定义预测例程(测试版),则无此要求。

scikit-learn

导出模型时使用的库 正确的模型名称
pickle model.pkl
sklearn.externals.joblib model.joblib

XGBoost

导出模型时使用的库 正确的模型名称
pickle model.pkl
joblib model.joblib
xgboost.Booster model.bst

为了在未来进行模型迭代,请妥善整理您的 Cloud Storage 存储分区,确保每个新模型都有一个专用目录。

将保存的模型上传到 Cloud Storage

如果您使用的 Cloud Storage 存储分区不在用于运行 AI Platform Training 的 Google Cloud 项目中,确保 AI Platform Training 有权访问您的存储分区

scikit-learn

# Upload the saved model file to Cloud Storage
gcs_model_path = os.path.join('gs://', BUCKET_NAME,
    datetime.datetime.now().strftime('iris_%Y%m%d_%H%M%S'), model_filename)
subprocess.check_call(['gsutil', 'cp', model_filename, gcs_model_path],
    stderr=sys.stdout)

XGBoost

# Upload the saved model file to Cloud Storage
gcs_model_path = os.path.join('gs://', BUCKET_NAME,
    datetime.datetime.now().strftime('iris_%Y%m%d_%H%M%S'), model_filename)
subprocess.check_call(['gsutil', 'cp', model_filename, gcs_model_path],
    stderr=sys.stdout)

创建训练应用软件包

在根据上述代码段创建 iris_training.py 后,创建一个包含 iris_training.py 作为其主模块的训练应用软件包。

创建训练应用软件包的最简单(推荐)方法是在提交您的训练作业时使用 gcloud 打包并上传应用。使用此方法,您需要创建一个非常简单的文件结构,其中包含两个文件:

scikit-learn

在本教程中,训练应用软件包的文件结构应如下所示:

iris_sklearn_trainer/
    __init__.py
    iris_training.py
  1. 在命令行中,在本地创建一个目录:

    mkdir iris_sklearn_trainer
    
  2. 创建一个名为 __init__.py 的空文件:

    touch iris_sklearn_trainer/__init__.py
    
  3. 将训练代码保存为 iris_training.py,并将此文件保存在 iris_sklearn_trainer 目录中。或者,使用 cURL 从 GitHub 下载此文件并保存:

    curl https://raw.githubusercontent.com/GoogleCloudPlatform/cloudml-samples/master/sklearn/iris_training.py > iris_sklearn_trainer/iris_training.py
    

    查看 GitHub 上的完整源代码

  4. 确认您已正确设置训练应用软件包:

    ls ./iris_sklearn_trainer
      __init__.py  iris_training.py
    

XGBoost

在本教程中,训练应用软件包的文件结构应如下所示:

iris_xgboost_trainer/
    __init__.py
    iris_training.py
  1. 在命令行中,在本地创建一个目录:

    mkdir iris_xgboost_trainer
    
  2. 创建一个名为 __init__.py 的空文件:

    touch iris_xgboost_trainer/__init__.py
    
  3. 将训练代码保存为 iris_training.py,并将此文件保存在 iris_xgboost_trainer 目录中。或者,使用 cURL 从 GitHub 下载此文件并保存:

    curl https://raw.githubusercontent.com/GoogleCloudPlatform/cloudml-samples/master/xgboost/iris_training.py > iris_xgboost_trainer/iris_training.py
    

    查看 GitHub 上的完整源代码

  4. 确认您已正确设置训练应用软件包:

    ls ./iris_xgboost_trainer
      __init__.py  iris_training.py
    

详细了解如何打包训练应用

在本地运行训练程序

您可以使用 gcloud ai-platform local train 命令在本地测试训练应用。此步骤是可选的,但有助于调试。

scikit-learn

在命令行中,设置以下环境变量,将 [VALUES-IN-BRACKETS] 替换为适当的值:

TRAINING_PACKAGE_PATH="./iris_sklearn_trainer/"
MAIN_TRAINER_MODULE="iris_sklearn_trainer.iris_training"

在本地测试训练作业:

gcloud ai-platform local train \
  --package-path $TRAINING_PACKAGE_PATH \
  --module-name $MAIN_TRAINER_MODULE

XGBoost

在命令行中,设置以下环境变量,将 [VALUES-IN-BRACKETS] 替换为适当的值:

TRAINING_PACKAGE_PATH="./iris_xgboost_trainer/"
MAIN_TRAINER_MODULE="iris_xgboost_trainer.iris_training"

在本地测试训练作业:

gcloud ai-platform local train \
  --package-path $TRAINING_PACKAGE_PATH \
  --module-name $MAIN_TRAINER_MODULE

提交训练作业

在本部分中,您将使用 gcloud ai-platform jobs submit training 提交训练作业。

指定训练作业参数

为训练作业请求中的每个参数设置以下环境变量:

  • BUCKET_NAME - Cloud Storage 存储分区的名称。
  • JOB_NAME - 作业使用的名称(只能包含混合大小写的字母、数字和下划线,并以字母开头)。例如 iris_scikit_learn_$(date +"%Y%m%d_%H%M%S")iris_xgboost_$(date +"%Y%m%d_%H%M%S")
  • JOB_DIR - 用于训练作业输出文件的 Cloud Storage 位置的路径。例如 gs://$BUCKET_NAME/scikit_learn_job_dirgs://$BUCKET_NAME/xgboost_job_dir
  • TRAINING_PACKAGE_PATH - 训练应用根目录的本地路径。例如 ./iris_sklearn_trainer/./iris_xgboost_trainer/
  • MAIN_TRAINER_MODULE - 指定 AI Platform Training 训练服务应运行的文件。该变量的格式为 [YOUR_FOLDER_NAME.YOUR_PYTHON_FILE_NAME]。例如 iris_sklearn_trainer.iris_trainingiris_xgboost_trainer.iris_training
  • REGION - 用于运行训练作业的区域的名称。请为 AI Platform Training 训练服务使用其中一个可用区域。请确保 Cloud Storage 存储桶位于同一区域。
  • RUNTIME_VERSION - 您必须指定支持 scikit-learn 的 AI Platform Training 运行时版本。在此示例中为 2.11
  • PYTHON_VERSION - 作业使用的 Python 版本。对于本教程,请指定 Python 3.7。
  • SCALE_TIER - 用于运行训练作业的机器的预定义集群规范。在此示例中为 BASIC。您还可以使用自定义容量层级为训练定义您自己的集群配置。

为方便起见,本教程中的环境变量如下所示。

scikit-learn

[VALUES-IN-BRACKETS] 替换为适当的值:

    BUCKET_NAME=[YOUR-BUCKET-NAME]
    JOB_NAME="iris_scikit_learn_$(date +"%Y%m%d_%H%M%S")"
    JOB_DIR=gs://$BUCKET_NAME/scikit_learn_job_dir
    TRAINING_PACKAGE_PATH="./iris_sklearn_trainer/"
    MAIN_TRAINER_MODULE="iris_sklearn_trainer.iris_training"
    REGION=us-central1
    RUNTIME_VERSION=2.11
    PYTHON_VERSION=3.7
    SCALE_TIER=BASIC

XGBoost

[VALUES-IN-BRACKETS] 替换为适当的值:

    BUCKET_NAME=[YOUR-BUCKET-NAME]
    JOB_NAME="iris_xgboost_$(date +"%Y%m%d_%H%M%S")"
    JOB_DIR=gs://$BUCKET_NAME/xgboost_job_dir
    TRAINING_PACKAGE_PATH="./iris_xgboost_trainer/"
    MAIN_TRAINER_MODULE="iris_xgboost_trainer.iris_training"
    REGION=us-central1
    RUNTIME_VERSION=2.11
    PYTHON_VERSION=3.7
    SCALE_TIER=BASIC

提交训练作业请求:

gcloud ai-platform jobs submit training $JOB_NAME \
  --job-dir $JOB_DIR \
  --package-path $TRAINING_PACKAGE_PATH \
  --module-name $MAIN_TRAINER_MODULE \
  --region $REGION \
  --runtime-version=$RUNTIME_VERSION \
  --python-version=$PYTHON_VERSION \
  --scale-tier $SCALE_TIER

您应该会看到类似如下所示的输出:

Job [iris_scikit_learn_[DATE]_[TIME]] submitted successfully.
Your job is still active. You may view the status of your job with the command

  $ gcloud ai-platform jobs describe iris_scikit_learn_[DATE]_[TIME]

or continue streaming the logs with the command

  $ gcloud ai-platform jobs stream-logs iris_scikit_learn_[DATE]_[TIME]

jobId: iris_scikit_learn_[DATE]_[TIME]
state: QUEUED

查看训练日志(可选)

AI Platform Training 会捕获所有 stdoutstderr 流以及日志记录语句。这些日志存储在 Logging 中;在执行期间和之后,您都可以查看这些日志。

要查看训练作业的日志,请执行以下操作:

控制台

  1. 打开 AI Platform Training 作业页面。

    在 Google Cloud 控制台中打开作业

  2. 选择要检查的训练作业的名称。之后您会转到所选训练作业的作业详情页面。

  3. 在作业详情中,选择查看日志链接。之后您会转到 Logging 页面,您可以在该页面中搜索和过滤所选训练作业的日志。

gcloud

您可以使用 gcloud ai-platform jobs stream-logs 在您的终端中查看日志。

gcloud ai-platform jobs stream-logs $JOB_NAME

在 Cloud Storage 中验证模型文件

查看目标模型文件夹的内容,验证已将保存的模型文件上传到 Cloud Storage。

gcloud storage ls gs://$BUCKET_NAME/iris_*

输出示例:

gs://bucket-name/iris_20180518_123815/:
gs://bucket-name/iris_20180518_123815/model.joblib

后续步骤