使用 Keras 建立自訂預測處理常式

Colab 標誌 在 Colab 中以筆記本的形式執行本教學課程 GitHub 標誌 在 GitHub 中查看筆記本

本教學課程說明如何將訓練完成的 Keras 模型部署至 AI Platform,以及如何使用自訂預測處理常式來提供預測,以便您自訂 AI Platform 回應各項預測要求的方式。

在這個範例中,您會透過自訂預測處理常式調整輸入內容來進行預先處理,並將 softmax 機率輸出內容轉換為標籤字串,藉此對輸出內容進行後續處理。

本教學課程將會逐步執行下列幾個步驟:

  • 在本機訓練簡易的 Keras 模型
  • 建立自訂預測處理常式並部署到 AI Platform
  • 提供來自該部署的預測要求

資料集

本教學課程會使用 R.A. Fisher 的鳶尾花 (Iris) 資料集,這是一個很小的資料集,非常適合用來嘗試機器學習技術。每個例項都具備四個數值特徵 (也就是某一朵花的不同測量結果) 與目標標籤,此標籤可將該花標記為下列三個鳶尾花品種之一:Iris setosa、Iris versicolour 或 Iris virginica。

本教學課程使用 scikit-learn 程式庫包含的 Iris 資料集副本

目標

目標是訓練模型以花卉的測量資料當做輸入內容,預測鳶尾花品種。

本教學課程的內容偏重於透過 AI Platform 使用這個模型,而不在模型本身的設計。

費用

本教學課程使用的 Google Cloud Platform (GCP) 計費元件包括:

  • AI Platform
  • Cloud Storage

瞭解 AI Platform 定價Cloud Storage 定價,並在 Pricing Calculator 中依據預測用量估算費用。

事前準備

在 AI Platform 訓練和部署模型之前,您必須先做好下列準備:

  • 設定本機開發環境。
  • 設定 GCP 專案並啟用計費功能和必要的 API。
  • 建立 Cloud Storage 值區儲存您的訓練套件和訓練過的模型。

設定本機開發環境

您需要下列資源才能完成本教學課程:

  • Python 3
  • virtualenv
  • Cloud SDK

如需如何才能符合相關需求條件的詳細操作說明,請參閱 Google Cloud 的設定 Python 開發環境指南。下列是精簡版的操作步驟:

  1. 安裝 Python 3。

  2. 安裝 virtualenv 並建立使用 Python 3 的虛擬環境。

  3. 啟用上個步驟建立的虛擬環境。

  4. 完成下一節所述步驟安裝 Cloud SDK。

設定 GCP 專案

  1. 登入您的 Google 帳戶。

    如果您沒有帳戶,請申請新帳戶

  2. 選取或建立 Google Cloud Platform 專案。

    前往「Manage resources」(管理資源) 頁面

  3. 請確認您已啟用 Google Cloud Platform 專案的計費功能。

    瞭解如何啟用計費功能

  4. 啟用AI Platform ("Cloud Machine Learning Engine") and Compute Engine API。

    啟用 API

  5. 安裝並初始化 Cloud SDK

驗證 GCP 帳戶

如要設定驗證方法,您必須建立服務帳戶金鑰,並為該服務帳戶金鑰的檔案路徑設定環境變數。

  1. 為驗證方法建立服務帳戶金鑰:
    1. 前往 GCP 主控台的「Create service account key」(建立服務帳戶金鑰) 頁面。

      前往「Create service account key」(建立服務帳戶金鑰) 頁面
    2. 自「Service account」(服務帳戶) 下拉式清單選取 [New service account] (新增服務帳戶)
    3. 在「Service account name」(服務帳戶名稱) 欄位中輸入名稱。
    4. 在「Role」(角色) 下拉式清單中,依序選取 [Machine Learning Engine] > [ML Engine Admin] (ML Engine 管理員),然後再依序選取 [Storage] (儲存空間) > [Storage Object Admin] (儲存空間物件管理員)

      注意:「Role」(角色) 欄位會將資源的存取權限授予服務帳戶。您稍後可以使用 GCP 主控台查看及變更這個欄位。如果您要開發正式版應用程式,除了依序點選 [Machine Learning Engine] > [ML Engine Admin] (ML Engine 管理員) 和 [Storage] (儲存空間) > [Storage Object Admin] (儲存空間物件管理員) 之外,您可能須指定更精細的權限。詳情請參閱 AI Platform 的存取權控管
    5. 按一下 [Create] (建立),隨後一個包含您金鑰的 JSON 檔案就會下載到電腦中。
  2. 將環境變數 GOOGLE_APPLICATION_CREDENTIALS 設為包含服務帳戶金鑰的 JSON 檔案路徑。此變數僅適用於您目前的殼層工作階段,因此如果您開啟新的工作階段,就必須再次設定變數。

建立 Cloud Storage 值區

如要部署自訂預測處理常式,您必須將訓練過的模型成品以及您的自訂程式碼上傳到 Cloud Storage。

