Python tf.SequenceExample与多维数组

Python tf.SequenceExample与多维数组,python,multidimensional-array,tensorflow,protocol-buffers,Python,Multidimensional Array,Tensorflow,Protocol Buffers,在Tensorflow中,我想将多维数组保存到TFRecord中。例如: [[1, 2, 3], [1, 2], [3, 2, 1]] 由于我试图解决的任务是顺序的,因此我尝试使用Tensorflow的tf.train.SequenceExample(),在写入数据时,我成功地将数据写入了TFRecord文件。但是,当我尝试使用tf.parse\u single\u sequence\u example从TFRecord文件加载数据时,我遇到了大量的神秘错误: W tensorflow/cor

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

[[1, 2, 3], [1, 2], [3, 2, 1]]
由于我试图解决的任务是顺序的,因此我尝试使用Tensorflow的
tf.train.SequenceExample()
,在写入数据时,我成功地将数据写入了TFRecord文件。但是,当我尝试使用
tf.parse\u single\u sequence\u 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

欢迎提供任何帮助。

使用提供的代码,我无法重现您的错误,但经过一些有根据的猜测,给出了以下工作代码

import tensorflow as tf
import numpy as np
import tempfile

tmp_filename = 'tf.tmp'

sequences = [[1, 2, 3], [1, 2], [3, 2, 1]]
label_sequences = [[0, 1, 0], [1, 0], [1, 1, 1]]

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 = len(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 zip(input_sequence,
                                                          output_sequence):

        if input_sequence is not None:
            input_characters.feature.add().int64_list.value.append(input_character)

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

    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)
        for sequence, label_sequence in zip(sequences, label_sequences):
            ex = make_example(sequence, label_sequence)
            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 = {
         "input_characters": tf.FixedLenSequenceFeature([], dtype=tf.int64),
         "output_characters": tf.FixedLenSequenceFeature([], dtype=tf.int64)
    }


    return serialized_example, context_features, sequence_features

save_tf(tmp_filename)
ex,context_features,sequence_features = read_and_decode_single_example(tmp_filename)
context_parsed, sequence_parsed = tf.parse_single_sequence_example(
    serialized=ex,
    context_features=context_features,
    sequence_features=sequence_features
)

sequence = tf.contrib.learn.run_n(sequence_parsed, n=1, feed_dict=None)
#check if the saved data matches the input data
print(sequences[0] in sequence[0]['input_characters'])

所需的修改是:

  • sequence\u length=sum([len(word)表示输入序列中的单词])
    to
    sequence\u length=len(输入序列)
  • 否则,它对示例数据不起作用

  • extend
    已更改为
    append

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

    首先您的错误是什么

    错误消息告诉您,您试图读取的内容不符合您指定的要素大小。那么你在哪里指定的呢?就在这里:

    sequence_features = {
        "input_characters": tf.FixedLenSequenceFeature([], dtype=tf.int64),
        "output_characters": tf.FixedLenSequenceFeature([], dtype=tf.int64)
    }
    
    这表示“我的输入字符是一个单值序列”,但事实并非如此;你得到的是一系列的单值序列,因此是一个错误

    第二你能做什么

    如果您改为使用:

    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告诉它在读取之前长度未知。不幸的是,这意味着您的输入字符不能再作为密集向量在一个步骤中读取。相反,默认情况下,它将是一个。你可以将其转化为稠密张量,例如:

    正如您所看到的,如果您的数据不总是具有相同的长度,那么您必须在词汇表中使用一个“not_really_a_word”单词,作为默认索引。e、 假设索引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))
    
    张量

    被警告;我不确定反向传播对稀疏传感器是否“有效”,就像对稠密张量一样。这篇文章讨论了在每个序列中填充0来掩盖“not_actually_a_word”单词的丢失(请参阅文章中的“旁注:在词汇表/类中小心0”)。这似乎表明第一种方法更容易实现

    注意,这与这里描述的情况不同,其中每个示例都是序列序列。据我理解,这种方法之所以得不到很好的支持,是因为它是对本应支持的案例的滥用,;直接加载固定尺寸的嵌入件



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

    嗨,您能提供更多上下文吗?最好提供一个可以实际运行和测试的最小示例,包括如何将数据保存到文件的步骤。您的示例很难理解,如果您编辑示例以包含相关上下文,您将获得更多帮助。例如-查看您在代码中添加注释的链接,很明显,您生成序列示例的代码段不包括实际写入数据的代码。尝试这些更改时,我收到错误:
    TypeError:[37]具有类型,但预期为:(,)
    。我想我看到了问题,
    [[1,2,3],[1,2],[3,2,1]]
    应该是一个序列而不是多个序列。你试过答案中的片段了吗?我在运行它时没有遇到任何错误(Ubuntu,python3.4,没有GPU的TF)。你的输入数据看起来和问题中的完全一样吗?我的输入完全一样,但是你在处理
    [[1,2,3],[1,2],[3,2,1]]
    这是三个不同的示例。这是一个示例。从文档中可以看出:它包含一个键值存储(功能);其中//每个键(字符串)映射到一个功能消息(它是压缩ByteList、//FloatList或Int64List中的一个).对于您的数据结构,除了单独存储列表并在阅读后加入列表之外,我看不到任何其他解决方案。
    array((1,2,3),  (2,3,0),  (3,2,1))