Сбой прогнозирования: ошибка при проверке ввода: ожидалось, что плотный_вход будет иметь форму (2898,), но получен массив с формой (1,)

Я использую следующий скрипт predictor.py, чтобы получать прогнозы из модели Keras, размещенной на платформе GCP AI.

import os
import pickle
import tensorflow as tf
import numpy as np
import logging

class MyPredictor(object):

    def __init__(self, model, bow_model):
        self._model = model
        self._bow_model = bow_model

    def predict(self, instances, **kwargs):
      
        vectors = self.embedding([instances])

        vectors = vectors.tolist()

        output = self._model.predict(vectors)

        return output

    def embedding(self, statement):
        vector = self._bow_model.transform(statement).toarray()
        #vector = vector.to_list()
        return vector


    @classmethod
    def from_path(cls, model_dir):

        model_path = os.path.join(model_dir, 'model.h5')
        model = tf.keras.models.load_model(model_path, compile = False)

        preprocessor_path = os.path.join(model_dir, 'bow.pkl')
        with open(preprocessor_path, 'rb') as f:
            bow_model = pickle.load(f)


        return cls(model, bow_model)

Однако я получаю

Prediction failed: Error when checking input: expected dense_input to have shape (2898,) but got array with shape (1,)

Проблема, похоже, связана с размерами моих входных данных при попытке сделать фактические прогнозы в строке output = self._model.predict ([векторы]). Модель ожидает вектор формы (2898,)

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

This is the shape
(1, 2898)

This is the dim number
2

This is the vector 
[[0 0 0 ... 0 0 0]]

Так что размеры и форма в порядке, и он действительно должен работать ....

Кроме того, я провел тест, чтобы получить прогнозы модели, хранящиеся локально, и она отлично работает. Это тестовый файл:

import os
import pickle
import tensorflow as tf
import numpy as np

class MyPredictor(object):

    def __init__(self, model, bow_model):
        self._model = model
        self._bow_model = bow_model

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

        print("These are the instances ", instances)

        vector = self.embedding([instances])

        output = self._model.predict(vector)

        return output

    def embedding(self, statement):
        vector = self._bow_model.transform(statement).toarray()
        #vector = vector.to_list()
        return vector



model_path = 'model.h5'
model = tf.keras.models.load_model(model_path, compile = False)

preprocessor_path = 'bow.pkl'
with open(preprocessor_path, 'rb') as f:
    bow_model = pickle.load(f)


instances = 'test'

predictor = MyPredictor(model, bow_model)

outputs = predictor.predict(instances)

print(outputs)

person priegueee    schedule 10.03.2021    source источник


Ответы (1)


Решено!

Это было так же глупо, как добавить скобки к этой строке output = self._model.predict([vectors])

После этого я получил еще одну ошибку, касающуюся того, что вывод прогноза не является сериализуемым по json. Я решил это, просто добавив .tolist () к return return output.to_list()

import os
import pickle
import tensorflow as tf
import numpy as np
import logging

class MyPredictor(object):

    def __init__(self, model, bow_model):
        self._model = model
        self._bow_model = bow_model

    def predict(self, instances, **kwargs):
      
        vectors = self.embedding([instances])

        vectors = vectors.tolist()

        output = self._model.predict([vectors])

        return output.to_list()

    def embedding(self, statement):
        vector = self._bow_model.transform(statement).toarray()
        #vector = vector.to_list()
        return vector


    @classmethod
    def from_path(cls, model_dir):

        model_path = os.path.join(model_dir, 'model.h5')
        model = tf.keras.models.load_model(model_path, compile = False)

        preprocessor_path = os.path.join(model_dir, 'bow.pkl')
        with open(preprocessor_path, 'rb') as f:
            bow_model = pickle.load(f)


        return cls(model, bow_model)

person priegueee    schedule 10.03.2021