將 Cloud Storage 值區名稱設定為環境變數。所有 Cloud Storage 值區中的這類名稱都不得重複:

BUCKET_NAME="your-bucket-name"

選取有提供 AI Platform 訓練和預測的地區,然後建立另一個環境變數。

REGION="us-central1"

在這個地區建立 Cloud Storage 值區,之後再使用相同地區進行訓練和預測。如果還沒有值區,請執行下列指令來建立值區:

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

建構和訓練 Keras 模型

原始形式的資料,通常無法用來訓練機器學習模型;即使能夠採用,在訓練前預先處理過資料,比較可以改善模型。

假設您希望預測的輸入內容採用和訓練資料相同的格式,那麼您就必須在訓練和預測期間套用相同的預先處理,以確保模型會做出一致的預測。

本節會建立預先處理模組並用來進行訓練,接著匯出預先處理工具 (其中具備訓練期間學習到的特性),以便稍後在自訂預測處理常式中使用。

安裝依附元件以進行本機訓練

在本機進行訓練需要下列幾項依附元件:

pip install numpy scikit-learn 'tensorflow>=1.13,<2'

編寫預先處理工具

按比例調整訓練資料,讓數值特徵欄的平均值為 0、標準差為 1,這樣有助改善模型

建立 preprocess.py,其中包含的類別可用於執行這項調整作業:

import numpy as np

class MySimpleScaler(object):
  def __init__(self):
    self._means = None
    self._stds = None

  def preprocess(self, data):
    if self._means is None: # during training only
      self._means = np.mean(data, axis=0)

    if self._stds is None: # during training only
      self._stds = np.std(data, axis=0)
      if not self._stds.all():
        raise ValueError('At least one column has standard deviation of 0.')

    return (data - self._means) / self._stds

請注意,MySimpleScaler 的例項會在首次使用時儲存每個特徵欄的平均值和標準差,接著使用這些摘要統計資料調整後續遇到的資料。

這樣您就能儲存訓練分佈的特性,並且在預測時用來進行相同的預先處理。

訓練模型

接著,請使用 preprocess.MySimpleScaler 預先處理鳶尾花資料,再透過 Keras 訓練簡易的類神經網路。

最後,將訓練完成的 Keras 模型匯出為 HDF5 (.h5) 檔案,並將 MySimpleScaler 項目匯出為 pickle (.pkl) 檔案:

import pickle

from sklearn.datasets import load_iris
import tensorflow as tf

from preprocess import MySimpleScaler

iris = load_iris()
scaler = MySimpleScaler()
num_classes = len(iris.target_names)
X = scaler.preprocess(iris.data)
y = tf.keras.utils.to_categorical(iris.target, num_classes=num_classes)

