Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/tensorflow/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将.npy(numpy文件)送入tensorflow数据管道_Numpy_Tensorflow_Dataset_Data Pipeline - Fatal编程技术网

将.npy(numpy文件)送入tensorflow数据管道

将.npy(numpy文件)送入tensorflow数据管道,numpy,tensorflow,dataset,data-pipeline,Numpy,Tensorflow,Dataset,Data Pipeline,Tensorflow似乎缺少“.npy”文件的读取器。 如何将数据文件读入新的tensorflow.data.Dataset管线? 我的数据无法存储在内存中 每个对象都保存在单独的“.npy”文件中。每个文件包含两个不同的数据阵列作为特征,一个标量作为标签。您的数据适合内存吗?如果是,您可以按照文档部分的说明进行操作: 使用NumPy数组 如果所有输入数据都适合内存,那么从它们创建数据集的最简单方法是将它们转换为tf.Tensor对象并使用Dataset.from_Tensor_slices()

Tensorflow似乎缺少“.npy”文件的读取器。 如何将数据文件读入新的tensorflow.data.Dataset管线? 我的数据无法存储在内存中


每个对象都保存在单独的“.npy”文件中。每个文件包含两个不同的数据阵列作为特征,一个标量作为标签。

您的数据适合内存吗?如果是,您可以按照文档部分的说明进行操作:

使用NumPy数组

如果所有输入数据都适合内存,那么从它们创建数据集的最简单方法是将它们转换为tf.Tensor对象并使用Dataset.from_Tensor_slices()

如果文件不适合内存,唯一推荐的方法似乎是首先将
npy
数据转换为
TFRecord
格式,然后使用
TFRecord
数据集格式,该格式可以在不完全加载内存的情况下进行流式传输

FWIW,对我来说,
TFRecord
不能直接用npy文件的目录名或文件名实例化似乎很疯狂,但这似乎是纯Tensorflow的一个限制

如果您可以将单个大型npy文件拆分为较小的文件,每个文件大致代表一个训练批,那么您可以在Keras中编写一个自定义数据生成器,只生成当前批所需的数据


一般来说,如果数据集无法放入内存,将其存储为单个大型npy文件会使处理变得非常困难,最好先将数据重新格式化为TFRecord或多个npy文件,然后使用其他方法。

您可以使用tf.py_func执行此操作,请参见示例。
parse函数只需将文件名从字节解码为字符串,然后调用np.load

更新:类似以下内容:

def read_npy_file(item):
    data = np.load(item.decode())
    return data.astype(np.float32)

file_list = ['/foo/bar.npy', '/foo/baz.npy']

dataset = tf.data.Dataset.from_tensor_slices(file_list)

dataset = dataset.map(
        lambda item: tuple(tf.py_func(read_npy_file, [item], [tf.float32,])))
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)

实际上,使用TensorFlow而不是TFRecords直接读取NPY文件是可能的。关键的部分是和,并查看了的文档。为简单起见,假设给定了一个float32 NPY文件,其中包含一个具有形状
(N,K)
的数组,并且您事先知道特性
K
的数量,以及它是float32数组的事实。NPY文件只是一个带有小标题的二进制文件,后跟原始数组数据(对象数组不同,但我们现在考虑的是数字)。简而言之,您可以使用如下函数查找此标头的大小:

def read_npy_file(item):
    data = np.load(item.decode())
    return data.astype(np.float32)

file_list = ['/foo/bar.npy', '/foo/baz.npy']

dataset = tf.data.Dataset.from_tensor_slices(file_list)

dataset = dataset.map(
        lambda item: tuple(tf.py_func(read_npy_file, [item], [tf.float32,])))
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中提取,因此需要提前知道文件名。另一个限制是,实际上,解决方案要求每个数据集只使用一个文件,或者使用具有相同头大小的文件,尽管您知道所有数组的大小实际上应该是相同的

诚然,如果考虑这种方法,最好是使用一个没有标题的纯二进制文件,或者硬编码功能的数量,或者从不同的源读取它们…

问题设置 我有一个文件夹,里面的图像被输入到一个InceptionV3模型中,用于提取特征。这似乎是整个过程的一个巨大瓶颈。作为一种解决方法,我从每张图像中提取特征,然后将它们以
.npy
格式存储在磁盘上

现在我有两个文件夹,一个用于图像,另一个用于相应的
.npy
文件。在
tf.data.Dataset
管道中加载
.npy
文件时存在明显问题

变通办法 我遇到了TensorFlow的官方教程,该教程为这个线程(和我)遇到的问题提供了一个很好的解决方法

加载nummpy文件 首先,我们需要创建一个映射函数,该函数接受
.npy
文件名并返回numpy数组

#加载numpy文件
定义映射函数(特征路径):
特征=np.加载(特征路径)
返回特性
使用
tf.numpy\u功能
使用,我们可以包装任何python函数并将其用作TensorFlow操作。该函数必须接受numpy对象(这正是我们想要的)

我们用所有
.npy
文件名的列表创建一个
tf.data.Dataset

dataset=tf.data.dataset.from\u tensor\u切片(特征路径)
然后,我们使用
tf.data.Dataset
API的
map
函数来完成剩下的任务

#使用map并行加载numpy文件
dataset=dataset.map(lambda项:tf.numpy_函数(
地图功能[item],tf.16),
num_parallel_calls=tf.data.AUTOTUNE)

我看过该指南,但不幸的是,它不适合记忆!非常感谢,但将我的numpy文件转换为TFRecord是我最不想做的事情,因为我有大约5000000个文件,这将需要很长时间才能完成。我想我会同意keras发电机的想法。再次感谢!您的5000000个文件中的每个文件都无法放入内存?我的情况与OP类似,我有大约一百万个小文件,使用一个简单的Keras生成器工作起来很有魅力。不幸的是,它不能很好地用于多处理,并且比tf.data API慢,因此我最终将整个数据集转换为TFRecord文件,性能比Keras生成器提高了很多,但这只是我的问题,可能有所不同