Ошибка в прогнозировании в мл-движке с питоном - PullRequest
0 голосов
/ 06 ноября 2019

Я использую мл движок для онлайн-прогнозов и успешно развернул модель. Когда я использовал команду прогнозирования gcloud:

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

ОК, поэтому я добавил --log-http в команду gcloud предсказать, и запрос Json сконструирован так:

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

Я попробовал тот же самый Json с POSTMAN, и он сработал, и были сгенерированы прогнозы. Когда я сделал то же самое в Python, это снова привело к ошибке запроса. При проверке тела http в python это привело к следующему:

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

У меня есть догадка, что это добавляет обратную косую черту к Json, что привело к этой ошибке. Кто-нибудь может знать, как бороться с этими обратными слешами?

1 Ответ

0 голосов
/ 07 ноября 2019

Хорошо, так что я смог взломать это. Метод прогнозирования внутренне преобразует запрос в JSON, поэтому вам не нужно явно преобразовывать его в формат JSON. Я отправлял запрос в JSON перед передачей в функцию прогнозирования. поэтому сброс JSON снова привел к обратным слешам, которые испортили запрос.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...