model = tf.keras.Sequential()
model.add(tf.keras.layers.Dense(25, activation=tf.nn.relu))
model.add(tf.keras.layers.Dense(25, activation=tf.nn.relu))
model.add(tf.keras.layers.Dense(num_classes, activation=tf.nn.softmax))
model.compile(
  optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
model.fit(X, y, epochs=10, batch_size=1)

model.save('model.h5')
with open ('preprocessor.pkl', 'wb') as f:
  pickle.dump(scaler, f)

部署自訂預測處理常式

請執行下列步驟部署自訂預測處理常式,以便從訓練過的模型提供預測:

  • 建立要用於處理要求的自訂預測者
  • 封裝您的預測者和預先處理模組
  • 將模型成品及自訂程式碼上傳到 Cloud Storage
  • 將自訂預測處理常式部署到 AI Platform

建立自訂預測者

如要部署自訂預測處理常式,您必須建立實作預測者介面的類別。這樣 AI Platform 就能知道如何載入您的模型以及如何處理預測要求。

將下列程式碼寫入 predictor.py

import os
import pickle

import numpy as np
from sklearn.datasets import load_iris
import tensorflow as tf

class MyPredictor(object):
  def __init__(self, model, preprocessor):
    self._model = model
    self._preprocessor = preprocessor
    self._class_names = load_iris().target_names

  def predict(self, instances, **kwargs):
    inputs = np.asarray(instances)
    preprocessed_inputs = self._preprocessor.preprocess(inputs)
    outputs = self._model.predict(preprocessed_inputs)
    if kwargs.get('probabilities'):
      return outputs.tolist()
    else:
      return [self._class_names[index] for index in np.argmax(outputs, axis=1)]

  @classmethod
  def from_path(cls, model_dir):
    model_path = os.path.join(model_dir, 'model.h5')
    model = tf.keras.models.load_model(model_path)

    preprocessor_path = os.path.join(model_dir, 'preprocessor.pkl')
    with open(preprocessor_path, 'rb') as f:
      preprocessor = pickle.load(f)

    return cls(model, preprocessor)

請注意,除了使用您在訓練期間定義的預先處理工具外,此預測者還會執行後處理步驟,將類神經網路的 softmax 輸出 (代表每個標籤的機率正確無誤的陣列) 轉換為具有最高機率的標籤。

但是如果預測者收到值為 Trueprobabilities 關鍵字引數,就會改成傳回機率陣列。本教學課程最後一個部分說明如何提供此關鍵字引數。

封裝自訂程式碼

您必須將 predictor.pypreprocess.py 封裝為 .tar.gz 來源發行版本套件,並提供套件給 AI Platform,以便其使用自訂程式碼來提供預測。

編寫下列 setup.py 來定義您的套件:

from setuptools import setup

setup(
    name='my_custom_code',
    version='0.1',
    scripts=['predictor.py', 'preprocess.py'])

然後,執行下列指令來建立 dist/my_custom_code-0.1.tar.gz

python setup.py sdist --formats=gztar

將模型成品和自訂程式碼上傳到 Cloud Storage

AI Platform 必須先存取 Cloud Storage 中的下列檔案,您才能部署要提供的模型:

  • model.h5 (模型成品)
  • preprocessor.pkl (模型成品)
  • my_custom_code-0.1.tar.gz (自訂程式碼)

模型成果必須統一儲存在模型目錄中,以便預測者存取為from_path 類別方法中的 model_dir 引數。不過,您可以自行選擇是否將自訂程式碼儲存在相同目錄中。執行下列指令來上傳檔案:

gsutil cp ./dist/my_custom_code-0.1.tar.gz gs://$BUCKET_NAME/custom_prediction_routine_tutorial/my_custom_code-0.1.tar.gz
gsutil cp model.h5 preprocessor.pkl gs://$BUCKET_NAME/custom_prediction_routine_tutorial/model/

部署自訂預測處理常式

建立「模型」資源和「版本」資源,以便部署自訂預測處理常式。首先,請使用您的資源名稱來定義環境變數:

MODEL_NAME='IrisPredictor'
VERSION_NAME='v1'

然後建立模型:

gcloud ai-platform models create $MODEL_NAME \
  --regions $REGION

接著建立版本。在這個步驟中,您會提供已上傳到 Cloud Storage 的成果和自訂程式碼的路徑:

gcloud components install beta

gcloud beta ai-platform versions create $VERSION_NAME \
  --model $MODEL_NAME \
  --runtime-version 1.13 \
  --python-version 3.5 \
  --origin gs://$BUCKET_NAME/custom_prediction_routine_tutorial/model/ \
  --package-uris gs://$BUCKET_NAME/custom_prediction_routine_tutorial/my_custom_code-0.1.tar.gz \
  --prediction-class predictor.MyPredictor

進一步瞭解部署自訂預測處理常式時必須指定的選項

提供線上預測

請傳送線上預測要求來嘗試部署。首先,安裝 Python 適用的 Google API 用戶端程式庫:

pip install --upgrade google-api-python-client

接著,請執行下列 Python 程式碼,將兩個鳶尾花資料項目傳送至已部署的版本:

import googleapiclient.discovery

instances = [
  [6.7, 3.1, 4.7, 1.5],
  [4.6, 3.1, 1.5, 0.2],
]

service = googleapiclient.discovery.build('ml', 'v1')
name = 'projects/{}/models/{}/versions/{}'.format(PROJECT_ID, MODEL_NAME, VERSION_NAME)

response = service.projects().predict(
    name=name,
    body={'instances': instances}
).execute()

if 'error' in response:
    raise RuntimeError(response['error'])
else:
  print(response['predictions'])
['versicolor', 'setosa']

傳送關鍵字引數

您將預測要求傳送至自訂預測處理常式時,可以在要求內文中提供其他欄位。預測者的 predict 方法會收到這些欄位,並將其當做 **kwargs 字典的欄位。

下列程式碼會傳送與先前相同的要求,不過這次的要求內文中新增了 probabilities 欄位:

response = service.projects().predict(
    name=name,
    body={'instances': instances, 'probabilities': True}
).execute()

if 'error' in response:
    raise RuntimeError(response['error'])
else:
  print(response['predictions'])
[[0.0019204545533284545, 0.8623144626617432, 0.13576509058475494], [0.999488353729248, 0.000511515187099576, 1.293626752385535e-07]]

清除所用資源

如要清除此專案中使用的所有 GCP 資源,您可以刪除針對教學課程使用的 GCP 專案

或者,您也可以執行下列指令來清除個別資源:

# Delete version resource
gcloud ai-platform versions delete $VERSION_NAME --quiet --model $MODEL_NAME

# Delete model resource
gcloud ai-platform models delete $MODEL_NAME --quiet

# Delete Cloud Storage objects that were created
gsutil -m rm -r gs://$BUCKET_NAME/custom_prediction_routine_tutorial

後續步驟

本頁內容對您是否有任何幫助?請提供意見:

傳送您對下列選項的寶貴意見...

這個網頁
Google Cloud Machine Learning 說明文件