2016-10-05 7 views
2

Ich habe eine grundlegende input_fn, die unten mit Tensorflow Estimators verwendet werden kann. Es funktioniert einwandfrei, ohne den Parameter num_epochs einzustellen; der erhaltene Tensor hat eine diskrete Form. Pass in num_epochs als alles andere als None führt zu einer unbekannten Form. Mein Problem liegt in der Konstruktion von Sparse-Tensoren unter Verwendung von num_epochs; Ich kann nicht herausfinden, wie man die Tensoren generisch erzeugt, ohne die Form des Eingangstensors zu kennen.Wie erstelle ich `input_fn` mit` read_batch_examples` mit `num_epochs` set?

Kann jemand an eine Lösung für dieses Problem denken? Ich würde gerne num_epochs=1 übergeben können, um nur 1 mal über den Datensatz auswerten zu können, und auch an predict zu übergeben, um eine Reihe von Vorhersagen über die Größe des Datensatzes zu erhalten, nicht mehr und nicht weniger.

def input_fn(batch_size): 
    examples_op = tf.contrib.learn.read_batch_examples(
     FILE_NAMES, 
     batch_size=batch_size, 
     reader=tf.TextLineReader, 
     num_epochs=1, 
     parse_fn=lambda x: tf.decode_csv(x, [tf.constant([''], dtype=tf.string)] * len(HEADERS))) 

    examples_dict = {} 
    for i, header in enumerate(HEADERS): 
     examples_dict[header] = examples_op[:, i] 

    continuous_cols = {k: tf.string_to_number(examples_dict[k], out_type=tf.float32) 
         for k in CONTINUOUS_FEATURES} 

    # Problems lay here while creating sparse categorical tensors 
    categorical_cols = { 
     k: tf.SparseTensor(
      indices=[[i, 0] for i in range(examples_dict[k].get_shape()[0])], 
      values=examples_dict[k], 
      shape=[int(examples_dict[k].get_shape()[0]), 1]) 
     for k in CATEGORICAL_FEATURES} 

    feature_cols = dict(continuous_cols) 
    feature_cols.update(categorical_cols) 
    label = tf.string_to_number(examples_dict[LABEL], out_type=tf.int32) 

    return feature_cols, label 

Antwort

3

Ich habe das oben genannte Problem gelöst, indem eine spezifische Funktion zu schaffen, was auf einer input_fn erwartet wird; Es nimmt eine dichte Spalte auf und erstellt einen SparseTensor, ohne die Form zu kennen. Die Funktion wurde ermöglicht mit tf.range und tf.shape. Ohne weitere Umschweife, hier ist der Arbeits generic input_fn Code, der unabhängig von num_epochs gesetzt wird funktioniert:

def input_fn(batch_size): 
    examples_op = tf.contrib.learn.read_batch_examples(
     FILE_NAMES, 
     batch_size=batch_size, 
     reader=tf.TextLineReader, 
     num_epochs=1, 
     parse_fn=lambda x: tf.decode_csv(x, [tf.constant([''], dtype=tf.string)] * len(HEADERS))) 

    examples_dict = {} 
    for i, header in enumerate(HEADERS): 
     examples_dict[header] = examples_op[:, i] 

    feature_cols = {k: tf.string_to_number(examples_dict[k], out_type=tf.float32) 
        for k in CONTINUOUS_FEATURES} 

    feature_cols.update({k: dense_to_sparse(examples_dict[k]) 
         for k in CATEGORICAL_FEATURES}) 

    label = tf.string_to_number(examples_dict[LABEL], out_type=tf.int32) 

    return feature_cols, label 


def dense_to_sparse(dense_tensor): 
    indices = tf.to_int64(tf.transpose([tf.range(tf.shape(dense_tensor)[0]), tf.zeros_like(dense_tensor, dtype=tf.int32)])) 
    values = dense_tensor 
    shape = tf.to_int64([tf.shape(dense_tensor)[0], tf.constant(1)]) 

    return tf.SparseTensor(
     indices=indices, 
     values=values, 
     shape=shape 
    ) 

hoffte, das hilft jemand!

Verwandte Themen