如何允许文本输入到 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。
我正在 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。