在 AI Platform Training 上使用 scikit-learn 进行训练

AI Platform Training 训练服务会管理云端计算资源,以训练模型。本页面介绍了使用 AI Platform Training 训练 scikit-learn 模型的过程。

在本教程中,我们将训练一个简单的模型,以根据人口普查收入数据集预测个人收入水平。您可以在本地创建训练应用,将训练应用上传到 Cloud Storage,然后提交训练作业。AI Platform Training 训练服务会将其输出写入您的 Cloud Storage 存储分区,并在 Logging 中创建日志。

此外,我们还在 GitHub 上以 Jupyter 笔记本形式提供了本页面上的内容。

如何在 AI Platform Training 上训练模型

您可以按三个步骤在 AI Platform Training 上训练模型:

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

准备工作

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

设置 GCP 项目

  1. 登录您的 Google Cloud 帐号。如果您是 Google Cloud 新手,请创建一个帐号来评估我们的产品在实际场景中的表现。新客户还可获享 $300 赠金,用于运行、测试和部署工作负载。
  2. 在 Google Cloud Console 的项目选择器页面上,选择或创建一个 Google Cloud 项目。

    转到“项目选择器”

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

  4. 启用 AI Platform Training & Prediction and Compute Engine API。

    启用 API

  5. 安装并初始化 Cloud SDK
  6. 在 Google Cloud Console 的项目选择器页面上,选择或创建一个 Google Cloud 项目。

    转到“项目选择器”

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

  8. 启用 AI Platform Training & Prediction and Compute Engine API。

    启用 API

  9. 安装并初始化 Cloud SDK

设置环境

请在以下选项中选择是在 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 Console。

    Google Cloud Console

  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.7 中使用的 scikit-learn 和 Pandas 版本:

(aip-env)$ pip install scikit-learn==1.0 pandas==1.3.3

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

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

Cloud Shell

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

pip install --user scikit-learn 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. 创建新的存储分区:

    gsutil mb -l $REGION gs://$BUCKET_NAME

关于数据

本示例中用于训练的人口普查收入数据集UC Irvine 机器学习存储库托管。

人口普查数据由 Lichman, M. (2013) 提供。UCI 机器学习存储库 http://archive.ics.uci.edu/ml。加利福尼亚州欧文市:加州大学信息与计算机科学学院。此数据集公开提供给所有人使用,但使用者必须遵守数据集来源规定的以下条款:http://archive.ics.uci.edu/ml。Google“按原样”提供此数据集,不作任何明示或暗示的保证。对于因使用数据集而导致的任何直接或间接损害,Google 不承担任何责任。

为方便起见,我们将数据托管在公开的 Cloud Storage 存储分区中:gs://cloud-samples-data/ai-platform/sklearn/census_data/,您可以在 Python 训练文件中下载这些数据。

创建 Python 模型文件

您可以在 GitHub 上找到本部分使用的所有训练代码:train.py

本部分的其余内容说明了训练代码的用途。

设置

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

import datetime
import pandas as pd
import joblib

from google.cloud import storage

from sklearn.ensemble import RandomForestClassifier
from sklearn.feature_selection import SelectKBest
from sklearn.pipeline import FeatureUnion
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import LabelBinarizer

# TODO: REPLACE 'YOUR_BUCKET_NAME' with your GCS Bucket name.
BUCKET_NAME = 'YOUR_BUCKET_NAME'

从 Cloud Storage 下载数据

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

您可以利用下面的代码,下载训练数据集 adult.data。(adult.test 提供了评估数据,但本教程未使用这些数据。)

# Public bucket holding the census data
bucket = storage.Client().bucket('cloud-samples-data')

# Path to the data inside the public bucket
blob = bucket.blob('ai-platform/sklearn/census_data/adult.data')
# Download the data
blob.download_to_filename('adult.data')

添加模型代码

您可以利用模型训练代码,执行一些基本步骤:

  • 定义和加载数据
  • 将分类特征转换为数字特征
  • 使用 scikit-learn 流水线提取数字特征
  • 将模型导出并保存到 Cloud Storage

定义和加载数据

# Define the format of your input data including unused columns (These are the columns from the census data files)
COLUMNS = (
    'age',
    'workclass',
    'fnlwgt',
    'education',
    'education-num',
    'marital-status',
    'occupation',
    'relationship',
    'race',
    'sex',
    'capital-gain',
    'capital-loss',
    'hours-per-week',
    'native-country',
    'income-level'
)

# Categorical columns are columns that need to be turned into a numerical value to be used by scikit-learn
CATEGORICAL_COLUMNS = (
    'workclass',
    'education',
    'marital-status',
    'occupation',
    'relationship',
    'race',
    'sex',
    'native-country'
)

# Load the training census dataset
with open('./adult.data', 'r') as train_data:
    raw_training_data = pd.read_csv(train_data, header=None, names=COLUMNS)

# Remove the column we are trying to predict ('income-level') from our features list
# Convert the Dataframe to a lists of lists
train_features = raw_training_data.drop('income-level', axis=1).values.tolist()
# Create our training labels list, convert the Dataframe to a lists of lists
train_labels = (raw_training_data['income-level'] == ' >50K').values.tolist()

将分类特征转换为数字特征

# Since the census data set has categorical features, we need to convert
# them to numerical values. We'll use a list of pipelines to convert each
# categorical column and then use FeatureUnion to combine them before calling
# the RandomForestClassifier.
categorical_pipelines = []

