Как изобразить список разреженных фич в тензорном потоке? - PullRequest
0 голосов
/ 03 июля 2018

Я пытаюсь использовать tensorflow.SequenceExample для хранения своих функций для чего-то вроде системы вопросов и ответов, которые описаны ниже.

Учитывая текст вопроса, например, "как далеко находится дом". Я хотел бы рассматривать это как последовательность и представлять каждое слово, используя разреженное представление. Это не горячая кодировка. Каждое слово имеет несколько логических функций.

how -> [ 1 0 0 0 1] -> [1,5]
far -> [ 0 1 1 0 0] -> [2,3]
is  -> [ 1 1 0 0 1] -> [1,2,5]
home-> [ 0 0 1 1 0] -> [3,4]

Мой текст теперь представлен как: [[1,5], [2,3], [1,2,5], [3,4]]

Точно так же у меня есть другой текст, скажем answer text, который имеет аналогичное представление списков списков.

Как мне записать это в формате тензорного потока TFRecord? Я попробовал это в коде ниже. Что я знаю об ошибке, так это то, что я посылаю int64list функции, которая ожидает только одно значение int64.

Кто-нибудь имел успех в представлении таких данных?

import tensorflow as tf


example = {

    'query': [[123, 543, 234, 2322],
              [133, 243, 233, 256, 4332],
              [232, 356, 632],
              [153, 143, 231, 456]],
    'document': [[1156, 12322],
                 [2133, 14332],
                 [1143, 1343, 1232, 1356, 1632],
                 [1153, 1143]],
    'label': 1
}

tmp_filename = 'tf.tmp'


def make_example(example):
    """
    Makes a single example from Python lists that follows the
    format of tf.train.SequenceExample.
    """
    query_features = example['query']
    keyword_features = example['document']
    example_sequence = tf.train.SequenceExample()

    example_sequence.context.feature["query_length"].int64_list.value.append(len(query_features))
    example_sequence.context.feature["keyword_length"].int64_list.value.append(len(keyword_features))

    query = example_sequence.feature_lists.feature_list["query"]
    document = example_sequence.feature_lists.feature_list["document"]

    for feat in query_features:
        print("Appending: ", feat)
        #query.feature.add().int64_list.value.append(feat)
        query.feature.add().list.value.append(feat)


    for feat in keyword_features:
        document.feature.add().int64_list.value.append(feat)

    return example_sequence


# Write all examples into a TFRecords file
def save_tf(filename):
    with open(filename, 'w') as fp:
        writer = tf.python_io.TFRecordWriter(fp.name)

        ex = make_example(example)
        writer.write(ex.SerializeToString())
        writer.close()


#
def read_and_decode_single_example(filename):
    filename_queue = tf.train.string_input_producer([filename],
                                                    num_epochs=None)

    reader = tf.TFRecordReader()
    _, serialized_example = reader.read(filename_queue)

    context_features = {
        "length": tf.FixedLenFeature([], dtype=tf.int64)
    }

    sequence_features = {

        "query": tf.VarLenFeature([], dtype=tf.int64),
        "document": tf.VarLenFeature([], dtype=tf.int64)
    }

    return serialized_example, context_features, sequence_feature

1 Ответ

0 голосов
/ 06 июля 2018

По моему опыту, лучший способ использовать массивы кодирования - использовать numpy's tostring для извлечения необработанных байтов. При чтении в наборе данных вы можете использовать TensorFlow's decode_raw.

Для вашей кодировки должно быть достаточно:

for feat in query_features:
    print("Appending: ", feat)
    raw_feat = np.array(feat, dtype=np.int64).tostring()
    query.feature.add().bytes_list.value.append(raw_feat)

for feat in keyword_features:
    raw_feat = np.array(feat, dtype=np.int64).tostring()
    document.feature.add().bytes_list.value.append(raw_feat) 

Обратите внимание, что вы должны убедиться, что вы используете тот же тип данных на другой стороне при декодировании (tf.int64 в этом примере), иначе вы получите бред.

...