从TFRecord保存和读取可变大小列表

Dra*_*ag0 10 tensorflow

将稀疏矢量存储到TFRecord的最佳方法是什么?我的稀疏向量只包含1和0所以我决定只保存'ones'所在的索引,如下所示:

example = tf.train.Example(
        features=tf.train.Features(
            feature={
                'label': self._int64_feature(label),
                'features' : self._int64_feature_list(values)
            }
        )
    )
Run Code Online (Sandbox Code Playgroud)

这里values是包含'ones'索引的列表.这个values数组有时包含数百个元素,有时根本没有.之后,我只是将序列化示例保存到tfrecord.后来,我正在读这样的tfrecord:

features = tf.parse_single_example(
    serialized_example,
    features={
        # We know the length of both fields. If not the
        # tf.VarLenFeature could be used
        'label': tf.FixedLenFeature([], dtype=tf.int64),
        'features': tf.VarLenFeature(dtype=tf.int64)
    }
)

label = features['label']
values = features['features']
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为values数组被识别为稀疏数组,我没有得到我保存的数据.在tfrecords中存储稀疏张量以及如何读取它的最佳方法是什么?

Eli*_*xby 1

如果你只是序列化 1 的位置,你应该能够通过一些技巧得到正确的稀疏张量:

解析后的稀疏张量features['features']将如下所示:

features['features'].indices: [[batch_id, position]...]

哪里position有无用的枚举。

但你真的想feature['features']看起来像[[batch_id, one_position], ...]

one_position您在稀疏张量中指定的实际值在哪里。

所以:

indices = features['features'].indices
indices = tf.transpose(indices) 
# Now looks like [[batch_id, batch_id, ...], [position, position, ...]]
indices = tf.stack([indices[0], features['features'].values])
# Now looks like [[batch_id, batch_id, ...], [one_position, one_position, ...]]
indices = tf.transpose(indices)
# Now looks like [[batch_id, one_position], [batch_id, one_position], ...]]
features['features'] = tf.SparseTensor(
   indices=indices,
   values=tf.ones(shape=tf.shape(indices)[:1])
   dense_shape=1 + tf.reduce_max(indices, axis=[0])
)
Run Code Online (Sandbox Code Playgroud)

瞧!features['features']现在表示一个矩阵,它是一批稀疏向量的串联。

注意:如果你想将其视为密集张量,你必须这样做tf.sparse_to_dense,并且密集张量将具有形状[None, None](这使得它很难使用]。如果你知道最大可能的向量长度,你可能想要对其进行硬编码:dense_shape=[batch_size, max_vector_length]