# Each categorical column needs to be extracted individually and converted to a numerical value.
# To do this, each categorical column will use a pipeline that extracts one feature column via
# SelectKBest(k=1) and a LabelBinarizer() to convert the categorical value to a numerical one.
# A scores array (created below) will select and extract the feature column. The scores array is
# created by iterating over the COLUMNS and checking if it is a CATEGORICAL_COLUMN.
for i, col in enumerate(COLUMNS[:-1]):
    if col in CATEGORICAL_COLUMNS:
        # Create a scores array to get the individual categorical column.
        # Example:
        #  data = [39, 'State-gov', 77516, 'Bachelors', 13, 'Never-married', 'Adm-clerical',
        #         'Not-in-family', 'White', 'Male', 2174, 0, 40, 'United-States']
        #  scores = [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        #
        # Returns: [['State-gov']]
        # Build the scores array.
        scores = [0] * len(COLUMNS[:-1])
        # This column is the categorical column we want to extract.
        scores[i] = 1
        skb = SelectKBest(k=1)
        skb.scores_ = scores
        # Convert the categorical column to a numerical value
        lbn = LabelBinarizer()
        r = skb.transform(train_features)
        lbn.fit(r)
        # Create the pipeline to extract the categorical feature
        categorical_pipelines.append(
            ('categorical-{}'.format(i), Pipeline([
                ('SKB-{}'.format(i), skb),
                ('LBN-{}'.format(i), lbn)])))

使用 scikit-learn 流水线提取数字特征

# Create pipeline to extract the numerical features
skb = SelectKBest(k=6)
# From COLUMNS use the features that are numerical
skb.scores_ = [1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0]
categorical_pipelines.append(('numerical', skb))

# Combine all the features using FeatureUnion
preprocess = FeatureUnion(categorical_pipelines)

# Create the classifier
classifier = RandomForestClassifier()

# Transform the features and fit them to the classifier
classifier.fit(preprocess.transform(train_features), train_labels)

# Create the overall model as a single pipeline
pipeline = Pipeline([
    ('union', preprocess),
    ('classifier', classifier)
])

将模型导出并保存到 Cloud Storage

如果您的 Cloud Storage 存储分区位于您用于 AI Platform Training 的项目中,则 AI Platform Training 可对您的存储分区执行读写操作。否则,您需要确保用于运行 AI Platform Training 的项目可以访问您的 Cloud Storage 存储分区。了解如何授予访问存储空间的权限

如果您要使用模型文件请求通过 AI Platform Prediction 进行在线预测,请确保将模型文件命名为 model.pklmodel.joblib

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

# Upload the model to GCS
bucket = storage.Client().bucket(BUCKET_NAME)
blob = bucket.blob('{}/{}'.format(
    datetime.datetime.now().strftime('census_%Y%m%d_%H%M%S'),
    model))
blob.upload_from_filename(model)

验证上传至 Cloud Storage 的模型文件(可选)

您可以在命令行中,查看目标模型文件夹中的内容,验证是否已将模型文件上传到 Cloud Storage。如果您还没有为存储分区名称设置环境变量 (BUCKET_NAME),请执行这一操作。

gsutil ls gs://$BUCKET_NAME/census_*

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

gs://[YOUR-PROJECT-ID]/census_[DATE]_[TIME]/model.joblib

创建训练应用软件包

创建训练应用软件包的最简单(推荐)方法是在提交您的训练作业时使用 gcloud 封装并上传应用。使用此方法,您可以创建一个非常简单的文件结构,其中只有两个文件。在本教程中,训练应用软件包的文件结构应与以下示例类似:

census_training/
    __init__.py
    train.py
  1. 在本地创建目录:

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

    touch census_training/__init__.py
    
  3. 将训练代码保存在一个 Python 文件中,然后将该文件保存在 census_training 目录内。请参阅 train.py 的示例代码。您可以使用 cURL 下载并保存该文件:

    curl https://raw.githubusercontent.com/GoogleCloudPlatform/cloudml-samples/master/sklearn/notebooks/census_training/train.py > census_training/train.py
    

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

提交训练作业

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

指定训练作业参数

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

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

为方便起见,本教程中的环境变量如下所示。将 [VALUES-IN-BRACKETS] 替换为适当的值:

PROJECT_ID=[YOUR-PROJECT-ID]
BUCKET_NAME=[YOUR-BUCKET-NAME]
JOB_NAME=census_training_$(date +"%Y%m%d_%H%M%S")
JOB_DIR=gs://$BUCKET_NAME/scikit_learn_job_dir
TRAINING_PACKAGE_PATH="[YOUR-LOCAL-PATH-TO-TRAINING-PACKAGE]/census_training/"
MAIN_TRAINER_MODULE=census_training.train
REGION=us-central1
RUNTIME_VERSION=2.6
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 [census_training_[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 census_training_[DATE]_[TIME]

or continue streaming the logs with the command

  $ gcloud ai-platform jobs stream-logs census_training_[DATE]_[TIME]
jobId: census_training_[DATE]_[TIME]
state: QUEUED

查看训练日志(可选)

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

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

控制台

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

    在 Cloud Console 中打开作业

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

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

gcloud

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

gcloud ai-platform jobs stream-logs $JOB_NAME

后续步骤