将 .npy(numpy 文件)输入到张量流数据管道中

2024-02-14

Tensorflow 似乎缺少“.npy”文件的阅读器。 如何将数据文件读入新的tensorflow.data.Dataset pipline? 我的数据不适合内存。

每个对象都保存在单独的“.npy”文件中。每个文件包含 2 个不同的 ndarrays 作为特征和一个标量作为它们的标签。


实际上可以使用 TensorFlow 而不是 TFRecords 直接读取 NPY 文件。关键部分是tf.data.FixedLengthRecordDataset https://www.tensorflow.org/api_docs/python/tf/data/FixedLengthRecordDataset and tf.io.decode_raw https://www.tensorflow.org/api_docs/python/tf/io/decode_raw,并查看文档NPY 格式 https://docs.scipy.org/doc/numpy/neps/npy-format.html。为了简单起见,我们假设一个 float32 NPY 文件包含一个形状为(N, K)给出了,并且你知道特征的数量K事先,以及它是一个 float32 数组的事实。 NPY 文件只是一个带有小标头的二进制文件,后面跟着原始数组数据(对象数组不同,但我们现在考虑的是数字)。简而言之,您可以使用如下函数找到该标头的大小:

def npy_header_offset(npy_path):
    with open(str(npy_path), 'rb') as f:
        if f.read(6) != b'\x93NUMPY':
            raise ValueError('Invalid NPY file.')
        version_major, version_minor = f.read(2)
        if version_major == 1:
            header_len_size = 2
        elif version_major == 2:
            header_len_size = 4
        else:
            raise ValueError('Unknown NPY file version {}.{}.'.format(version_major, version_minor))
        header_len = sum(b << (8 * i) for i, b in enumerate(f.read(header_len_size)))
        header = f.read(header_len)
        if not header.endswith(b'\n'):
            raise ValueError('Invalid NPY file.')
        return f.tell()

这样你就可以创建一个像这样的数据集:

import tensorflow as tf

npy_file = 'my_file.npy'
num_features = ...
dtype = tf.float32
header_offset = npy_header_offset(npy_file)
dataset = tf.data.FixedLengthRecordDataset([npy_file], num_features * dtype.size, header_bytes=header_offset)

该数据集的每个元素都包含一长串表示单个示例的字节。您现在可以对其进行解码以获得实际的数组:

dataset = dataset.map(lambda s: tf.io.decode_raw(s, dtype))

不过,这些元素将具有不确定的形状,因为 TensorFlow 不会跟踪字符串的长度。因为您知道特征的数量,所以您可以强制执行形状:

dataset = dataset.map(lambda s: tf.reshape(tf.io.decode_raw(s, dtype), (num_features,)))

同样,您可以选择在批处理后执行此步骤,或以您喜欢的任何方式组合它。

限制是您必须提前知道功能的数量。不过,可以从 NumPy 标头中提取它,只是有点麻烦,而且在任何情况下都很难从 TensorFlow 中提取,因此需要提前知道文件名。另一个限制是,该解决方案要求您每个数​​据集仅使用一个文件或具有相同标头大小的文件,尽管如果您知道所有数组都具有相同的大小,那么实际上应该是这样。

诚然,如果有人考虑这种方法,最好拥有一个没有标题的纯二进制文件,并且要么对功能数量进行硬编码,要么从不同的源读取它们......

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 .npy(numpy 文件)输入到张量流数据管道中 的相关文章

随机推荐