使用feature_columns出现Table not initialized错误

问题出现原因

在做推荐项目的排序模型时, 使用到了很多特征, 为了方便, 使用了tf.feature_columns模块去声明特征, 然后结合tf.keras.layers.DenseFeatures将特征和输入结合起来, 得到拼接在一起碾平的输入, 后面再接其他网络.

使用tf.feature_columnstf.keras.layers.DenseFeatures会在生成的DenseLayer内部生成查询表(table), 例如embedding_columns会生成embedding矩阵. 在训练和预测之前, 需要先初始化这些table.

因此在训练之前, 需要先调用初始化op:

sess = keras.backend.get_session()
sess,run(tf.tables_initialzer())

然后再执行训练过程.

为了优化推理阶段的时效, 以及考虑模型的定时更新, 我们在项目中使用了tensorflow-serving部署模型. 但在模型训练好, 保存, 并使用docker加载模型启动tensorflow-serving服务之后, 客户端去调用接口获取推理结果时, 遇到了报错的问题:

Failed precondition: Table not initialized.

解决方法

看来如同训练一样, 在tensorflow-serving加载模型之后, 也要进行一次tables_initialzer操作, 才能正常进行推理.

但tensorflow-serving加载模型, 启动服务的过程并不涉及任何用户代码, 无法像训练时一样, 增加两行代码来完成初始化.

正确的解决方法是在使用saved_model模块保存模型时, 就指明初始化op操作:

builder.add_meta_graph_and_variables(
        session,
        [tf.saved_model.tag_constants.SERVING],
        signature_def_map={tf.saved_model.signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: prediction_signature},
        main_op=tf.tables_initializer())

参考资料

最后更新于