在Tensorflow中,我想将多维数组保存到TFRecord。例如:

[[1, 2, 3], [1, 2], [3, 2, 1]]

由于我要解决的任务是顺序的,因此我尝试使用Tensorflow的tf.train.SequenceExample(),并且在写入数据时成功将数据写入TFRecord文件。但是,当我尝试使用tf.parse_single_sequence_example从TFRecord文件中加载数据时,我遇到了很多神秘的错误:
W tensorflow/core/framework/op_kernel.cc:936] Invalid argument: Name: , Key: input_characters, Index: 1.  Number of int64 values != expected.  values size: 6 but output shape: []
E tensorflow/core/client/tensor_c_api.cc:485] Name: , Key: input_characters, Index: 1.  Number of int64 values != expected.  values size: 6 but output shape: []

我用来尝试加载数据的功能如下:
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 = {
         "input_characters": tf.FixedLenSequenceFeature([],           dtype=tf.int64),
         "output_characters": tf.FixedLenSequenceFeature([], dtype=tf.int64)
    }

    context_parsed, sequence_parsed = tf.parse_single_sequence_example(
    serialized=serialized_example,
    context_features=context_features,
    sequence_features=sequence_features
)

context = tf.contrib.learn.run_n(context_parsed, n=1, feed_dict=None)
print context

我用来保存数据的功能在这里:
# http://www.wildml.com/2016/08/rnns-in-tensorflow-a-practical-guide-and-undocumented-features/
def make_example(input_sequence, output_sequence):
    """
    Makes a single example from Python lists that follows the
    format of tf.train.SequenceExample.
    """

    example_sequence = tf.train.SequenceExample()

    # 3D length
    sequence_length = sum([len(word) for word in input_sequence])
    example_sequence.context.feature["length"].int64_list.value.append(sequence_length)

    input_characters = example_sequence.feature_lists.feature_list["input_characters"]
    output_characters = example_sequence.feature_lists.feature_list["output_characters"]

    for input_character, output_character in izip_longest(input_sequence,
                                                          output_sequence):

        # Extend seems to work, therefore it replaces append.
        if input_sequence is not None:
            input_characters.feature.add().int64_list.value.extend(input_character)

        if output_characters is not None:
            output_characters.feature.add().int64_list.value.extend(output_character)

    return example_sequence

任何帮助都将受到欢迎。

最佳答案

我有同样的问题。我认为这完全可以解决,但是您必须确定输出格式,然后弄清楚如何使用它。

首先您遇到什么错误?

错误消息告诉您您尝试读取的内容不符合您指定的功能大小。那么您在哪里指定呢?就在这儿:

sequence_features = {
    "input_characters": tf.FixedLenSequenceFeature([], dtype=tf.int64),
    "output_characters": tf.FixedLenSequenceFeature([], dtype=tf.int64)
}

这说“我的input_characters是一个单值序列”,但这不是真的。您所拥有的是一个序列的单值序列,因此是一个错误。

第二您可以做什么?

如果您改为使用:
a = [[1,2,3], [2,3,1], [3,2,1]]
sequence_features = {
    "input_characters": tf.FixedLenSequenceFeature([3], dtype=tf.int64),
    "output_characters": tf.FixedLenSequenceFeature([3], dtype=tf.int64)
}

因为您已指定顶层序列的每个元素长3个元素,所以您的代码不会出错。

另外,如果您没有固定长度的序列,那么您将不得不使用其他类型的功能。
sequence_features = {
    "input_characters": tf.VarLenFeature(tf.int64),
    "output_characters": tf.VarLenFeature(tf.int64)
}

VarLenFeature告诉它读取前的长度是未知的。不幸的是,这意味着您的input_characters不能再一步就被读取为密集向量。而是默认为SparseTensor。您可以使用tf.sparse_tensor_to_dense将其变成密集的张量,例如:
input_densified = tf.sparse_tensor_to_dense(sequence_parsed['input_characters'])

正如您一直在the article中提到的那样,如果您的数据长度不总是相同,则您的词汇表中必须有一个“not_really_a_word”字样,您将其用作默认索引。例如假设您有索引0映射到“not_really_a_word”字词,然后使用
a = [[1,2,3],  [2,3],  [3,2,1]]

python列表将最终成为
array((1,2,3),  (2,3,0),  (3,2,1))

张量。

被警告;我不确定像SparseTensors那样,反向传播是否“奏效”,就像密集的张量那样。 wildml article讨论每个序列的填充0,以掩盖“not_actually_a_word”一词的损失(请参见:“注意:请谨慎对待您的词汇/类(class)中的0”)。这似乎表明第一种方法将更易于实现。

注意,这与此处描述的情况不同,在此情况下,每个示例都是一个序列序列。据我了解,这种方法没有得到很好支持的原因是因为它滥用了本应支持的情况;直接加载固定大小的嵌入。

我将假设您接下来要做的就是将这些数字转换为单词嵌入。您可以使用tf.nn.embedding_lookup将索引列表转换为嵌入列表

09-26 03:03