Google Cloud ML引擎+ Tensorflow在input_fn()中执行预处理/标记化

问题描述:

我想在我的输入函数中执行基本的预处理和标记化。我的数据包含在我无法修改的谷歌云存储存储位置(gs://)中的csv中。此外,我对我的ml-engine包中的输入文本进行任何修改,以便在服务时间内复制行为。Google Cloud ML引擎+ Tensorflow在input_fn()中执行预处理/标记化

我输入功能遵循以下基本结构:

filename_queue = tf.train.string_input_producer(filenames) 
reader = tf.TextLineReader() 
_, rows = reader.read_up_to(filename_queue, num_records=batch_size) 
text, label = tf.decode_csv(rows, record_defaults = [[""],[""]]) 

# add logic to filter special characters 
# add logic to make all words lowercase 
words = tf.string_split(text) # splits based on white space 

是否有避免对整个数据预先设定执行该预处理任何选项?这post表明tf.py_func()可以用来做这些转换,但是他们建议“缺点是,因为它没有保存在图中,我不能恢复我保存的模型”,所以我不相信这会在服务时间有用。如果我正在定义我自己的tf.py_func()来执行预处理,并且在培训师包中定义了我正在上传到云中,我是否会遇到任何问题?有没有其他选择,我不考虑?

最佳做法是编写一个函数,您可以从training/eval input_fn和您的服务input_fn中调用该函数。

例如:

def add_engineered(features): 
    text = features['text'] 
    features['words'] = tf.string_split(text) 
    return features 

然后,在你input_fn,包您提供呼叫返回功能add_engineered:

def input_fn(): 
    features = ... 
    label = ... 
    return add_engineered(features), label 

,并在您serving_input FN,确保类似的包裹通过调用add_engineered返回的功能(不是feature_placeholders):

def serving_input_fn(): 
    feature_placeholders = ... 
    features = ... 
    return tflearn.utils.input_fn_utils.InputFnOps(
     add_engineered(features), 
     None, 
     feature_placeholders 
    ) 

你的模型会使用'单词'。但是,预测时您的JSON输入只需包含“文本”即原始值。

下面是一个完整的工作示例:

https://github.com/GoogleCloudPlatform/training-data-analyst/blob/master/courses/machine_learning/feateng/taxifare/trainer/model.py#L107

+0

喜勒 - 感谢您的详细答复!我理解input_fn中的包含内容,但我特别寻求建议,以便不仅仅应用tf.string_split(),而是提供最佳方法。在tf.string_split之前,我想使所有字符都为小写字母,并且我还想从原始文本中剥离特殊字符(例如可能附加在单词末尾的*或!),所以“这是一个句子* to令牌化!”应该在string_split()之前转换为“这是一个标记化的句子”。 py_func()是唯一的选择吗?这会在服务时间造成问题吗? – reese0106

+0

除了Lak的回答,我想回答一下关于tf.py_func的部分:它*不会*序列化和反序列化,所以不能用于服务。 – rhaertel80

+0

在add_engineered方法中,不限于tensorflow函数。你可以调用任何python函数,但要注意的是tensorflow函数可能会涉及到数据在C++和python之间传递,导致效率低下。核心python函数很容易,但是当您部署应用程序时,依赖外部模块的函数将需要更改配置。 – Lak