Невозможно получить прогноз от платформы Google AI с Pytorch - PullRequest
0 голосов
/ 28 мая 2020

Я развернул пользовательскую модель Pytorch на платформе Google AI для прогнозирования, но когда я пытаюсь сделать запрос на прогноз с данными изображения с помощью инструментов gcloud, я получаю в ответ следующую ошибку:

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

Я попытался закодировать данные своего изображения в формате b64 или поместить его в многомерный массив python, выполнив следующие действия:

pil_im = Image.open('Pic512.png')
pil_im = pil_im.resize((224,224)).convert('RGB')
im_arr = np.asarray(pil_im)
py_arr = im_arr.tolist()
json_instance_1 = {'instances': py_arr}  
with open('json_instance_1.json', 'w') as f:
    json.dump(json_instance_1, f)

Я преобразовал его в b64 вот так, после соответствующим образом скорректировав свой код Predictor:

with open('Pic512.png', 'rb') as f:
    byte_im = f.read()
json_instance = {'instances': {'b64': base64.b64encode(byte_im).decode()}} 
with open('json_instance.json', 'w') as f:
    json.dump(json_instance, f)

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

Мой модуль прогнозирования:

from facenet_pytorch import MTCNN, InceptionResnetV1, extract_face
import torch
from torchvision import transforms
from torch.nn import functional as F
from PIL import Image
# from sklearn.externals import joblib
import numpy as np
import os
import io
import base64



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

    def __init__(self, model, preprocessor, device):
        """Stores artifacts for prediction. Only initialized via `from_path`.
        """
        self._resnet = model
        self._mtcnn_mult = preprocessor
        self._device = device
        self.get_std_tensor = transforms.Compose([
            np.float32,
            np.uint8,
            transforms.ToTensor(),
        ])
        self.tensor2pil = transforms.ToPILImage(mode='RGB')
        self.trans_resnet = transforms.Compose([
            transforms.Resize((100, 100)),
            np.float32,
            transforms.ToTensor()
        ])

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

        pil_transform = transforms.Resize((512, 512))

        imarr = np.uint8(np.array(instances))
        # img_bytes_string = io.BytesIO(base64.b64decode(instances))
        pil_im = Image.fromarray(imarr)
        # pil_im = Image.open(img_bytes_string)
        image = pil_im.convert('RGB')
        pil_im_512 = pil_transform(image)

        boxes, _ = self._mtcnn_mult.detect(pil_im_512)
        box = boxes[0]

        face_tensor = extract_face(pil_im_512, box, margin=40)
        std_tensor = self.get_std_tensor(face_tensor.permute(1, 2, 0))
        cropped_pil_im = self.tensor2pil(std_tensor)

        face_tensor = self.trans_resnet(cropped_pil_im)
        face_tensor4d = face_tensor.unsqueeze(0)
        face_tensor4d = face_tensor4d.to(self._device)

        self._resnet.eval()
        prediction = self._resnet(face_tensor4d)
        preds = F.softmax(prediction, dim=1).detach().numpy().reshape(-1)
        print('probability of (class1, class2) = ({:.4f}, {:.4f})'.format(preds[0], preds[1]))

        return {'probs':preds.tolist()}

    @classmethod
    def from_path(cls, model_dir):

        device_path = os.path.join(model_dir, 'device_cpu.pt')
        device = torch.load(device_path)

        model_path = os.path.join(model_dir, 'FullResNetRefinedExtra_no_norm_100x100_8634.pt')
        classifier = torch.load(model_path, map_location=device)

        mtcnn_path = os.path.join(model_dir, 'mtcnn_mult.pt')
        mtcnn_mult = torch.load(mtcnn_path)

        return cls(classifier, mtcnn_mult, device)

Когда я тестирую класс локально, все работает, поэтому я предполагаю, что это проблема, связанная с сериализацией и десериализацией на стороне Google Platform. Как я могу решить эту проблему?

...