用SQLite格式为TFF创建自定义联邦图像数据集的最佳方法是什么?



我浏览了CIFAR-100内置数据集的源代码,并决定为FairFace数据集创建一个兼容的版本,以便在将FairFace转换为与CIFAR-100非常相似的结构后,能够在不进行任何修改的情况下利用其他内置函数。

我确实搜索了一下,但无法找到CIFAR-100 SQLite数据库是如何创建的-特别是如何将图像转换为BLOB进行存储。经过一些尝试和错误,我试着这样做:

sample = getDatabyIndex(train_labels, index)
example = tf.train.Example(features=tf.train.Features(feature={
'image' : bytes_feature(sample[0].tobytes()),
'label' : int64_feature(sample[1])
}))
example = example.SerializeToString()
cur.execute("insert into examples('split_name','client_id','serialized_example_proto') values(?,?,?)", ('train', i, sqlite3.Binary(example)))

对训练数据中的每个样本执行此操作,对测试数据执行类似操作。我能够使用以下解码方法加载它:

def parse_proto(tensor_proto):
parse_spec = {
'image': tf.io.FixedLenFeature(shape=(), dtype=tf.string),
'label': tf.io.FixedLenFeature(shape=(), dtype=tf.int64),
}
decoded_example = tf.io.parse_example(tensor_proto, parse_spec)
return collections.OrderedDict(
image=tf.reshape(tf.io.decode_raw(decoded_example['image'], tf.uint8), (224,224,3)),
label=decoded_example['label'])

然而,我注意到的是,最后的sqlite。lzma压缩归档文件的大小为6.4 GB,而数据集的源归档文件的大小为555mb。我猜测,由于我存储图像的方式,如果以更兼容的方式存储图像,压缩就不能正常工作。我从CIFAR-100代码中看到,图像直接加载为形状(32,32,3)的FixedLenFeatures,这意味着它们是这样存储的,但我无法找到这样存储图像的方法。为我工作的唯一方法是bytes_feature路线。

最好的/推荐的方法是什么?

如果没有更多关于LZMA压缩的信息,就很难回答大小增加的问题。

要直接使用与tff.simulation.datasets.cifar100.load_data中CIFAR-100数据集相同的tf.io.FixedLenFeature,tf.train.Example需要使用int64_feature()来构建'image'键而不是字节。这可能需要将sample[0]转换为不同的dtype(假设它是np.ndarray)。

在解码:

  1. 首先解析为int64的(N, M, 3)张量。从tensorflow_federated/python/模拟/数据/cifar100.py # L31:

    'image': tf.io.FixedLenFeature(shape=(32, 32, 3), dtype=tf.int64),
    
  2. 强制转换为tf.unit8。从tensorflow_federated/python/模拟/数据/cifar100.py # L37:

    image=tf.cast(parsed_features['image'], tf.uint8),
    

注意:由于在协议缓冲区(https://developers.google.com/protocol-buffers/docs/encoding#varints)中使用了可变编码,使用int64不会为序列化表示增加显著的开销(至少小于4倍)。

相关内容

  • 没有找到相关文章

最新更新