Понимание входных данных для пользовательских процедур прогнозирования платформы Google ai - PullRequest
1 голос
/ 22 мая 2019

Я следую этой документации по процедурам пользовательского прогнозирования и пытаюсь понять, как выглядят входные данные для процедуры пользовательского прогнозирования. Код для отправки ввода выглядит следующим образом:

instances = [
        [6.7, 3.1, 4.7, 1.5],
        [4.6, 3.1, 1.5, 0.2],
    ]
service = discovery.build('ml', 'v1')
name = 'projects/{}/models/{}'.format(project, model)

if version is not None:
    name += '/versions/{}'.format(version)

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

и Predictor.py на данный момент очень просто. Я просто пытаюсь понять, как выглядит вход ...

class Predictor(object):
    """An example Predictor for an AI Platform custom prediction routine."""

    def __init__(self, model):
        self._model = model

    def predict(self, instances, **kwargs):

        inputs = np.asarray(instances)
        if kwargs.get('max'):
            return np.argmax(inputs, axis=1)

        return np.sum(inputs)


    @classmethod
    def from_path(cls, model_dir):
        return cls(None)

Но когда я пытаюсь получить ответ, я получаю следующую ошибку:

{
  "error": "Prediction failed: unknown error."
}

Кроме того, чрезвычайно сложно отлаживать код, потому что нет способа войти в код или распечатать журналы ... Я понятия не имею, что происходит ... Как выглядит ввод? как мне получить к ним доступ? Это всего лишь простой тест, но в конце концов я хочу отправить изображения, тогда отладку будет еще сложнее. Как я получу их? Как я буду предварительно обрабатывать их в препроцессоре? Давайте предположим, что пропорции, которые я сделал во время тренировки, выглядят так:

data = cv2.imread(str(img_path))
data = cv2.resize(data, (224, 224))
data = cv2.cvtColor(data, cv2.COLOR_BGR2RGB)
x = data.astype(np.float32) / 255.
return np.expand_dims(x, axis=0)

Как выглядит instances объект, чтобы я мог соответственно построить препроцессор? заранее спасибо.

Ответы [ 2 ]

1 голос
/ 22 мая 2019

Я создаю новый пример для пользовательского прогнозирования, который может быть полезен для отладки: сначала я записываю файл локально через блокнот (Colab)

%%writefile model_prediction.py

import numpy as np
import os
import pickle
import pandas as pd
import importlib

