首页 > 解决方案 > 'transpose 需要一个大小为 5 的向量。但是 input(1) 是一个大小为 3\n\t 的向量,当向 tensorflow 服务模型发出推理 POST 请求时

问题描述

我已经训练了一个模型并将其部署到 tensorflow-serving 进行推理。

发出请求时出现此错误:

<Response [400]>
{'error': 'transpose expects a vector of size 5. But input(1) is a vector of size 3\n\t [[{{node bidirectional_1/transpose}} = Transpose[T=DT_FLOAT, Tperm=DT_INT32, _class=["loc:@bidirectional_1/TensorArrayUnstack/TensorArrayScatter/TensorArrayScatterV3"], _output_shapes=[[50,?,512]], _device="/job:localhost/replica:0/task:0/device:CPU:0"](embedding_1/embedding_lookup, Attention/transpose/perm)]]'}

这个模型与我部署的第一个模型之间的显着区别是它包含一个 Keras 自定义层,而我的成功尝试只包含标准 Keras 层。

这就是我测试对我的 tf-serving 模型的 POST 请求的方式:

with open("CNN_last_test_set.pkl", "rb") as fp:
    x_arr_test, y_test = pickle.load(fp)

out = x_arr_test[:1, :]
out = out.tolist()
payload = {
    "instances": [{'input': [out]}]
}

r = requests.post('http://localhost:9000/v1/models/prod_mod:predict', json=payload)
pred = json.loads(r.content.decode('utf-8'))

要创建与 tf-serving 一起使用的 tensorflow 模型对象,我正在使用此函数:

def export_model_custom_layer(filename, export_path_base):
    # set the mode to test time.
    K.set_learning_phase(0)
    model = keras.models.load_model(filename, custom_objects={"Attention": Attention})
    sess = K.get_session()

    # set the path to save the model and model version
    export_version = 1

    export_path = os.path.join(
        tf.compat.as_bytes(export_path_base),
        tf.compat.as_bytes(str(export_version)))
    tf.saved_model.simple_save(
        sess,
        export_path,
        inputs={'input': model.input},
        outputs={t.name.split(':')[0]: t for t in model.outputs},
        legacy_init_op=tf.tables_initializer())

在我将客户层定义为自定义对象的地方,为了使其工作,我将此功能添加到我的客户层:

    def get_config(self):
        config = {
            'name': "Attention"
                  }
        base_config = super(Attention, self).get_config()
        return dict(list(base_config.items()) + list(config.items()))

当我使用与使用标准 keras model.predict() 接收的 tf-serving 模型相同的数据格式对模型进行预测时,它按预期工作:

class Attention(Layer):...

with open("CNN_last_test_set.pkl", "rb") as fp:
    x_arr_test, y_test = pickle.load(fp)

model = keras.models.load_model(r"Data/modelCNN.model", custom_objects={"Attention": Attention})
out = x_arr_test[:1, :]
test1 = out.shape
out = out.tolist()

test = model.predict([out])

>> print(test)
>> [[0.21351092]]

这使我相信,当我将模型从 keras 导出到 .pb 文件时,或者以某种方式在 docker 容器中运行模型时,就会出现问题。

我不确定如何处理这个错误,但我假设这与我的自定义层对象有关,因为它与我以前只包含标准 Keras 层的模型一起使用。

非常感谢任何帮助,谢谢!

编辑:我解决了这个问题,问题是我的输入数据有两个多余的维度。我意识到,当我从变量“out”周围删除括号时,我的错误从“转置需要一个大小为 5 的向量”变为“转置需要一个大小为 4 的向量”。所以我将我的“out”变量从 (1, 50) 重新调整为 (50,) 并删除了括号,问题就自行解决了。

标签: dockertensorflowkerastensorflow-serving

解决方案


推荐阅读