LoginSignup
3
5

More than 5 years have passed since last update.

Access Tokenを取得してGoogle Cloud MLでオンライン予測

Last updated at Posted at 2019-01-27

Google APIのAccess Tokenを取得してGoogle Cloud MLでオンライン予測のリクエストを投げています。そのときの記録です。TensorFlow Object Detection APIを使って訓練したモデルを使っています。
記事「Google API の Access Token を手動で取得する」を参考にしています。

関連記事

前提

Google APIが有効化済

手順

1. GCPでOAuthクライアントID作成

Google Cloud Consoleの認証ページにブラウザでアクセスします。
「認証情報を作成」から「OAuthクライアントID」を選択。
10.Authorization01.jpg

「その他」を選んで「名前」を入力して「作成」ボタン押下。
10.Authorization02.jpg

クライアントIDとクライアントシークレットを取得。
10.Authorization03.jpg

OAuthクライアントIDのJSONファイルをダウンロード。
10.Authorization04.jpg

JSONファイルの中身。

{
    "installed": {
        "client_id": "<client_id>.apps.googleusercontent.com",
        "project_id": "cloud-ml01",
        "auth_uri": "https://accounts.google.com/o/oauth2/auth",
        "token_uri": "https://oauth2.googleapis.com/token",
        "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
        "client_secret": "<client_secret>",
        "redirect_uris": [
            "urn:ietf:wg:oauth:2.0:oob",
            "http://localhost"
        ]
    }
}

2. Authorization Code取得

client_idのパラメータを1で取得した値を設定してブラウザで下記のURLでアクセス。
Cloud Machine Learning Engineのスコープ

https://accounts.google.com/o/oauth2/auth?client_id=xxx&redirect_uri=urn:ietf:wg:oauth:2.0:oob&scope=https://www.googleapis.com/auth/cloud-platform&response_type=code&approval_prompt=force&access_type=offline

認証を求められるので、「許可」を選択。画面でAuthorization Codeをコピーして取得。

3. Access Token取得

今度はcurlを使ってAccess Tokenを取得。client_idとclient_secret、redirect_uriはjsonにある値を設定。codeは2で取得したAuthorization Codeを設定。

curl -k -d client_id=xxx -d client_secret=xxx -d redirect_uri=xxx -d grant_type=authorization_code -d code=xxxxx https://accounts.google.com/o/oauth2/token

JSON形式でAccess Token取得。

{
  "access_token": "xxx",
  "expires_in": 3600,
  "refresh_token": "xxx",
  "scope": "https://www.googleapis.com/auth/cloud-platform",
  "token_type": "Bearer"
}

4. Httpのテスト(Postman)

Postmanを使ってHttpでのリクエストテストをします。
ヘッダのAuthorizationにBearerに続いてAccess Tokenを貼り付けます(BearerとAccess Tokenの間にスペースが必要)。

{
    "instances": [
        {
            "inputs":[[[numpy形式]]]
        }
    ]
}

ちなみに画像のnumpy形式を出力するために以下のpythonプログラムを作成。どうしてもデータ量が重くなるので、10kb程度の画像を使っています。pillowとnumpyをインストールしたpython3.5.6環境で実行しています。

from PIL import Image
import numpy as np
import json

def load_image_into_numpy_array(image):
  (im_width, im_height) = image.size
  return np.array(image.getdata()).reshape(
      (im_height, im_width, 3)).astype(np.uint8)

image = Image.open(r'C:\tmp\tensorflow\od\horikawa\test01.jpg')
image_np = load_image_into_numpy_array(image)
print(image_np.shape)

b = image_np.tolist()
json_file = r"C:\tmp\image.json"

with open(json_file, 'w', encoding='utf-8') as f:
    instance = {"instances":[{ "inputs": b} ]}
    json.dump(instance, f , sort_keys=True)
    f.write("\n")

print(json.dumps(instance))

おまけ

Google公式のサンプルを参考にpythonでhttpを投げるとこんな感じです。コードが汚くてすいません。前提として「認証情報設定」に従ってサービスアカウントを作成して秘密鍵をjosn形式でダウンロードしておく必要があります。

import base64, json, httplib2, six, googleapiclient.discovery
from oauth2client.service_account import ServiceAccountCredentials
from googleapiclient import errors
from PIL import Image
import numpy as np

def load_image_into_numpy_array(image):
    (im_width, im_height) = image.size
    return np.array(image.getdata()).reshape(
      (im_height, im_width, 3)).astype(np.uint8)

# [START predict_json]
def predict_json():
    """Send json data to a deployed model for prediction.
    Args:
        project (str): project where the Cloud ML Engine Model is deployed.
        model (str): model name.
        instances ([Mapping[str: Any]]): Keys should be the names of Tensors
            your deployed model expects as inputs. Values should be datatypes
            convertible to Tensors, or (potentially nested) lists of datatypes
            convertible to tensors.
        version: str, version of the model to target.
    Returns:
        Mapping[str: any]: dictionary of prediction results defined by the
            model.
    """
    # Create the ML Engine service object.
    # To authenticate set the environment variable
    # GOOGLE_APPLICATION_CREDENTIALS=<path_to_service_account_file>
    SCOPES = ['https://www.googleapis.com/auth/cloud-platform']
#   API & Services -> Credentials -> Create Credential -> service account key
#   Set json file
    SERVICE_ACCOUNT_FILE = r'C:\xxxx.json'

    credentials = ServiceAccountCredentials.from_json_keyfile_name(
        SERVICE_ACCOUNT_FILE, scopes=SCOPES)

    # Need to set timeout, since prediction takes time
    http = httplib2.Http(timeout=2000)
    http = credentials.authorize(http)
    service = googleapiclient.discovery.build('ml', 'v1', http=http)

    #use default version,  change project name and model name
    name = 'projects/{}/models/{}'.format('project name', 'model name')

    image = Image.open(r'C:\test01.jpg')
    print(image)
    image_np = load_image_into_numpy_array(image)
    print(image_np.shape)
    image_list = image_np.tolist()

    print('predict start:'+ name)
    response = service.projects().predict(
            name=name,
            body={'instances':[ { "inputs": image_list} ]}
        ).execute()

    print('predict end:'+ name)

    if 'error' in response:
        raise RuntimeError(response['error'])

    json_dump_data = json.dumps(response['predictions'])
    json_data = json.loads(json_dump_data)

    return json_data

def main():
    """Send user input to the prediction service."""
    try:
        result = predict_json()
    except RuntimeError as err:
        print(str(err))
    return result

if __name__ == '__main__':
    result = main( )
    print(result)
    print(result[0]["detection_scores"][0])
    print(result[0]["num_detections"])
    print(result[0]["detection_boxes"][0])
    print(result[0]["detection_classes"][0])
3
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
5