在哪里执行tf.string_split()操作

时间:2017-08-24 18:50:15

标签: tensorflow tensorflow-serving google-cloud-ml-engine

我正在努力解决如何调整ML引擎示例以使用长文本字符串作为输入功能。我正在构建一个自定义估算器(如example),我希望了解"最佳做法"着眼于部署模型 - 我希望尽可能多的转换包含在model_fn本身中,以便在服务时更容易。考虑一个带有列"文本"的.csv。包含诸如&#34之类的句子;这是一个句子" - 最终我需要使用tf.string_split()将此文本拆分为标记,然后将单个标记转换为索引(使用词汇表文件或类似文件),然后将这些标记传递给嵌入。假设"这是一个句子"是我们正在处理的句子,下面概述了一种方法。我的问题是这是否是最佳的"实现这一目标的方法,或者是否有更好的方法来实现这一目标。

功能列

def get_feature_columns():
    sparse = tf.contrib.layers.sparse_column_with_integerized_feature(
        column_name = 'text',
        bucket_size = 100000,
        combiner = "sum")
    embedding = tf.contrib.layers.embedding_column(
        sparse, dimension = word_embedding_size)

    return set([embedding])

输入功能

def generate_input_fn():
    # read rows
    filename_queue = tf.train.string_input_producer(filenames, 
        num_epochs=num_epochs, shuffle=shuffle, capacity=32)

    reader = tf.TextLineReader(skip_header_lines=skip_header_lines)

    _, rows = reader.read_up_to(filename_queue, num_records=batch_size)

    text, label = tf.decode_csv(rows, record_defaults=[[""], [""]])

    # transform text from sentence --> tokens --> integerized tokens
    text_index = tf.contrib.lookup.index_table_from_file(vocabulary_file = vocab_file)
    tokens = tf.string_split(text)
    tokens_idx = text_index.lookup(tokens)

    features = dict(zip(['text', 'label'], [tokens_idx, label]))

    features = tf.train.shuffle_batch(features,batch_size)

    return features, features.pop('label')

模型FN :还有其他背景,但一般情况下这是通过..

input_layer = tf.feature_column.input_layer(features, 
        feature_columns = get_feature_columns())

我认识到一种方法是提前进行拆分和索引,但由于我访问.csv的方式,目前无法实现这一点。我对这种方法的问题是,我觉得转换应该都在get_feature_columns()内处理 - 是不是最佳实践"在发送到模型之前处理输入函数内的转换,或者我是否应该尝试找到在模型本身中执行拆分或查找的方法?

我担心的是,我现在需要一个单独的serving_input_fn(),需要执行当前input_fn()中显示的相同转换,但如果进行了更改,这些转换很容易失去同步一个而不是另一个。是否还有其他选择可以避免这个问题?

1 个答案:

答案 0 :(得分:1)

input_fn中发生的事情与model_fn中发生的事情之间的区别完全取决于您在推理时的行为。一般的经验法则是:

  • 如果您需要对训练输入和预测输入执行转换,请将其放在model_fn
  • 如果您只需要在训练输入或预测输入上进行转换,请将其放入相应的input_fn(服务或培训/评估)

这只是一个方便的规则,它将以任何方式工作。但是,通常您希望尽可能多地在图表外部进行预处理以进行训练/评估,因此当您训练多个历元或尝试新的模型体系结构时,您不会复制预处理的计算时间。但是,您希望尽可能多地将预处理放在图形内部进行推理,因为从延迟角度来看,它(通常)会比代理更高效。

希望这可以解决问题。