我最近在谷歌云的人工智能平台上部署了一个自定义模型,我正在尝试调试预处理逻辑的某些部分。但是,我的打印语句不会记录到堆栈驱动程序输出中。我也尝试使用从 google.cloud 导入的日志记录客户端,但无济于事。这是我的自定义预测文件:
import os
import pickle
import numpy as np
from sklearn.datasets import load_iris
import tensorflow as tf
from google.cloud import logging
class MyPredictor(object):
def __init__(self, model, preprocessor):
self.logging_client = logging.Client()
self._model = model
self._preprocessor = preprocessor
self._class_names = ["Snare", "Kicks", "ClosedHH", "ClosedHH", "Clap", "Crash", "Perc"]
def predict(self, instances, **kwargs):
log_name = "Here I am"
logger = self.logging_client.logger(log_name)
text = 'Hello, world!'
logger.log_text(text)
print('Logged: {}'.format(text), kwargs.get("sr"))
inputs = np.asarray(instances)
outputs = self._model.predict(inputs)
if kwargs.get('probabilities'):
return outputs.tolist()
#return "[]"
else:
return [self._class_names[index] for index in np.argmax(outputs.tolist(), 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, custom_objects={"adam": tf.keras.optimizers.Adam,
"categorical_crossentropy":tf.keras.losses.categorical_crossentropy, "lr":0.01, "name": "Adam"})
preprocessor_path = os.path.join(model_dir, 'preprocessor.pkl')
with open(preprocessor_path, 'rb') as f:
preprocessor = pickle.load(f)
return cls(model, preprocessor)
我在网上找不到任何关于为什么我的日志没有显示在堆栈驱动程序中的内容(无论是打印语句还是日志记录库调用(。有人遇到过这个问题吗?
谢谢 尼基塔
注意:如果您有足够的代表来创建标签,请将google-ai-platform标签添加到这篇文章中。我认为这真的会帮助那些处于我这个位置的人。谢谢!
来自文档:
如果要启用联机预测日志记录,则必须对其进行配置 创建模型资源或创建模型版本时 资源,具体取决于要启用的日志记录类型。那里 是三种类型的日志记录,您可以单独启用它们:
访问日志记录,记录时间戳和延迟等信息 对堆栈驱动程序日志记录的每个请求。
您可以在创建模型资源时启用访问日志记录。
流日志记录,记录来自 堆栈驱动程序日志记录的预测节点,可用于 调试。这种类型的日志记录处于测试阶段,不受 计算引擎 (N1( 计算机类型。
您可以在创建模型资源时启用流日志记录。
请求-响应日志记录,记录联机预测示例 对 BigQuery 表的请求和响应。这种类型的日志记录位于 试用版。
您可以通过创建模型版本来启用请求-响应日志记录 资源,然后更新该版本。
对于您的使用案例,请使用以下模板将自定义信息记录到 StackDriver 中:
型
gcloud beta ai-platform models create {MODEL_NAME}
--regions {REGION}
--enable-logging
--enable-console-logging
模型版本
gcloud beta ai-platform versions create {VERSION_NAME}
--model {MODEL_NAME}
--origin gs://{BUCKET}/{MODEL_DIR}
--python-version 3.7
--runtime-version 1.15
--package-uris gs://{BUCKET}/{PACKAGES_DIR}/custom-model-0.1.tar.gz
--prediction-class=custom_prediction.CustomModelPrediction
--service-account custom@project_id.iam.gserviceaccount.com
我试过这个并且工作正常:
- 由于@classmethod装饰器,我对构造函数进行了一些修改。
- 创建一个服务帐户并授予其"堆栈驱动程序调试器用户"角色,在模型版本创建期间使用它
- 将
google-cloud-logging
库添加到setup.py
- 考虑启用堆栈驱动程序日志记录的额外成本
- 使用时
log_struct
请检查是否传递了正确的类型。(如果使用str
,请确保使用.decode('utf-8')
在 Python 3 中将bytes
转换为str
( - 在堆栈驱动程序客户端创建期间定义project_id参数
logging.Client()
,否则你会得到:
ERROR:root:Prediction failed: 400 Name "projects//logs/my-custom-prediction-log" is missing the parent component. Expected the form projects/[PROJECT_ID]/logs/[ID]"
代码如下:
%%writefile cloud_logging.py
import os
import pickle
import numpy as np
from datetime import date
from google.cloud import logging
import tensorflow.keras as keras
LOG_NAME = 'my-custom-prediction-log'
class CustomModelPrediction(object):
def __init__(self, model, processor, client):
self._model = model
self._processor = processor
self._client = client
def _postprocess(self, predictions):
labels = ['negative', 'positive']
return [
{
"label":labels[int(np.round(prediction))],
"score":float(np.round(prediction, 4))
} for prediction in predictions]
def predict(self, instances, **kwargs):
logger = self._client.logger(LOG_NAME)
logger.log_struct({'instances':instances})
preprocessed_data = self._processor.transform(instances)
predictions = self._model.predict(preprocessed_data)
labels = self._postprocess(predictions)
return labels
@classmethod
def from_path(cls, model_dir):
client = logging.Client(project='project_id') # Change to your project
model = keras.models.load_model(
os.path.join(model_dir,'keras_saved_model.h5'))
with open(os.path.join(model_dir, 'processor_state.pkl'), 'rb') as f:
processor = pickle.load(f)
return cls(model, processor, client)
# Verify model locally
from cloud_logging import CustomModelPrediction
classifier = CustomModelPrediction.from_path('.')
requests = ["God I hate the north", "god I love this"]
response = classifier.predict(requests)
response
然后我检查示例库:
python snippets.py my-custom-prediction-log list
Listing entries for logger my-custom-prediction-log:
* 2020-02-19T19:51:45.809767+00:00: {u'instances': [u'God I hate the north', u'god I love this']}
* 2020-02-19T19:57:18.615159+00:00: {u'instances': [u'God I hate the north', u'god I love this']}
若要可视化日志,请在 StackDriver>日志记录>选择"全局"和"日志名称",如果要查看模型日志,应该能够选择"云 ML 模型版本"。
您可以在此处使用我的文件:模型和预处理器
如果您只想打印工作而不使用我上面的日志记录方法,则可以在打印中添加刷新标志,
print(“logged”,flush=True)