使用python的ml-engine中的预测错误

时间:2019-11-06 09:57:30

标签: python google-cloud-ml

我正在使用ml引擎进行在线预测,并成功部署了该模型。当我使用gcloud Forecast命令时:

gcloud ml-engine predict --model fastercnn --version v5 --json-instances input.json

它给出了所需的预测。但是,当我使用python Google客户端时,它会出现以下错误:

Traceback (most recent call last):
  File "predict.py", line 55, in <module>
    prediction = predict_json('handdetector', 'fastercnn', request)
  File "predict.py", line 35, in predict_json
    response.execute()
  File "/Users/syedmustufainabbasrizvi/.pyenv/versions/sign-language/lib/python3.6/site-packages/googleapiclient/_helpers.py", line 130, in positional_wrapper
    return wrapped(*args, **kwargs)
  File "/Users/syedmustufainabbasrizvi/.pyenv/versions/sign-language/lib/python3.6/site-packages/googleapiclient/http.py", line 856, in execute
    raise HttpError(resp, content, uri=self.uri)
googleapiclient.errors.HttpError: <HttpError 400 when requesting https://ml.googleapis.com/v1/projects/handdetector/models/fastercnn/versions/v5:predict?alt=json returned "Bad Request">

我在python中使用了以下代码:

def predict_json(project, model, request, version='v5'):
    """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>
    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=request
    )
    print (response.body)
    response.execute()
    if 'error' in response:
        raise RuntimeError(response['error'])

    return response['predictions']

两个命令中的Json都相同:

"{\"image_bytes\": {\"b64\": \"/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsI}}

模型配置:

The given SavedModel SignatureDef contains the following input(s):
  inputs['image_bytes'] tensor_info:
      dtype: DT_STRING
      shape: (-1)
      name: encoded_image_string_tensor:0
The given SavedModel SignatureDef contains the following output(s):
  outputs['detection_boxes'] tensor_info:
      dtype: DT_FLOAT
      shape: (-1, 300, 4)
      name: detection_boxes:0
  outputs['detection_classes'] tensor_info:
      dtype: DT_FLOAT
      shape: (-1, 300)
      name: detection_classes:0
  outputs['detection_features'] tensor_info:
      dtype: DT_FLOAT
      shape: (-1, -1, -1, -1, -1)
      name: detection_features:0
  outputs['detection_multiclass_scores'] tensor_info:
      dtype: DT_FLOAT
      shape: (-1, 300, 2)
      name: detection_multiclass_scores:0
  outputs['detection_scores'] tensor_info:
      dtype: DT_FLOAT
      shape: (-1, 300)
      name: detection_scores:0
  outputs['num_detections'] tensor_info:
      dtype: DT_FLOAT
      shape: (-1)
      name: num_detections:0
  outputs['raw_detection_boxes'] tensor_info:
      dtype: DT_FLOAT
      shape: (-1, 300, 4)
      name: raw_detection_boxes:0
  outputs['raw_detection_scores'] tensor_info:
      dtype: DT_FLOAT
      shape: (-1, 300, 2)
      name: raw_detection_scores:0
Method name is: tensorflow/serving/predict

好的,所以我在gcloud Forecast命令中添加了--log-http,并且Json请求的构造如下:

{"instances": [{"image_bytes": {"b64": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCACAAIADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBR......"}}]}

我用POSTMAN尝试了相同的Json,它起作用了,并且产生了预测。当我在python中执行相同操作时,再次导致错误的请求错误。在python中检查http正文时,结果如下:

{"instances": ["{\"image_bytes\": {\"b64\": \"/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4n.......}}]}

我有种预感,它会在Json上添加反斜杠,从而导致此错误。有人知道如何处理这些反斜杠吗?

1 个答案:

答案 0 :(得分:1)

好的,所以我能够破解它。预测方法在内部将请求转换为JSON,因此您不必显式将其转换为JSON格式。在提供给预测函数之前,我将请求转储到JSON。因此再次转储JSON会导致反斜杠,使请求混乱。