将Tensorflow预处理添加到现有Keras模型中(用于Tensorflow服务) [英] Add Tensorflow pre-processing to existing Keras model (for use in Tensorflow Serving)
问题描述
我想在导出的Keras模型中包括我的自定义预处理逻辑,以用于Tensorflow Serving.
I would like to include my custom pre-processing logic in my exported Keras model for use in Tensorflow Serving.
我的预处理执行字符串标记化,并使用外部字典将每个标记转换为索引以输入到嵌入层:
from keras.preprocessing import sequence
token_to_idx_dict = ... #read from file
# Custom Pythonic pre-processing steps on input_data
tokens = [tokenize(s) for s in input_data]
token_idxs = [[token_to_idx_dict[t] for t in ts] for ts in tokens]
tokens_padded = sequence.pad_sequences(token_idxs, maxlen=maxlen)
模型架构和培训:
model = Sequential()
model.add(Embedding(max_features, 128, input_length=maxlen))
model.add(LSTM(128, activation='sigmoid'))
model.add(Dense(n_classes, activation='softmax'))
model.compile(loss='sparse_categorical_crossentropy', optimizer='adam')
model.fit(x_train, y_train)
由于该模型将在Tensorflow Serving中使用,因此我想将所有预处理逻辑合并到模型本身(在导出的模型文件中编码).
Since the model will be used in Tensorflow Serving, I want to incorporate all pre-processing logic into the model itself (encoded in the exported model file).
问:我如何仅使用Keras库?
我找到了本指南解释了如何组合Keras和Tensorflow.但是我仍然不确定如何将所有内容导出为一个模型.
I found this guide explains how to combine Keras and Tensorflow. But I'm still unsure how to export everything as one model.
我知道Tensorflow具有内置的字符串拆分功能,字典查找操作.
I know Tensorflow has built-in string splitting, file I/O, and dictionary lookup operations.
使用Tensorflow操作的预处理逻辑:
# Get input text
input_string_tensor = tf.placeholder(tf.string, shape={1})
# Split input text by whitespace
splitted_string = tf.string_split(input_string_tensor, " ")
# Read index lookup dictionary
token_to_idx_dict = tf.contrib.lookup.HashTable(tf.contrib.lookup.TextFileInitializer("vocab.txt", tf.string, 0, tf.int64, 1, delimiter=","), -1)
# Convert tokens to indexes
token_idxs = token_to_idx_dict.lookup(splitted_string)
# Pad zeros to fixed length
token_idxs_padded = tf.pad(token_idxs, ...)
问:我如何才能一起使用这些Tensorflow预先定义的预处理操作和我的Keras图层来进行训练,然后将模型导出为黑匣子"以在Tensorflow服务中使用?
推荐答案
我知道了,所以我将在这里回答我自己的问题.
I figured it out, so I'm going to answer my own question here.
要点如下:
首先,(在单独的代码文件中)我仅通过自己的预处理功能使用Keras训练了模型,导出了Keras模型权重文件和令牌索引字典.
First, (in separate code file) I trained the model using Keras only with my own pre-processing functions, exported the Keras model weights file and my token-to-index dictionary.
然后,我仅复制Keras模型体系结构,将输入设置为预处理的张量输出,从先前训练过的Keras模型加载权重文件,并将其夹在Tensorflow预处理操作和Tensorflow导出器之间.
Then, I copied just the Keras model architecture, set the input as the pre-processed tensor output, loaded the weights file from the previously trained Keras model, and sandwiched it between the Tensorflow pre-processing operations and the Tensorflow exporter.
最终产品:
import tensorflow as tf
from keras import backend as K
from keras.models import Sequential, Embedding, LSTM, Dense
from tensorflow.contrib.session_bundle import exporter
from tensorflow.contrib.lookup import HashTable, TextFileInitializer
# Initialize Keras with Tensorflow session
sess = tf.Session()
K.set_session(sess)
# Token to index lookup dictionary
token_to_idx_path = '...'
token_to_idx_dict = HashTable(TextFileInitializer(token_to_idx_path, tf.string, 0, tf.int64, 1, delimiter='\t'), 0)
maxlen = ...
# Pre-processing sub-graph using Tensorflow operations
input = tf.placeholder(tf.string, name='input')
sparse_tokenized_input = tf.string_split(input)
tokenized_input = tf.sparse_tensor_to_dense(sparse_tokenized_input, default_value='')
token_idxs = token_to_idx_dict.lookup(tokenized_input)
token_idxs_padded = tf.pad(token_idxs, [[0,0],[0,maxlen]])
token_idxs_embedding = tf.slice(token_idxs_padded, [0,0], [-1,maxlen])
# Initialize Keras model
model = Sequential()
e = Embedding(max_features, 128, input_length=maxlen)
e.set_input(token_idxs_embedding)
model.add(e)
model.add(LSTM(128, activation='sigmoid'))
model.add(Dense(num_classes, activation='softmax'))
# Load weights from previously trained Keras model
weights_path = '...'
model.load_weights(weights_path)
K.set_learning_phase(0)
# Export model in Tensorflow format
# (Official tutorial: https://github.com/tensorflow/serving/blob/master/tensorflow_serving/g3doc/serving_basic.md)
saver = tf.train.Saver(sharded=True)
model_exporter = exporter.Exporter(saver)
signature = exporter.classification_signature(input_tensor=model.input, scores_tensor=model.output)
model_exporter.init(sess.graph.as_graph_def(), default_graph_signature=signature)
model_dir = '...'
model_version = 1
model_exporter.export(model_dir, tf.constant(model_version), sess)
# Input example
with sess.as_default():
token_to_idx_dict.init.run()
sess.run(model.output, feed_dict={input: ["this is a raw input example"]})
这篇关于将Tensorflow预处理添加到现有Keras模型中(用于Tensorflow服务)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!