class CustomModelPrediction(object):
    _UNUSED_COLUMNS = ['fnlwgt', 'education', 'gender']
    _CSV_COLUMNS = [
        'age', 'workclass', 'fnlwgt', 'education', 'education_num',
        'marital_status', 'occupation', 'relationship', 'race', 'gender',
        'capital_gain', 'capital_loss', 'hours_per_week', 'native_country',
        'income_bracket'
    ]
    _CATEGORICAL_TYPES = {
        'workclass': pd.api.types.CategoricalDtype(categories=[
            'Federal-gov', 'Local-gov', 'Never-worked', 'Private',
            'Self-emp-inc',
            'Self-emp-not-inc', 'State-gov', 'Without-pay'
        ]),
        'marital_status': pd.api.types.CategoricalDtype(categories=[
            'Divorced', 'Married-AF-spouse', 'Married-civ-spouse',
            'Married-spouse-absent', 'Never-married', 'Separated', 'Widowed'
        ]),
        'occupation': pd.api.types.CategoricalDtype([
            'Adm-clerical', 'Armed-Forces', 'Craft-repair',
            'Exec-managerial',
            'Farming-fishing', 'Handlers-cleaners', 'Machine-op-inspct',
            'Other-service', 'Priv-house-serv', 'Prof-specialty',
            'Protective-serv',
            'Sales', 'Tech-support', 'Transport-moving'
        ]),
        'relationship': pd.api.types.CategoricalDtype(categories=[
            'Husband', 'Not-in-family', 'Other-relative', 'Own-child',
            'Unmarried',
            'Wife'
        ]),
        'race': pd.api.types.CategoricalDtype(categories=[
            'Amer-Indian-Eskimo', 'Asian-Pac-Islander', 'Black', 'Other',
            'White'
        ]),
        'native_country': pd.api.types.CategoricalDtype(categories=[
            'Cambodia', 'Canada', 'China', 'Columbia', 'Cuba',
            'Dominican-Republic',
            'Ecuador', 'El-Salvador', 'England', 'France', 'Germany',
            'Greece',
            'Guatemala', 'Haiti', 'Holand-Netherlands', 'Honduras', 'Hong',
            'Hungary',
            'India', 'Iran', 'Ireland', 'Italy', 'Jamaica', 'Japan', 'Laos',
            'Mexico',
            'Nicaragua', 'Outlying-US(Guam-USVI-etc)', 'Peru',
            'Philippines', 'Poland',
            'Portugal', 'Puerto-Rico', 'Scotland', 'South', 'Taiwan',
            'Thailand',
            'Trinadad&Tobago', 'United-States', 'Vietnam', 'Yugoslavia'
        ])
    }

    def __init__(self, model, processor):
        self._model = model
        self._processor = processor
        self._class_names = ['<=50K', '>50K']

    def _preprocess(self, instances):
        """Dataframe contains both numeric and categorical features, convert
        categorical features to numeric.

        Args:
          dataframe: A `Pandas.Dataframe` to process.
        """
        dataframe = pd.DataFrame(data=[instances], columns=self._CSV_COLUMNS[:-1])
        dataframe = dataframe.drop(columns=self._UNUSED_COLUMNS)
        # Convert integer valued (numeric) columns to floating point
        numeric_columns = dataframe.select_dtypes(['int64']).columns
        dataframe[numeric_columns] = dataframe[numeric_columns].astype(
            'float32')

        # Convert categorical columns to numeric
        cat_columns = dataframe.select_dtypes(['object']).columns
        # Keep categorical columns always using same values based on dict.
        dataframe[cat_columns] = dataframe[cat_columns].apply(
            lambda x: x.astype(self._CATEGORICAL_TYPES[x.name]))
        dataframe[cat_columns] = dataframe[cat_columns].apply(
            lambda x: x.cat.codes)
        return dataframe

    def predict(self, instances, **kwargs):
        preprocessed_data = self._preprocess(instances)
        preprocessed_inputs = self._processor.preprocess(preprocessed_data)
        outputs = self._model.predict_classes(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):
        import tensorflow as tf
        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)

После того, как файл записан, я могу проверить егонапример, локально перед развертыванием модели:

from model_prediction import CustomModelPrediction
model = CustomModelPrediction.from_path('.')
instance = [25, 'Private', 226802, '11th', 7, 'Never-married', 'Machine-op-inspct', 'Own-child', 'Black', 'Male', 0, 0, 40, 'United-States']
model.predict(instance)

Другой вариант - после сборки пакета установки вы также можете протестировать установку локально, где my_custom_code-0.1.tar.gz - файл, предназначенный для развертывания в платформе AI:

 pip install --target=/tmp/custom_lib --no-cache-dir -b /tmp/pip_builds my_custom_code-0.1.tar.gz

Также взгляните на этот раздел:

Вы можете использовать --enable-console-logging для получения журналов, экспортируемых в ваш проект.Возможно, вам потребуется создать новую модель.

0 голосов
/ 18 июня 2019

Похоже, что использование кода отладки (на момент публикации) без модели не работает. Я использовал следующий код, чтобы все работало для моего варианта использования с предсказанием изображения:

image_filename = 'your image path'
PROJECT_ID = ''
MODEL_NAME = ''
VERSION_NAME = ''

img = base64.b64encode(open(image_filename, "rb").read()).decode()
image_bite_dict = {"key": "0", "image_bytes": {"b64": img}}

instances = [
            image_bite_dict
        ]


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()
...