如何允许文本输入到 TensorFlow 模型?

How do I allow a text input to a TensorFlow model?

我正在 TensorFlow 中开发自定义文本分类模型,现在想使用 TensorFlow 服务来设置它以进行生产部署。该模型基于通过单独模型计算的文本嵌入进行预测,并且该模型需要将原始文本编码为向量。

我现在以一种有点脱节的方式工作,其中一项服务执行所有文本预处理,然后计算嵌入,然后将其作为嵌入文本向量发送到文本分类器。如果我们可以将所有这些都捆绑到一个 TensorFlow 服务模型中,尤其是初始文本预处理步骤,那就太好了。

这就是我被困的地方。您如何构建作为原始文本输入的 Tensor(或其他 TensorFlow 原语)?您是否需要做任何特别的事情来为令牌向量组件映射指定查找 table,以便将其保存为模型包的一部分?

作为参考,这是我现在拥有的粗略近似值:

input = tf.placeholder(tf.float32, [None, 510], name='input')

# lots of steps omitted for brevity/clarity

outputs = tf.linalg.matmul(outputs, terminal_layer, transpose_b=True, name='output')

sess = tf.Session()
tf.saved_model.simple_save(sess,
                           'model.pb',
                           inputs={'input': input}, outputs={'output': outputs})

这要归功于作为 TensorFlow 标准库的一部分提供的 tf.lookup.StaticVocabularyTable

我的模型使用的是词袋方法,而不是保留顺序,尽管这将是对代码的一个非常简单的更改。

假设您有一个编码词汇表的列表对象(我称之为 vocab)和一个您要使用的相应 term/token 嵌入矩阵(我称之为 raw_term_embeddings,因为我将其强制转换为张量),代码将如下所示:

initalizer = tf.lookup.KeyValueTensorInitializer(vocab, np.arange(len(vocab)))
lut = tf.lookup.StaticVocabularyTable(initalizer, 1) # the one here is the out of vocab size
lut.initializer.run(session=sess) # pushes the LUT onto the session

input = tf.placeholder(tf.string, [None, None], name='input')

ones_at = lut.lookup(input)
encoded_text = tf.math.reduce_sum(tf.one_hot(ones_at, tf.dtypes.cast(lut.size(), np.int32)), axis=0, keepdims=True)

# I didn't build an embedding for the out of vocabulary token
term_embeddings = tf.convert_to_tensor(np.vstack([raw_term_embeddings]), dtype=tf.float32)
embedded_text = tf.linalg.matmul(encoded_text, term_embeddings)

# then use embedded_text for the remainder of the model

一个小技巧还确保将 legacy_init_op=tf.tables_initializer() 传递给保存函数以提示 TensorFlow Serving 在加载模型时初始化文本编码的查找 table。