Я следую документации это по пользовательским процедурам прогнозирования и пытаюсь понять, как выглядят входные данные для пользовательской процедуры прогнозирования. Код для отправки ввода выглядит следующим образом:
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
, чтобы я мог соответствующим образом построить препроцессор?
заранее спасибо.
Я создаю новый образец для пользовательского прогноза, который может быть полезен для отладки: Сначала я пишу файл локально через ноутбук (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
, чтобы экспортировать журналы в свой проект. Возможно, вам потребуется создать новую модель.
Большое спасибо за ваш ответ. Если я воспроизведу ваш второй и третий фрагмент кода, все будет работать нормально, потому что я знаю, что я передаю. Но если я развернусь на платформе Google AI и передам входные данные, завернутые в JSON (как описано здесь cloud.google.com/ml-engine/docs/v1/…), я получу ошибку и, кроме того, я думаю, что теряю понимание того, что я на самом деле получаю. Если я перейду на платформу AI > режимы > щелкну мою модель > щелкну мою версию > протестировать и использовать и вставлю туда пример ввода JSON, я получу "error": "Internal error encountered."
.
Кроме того, я включил ведение журнала с помощью --enable-console-logging
(надеюсь, это очень полезно), но где мне теперь найти журналы? и как мне написать в лог? Спасибо
Я не запускал блокнот, но выполняю все шаги в своем примере.
Я запустил ваш ноутбук, и он отлично работает (неудивительно). Но если я изменю Predictor.predict своим кодом (больше ничего не изменилось), произойдет сбой с той же ошибкой... Возможно, вы также можете попытаться воспроизвести ошибку. Это все еще очень сложно отлаживать.
Привет DarioB, извините за поздний ответ, я просто открываю вопрос для создания журналов с помощью --enable-console-logging (похоже, журналы недоступны), с пользовательским прогнозом вам все еще нужен ключ «экземпляры», а внутри него Объект, который вы хотите предсказать, например, словарь, этот объект будет ** значением kwargs, например {"instances": "{"max": [1.1, 1.0, 0.1]}"}, каков ваш окончательный объект json? Вы пробовали: gcloud ai-platform Predict --model=${MODEL_NAME} --version=${MODEL_VERSION} --json-instances=new-data.json ?
Привет, спасибо за ваш ответ. Я попробовал то, что вы предложили. Я все еще получаю ту же ошибку. Мой ввод JSON выглядит так {"instances": [ {"values": [1, 2, 3, 4], "key": 1}, {"values": [5, 6, 7, 8], "key": 2} ]}
@DarioB, ты когда-нибудь решал эту проблему? У меня все еще та же проблема.
да, я решил это, в моем случае я действительно добавил реальную модель (а не код отладки), и это действительно сработало. Не уверен, почему. добавлю развернутый ответ
@DarioB, что ты имеешь в виду под настоящей моделью? В чем для вас разница между реальной моделью и отладочным кодом? Я просто сохраняю модель в Tensorflow с помощью saver.save
и загружаю ее. Я даже не могу заставить его работать, передав входные данные JSON в Google Cloud Console в разделе: AI platform > model > click on my model > click on my version > test & use
.
Кстати, у меня есть модель, и я все еще получаю эту ошибку.
Понимаю. Проблема, вероятно, заключается в том, как вы переносите свои данные в объект JSON и как вы читаете их в конце предиктора. Я ожидал получить ошибку типа «Ошибка ключа», но на самом деле ее нет. Сначала попробуйте сделать прогноз локально, и пусть он сначала работает таким образом. Я надеюсь, что это помогает.
Я разобрался. Это было связано с другим пакетом, в котором не было необходимых данных.
Привет, как я могу использовать указание prediction-class
, если класс находится в подкаталоге. например, в моем tar.gz, который я загружаю, он имеет структуру (верхний уровень) setup.py, categorisation_project. Затем в папке categorization_project есть место, где мой predictor.py
сидит с MyPredictor
, на который нужно ссылаться. Я пытался использовать categorisation_project.predictor.MyPredictor
, но это не сработало. У меня также есть __init__.py
, чтобы убедиться, что все работает правильно. Есть ли способ заставить это работать?
Похоже, что использование отладочного кода (на момент написания этого поста) без модели не работает. Я использовал следующий код, чтобы все работало для моего варианта использования прогнозирования изображения:
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()
Я все еще не могу заставить его работать. Не могли бы вы рассказать мне, как именно вы сохранили модель для развертывания? Также можете ли вы добавить образец своего класса прогнозирования?
Вы можете использовать
--enable-console-logging
при создании модели, чтобы включить вывод журнала в ведение журнала StackDriver.