使用Numpy从Google Cloud Storage加载内存映射数组(mmap_mode)。

3
我想把存在谷歌存储(gs://project/file.npy)上的.npy文件作为训练数据加载到我的谷歌ML任务中。由于该文件大小超过10GB,我想使用numpy.load()函数的mmap_mode选项,以避免内存不足。
背景:我使用Keras和fit_generator以及Keras Sequence从存储在谷歌存储中的.npy文件中加载数据批次。
为了访问谷歌存储,我使用BytesIO,因为并非每个库都能访问谷歌存储。 没有mmap_mode = 'r'选项时,此代码可以正常运行:
from tensorflow.python.lib.io import file_io
from io import BytesIO

filename = 'gs://project/file'

x_file = BytesIO(file_io.read_file_to_string(filename + '.npy', binary_mode = True))
x = np.load(x_file)

如果激活mmap_mode,就会出现以下错误:
TypeError: 期望str、bytes或os.PathLike对象,而不是BytesIO
我不明白为什么它现在不再接受BytesIO了。
包含mmap_mode的代码:
x_file = BytesIO(file_io.read_file_to_string(filename + '.npy', binary_mode = True))
x = np.load(x_file, mmap_mode = 'r')

跟踪:

文件"[...]/numpy/lib/npyio.py",第444行,在load函数中,返回format.open_memmap(file, mode=mmap_mode);文件"[...]/numpy/lib/format.py",第829行,在open_memmap函数中,fp = open(os_fspath(filename), 'rb');文件"[...]/numpy/compat/py3k.py",第237行,在os_fspath函数中,TypeError: 期望 str、bytes 或 os.PathLike 对象,而不是 BytesIO(path_type.name)。


2
看一下 np.lib.npyio.format.open_memmap 的文档(或代码)。它说“磁盘上的文件名。这可能不是类似文件的对象”。在处理了 save/load 头之后,此代码使用 np.memmap,因此受到其限制。 - hpaulj
1
在memmap模式下,文件是“随机”访问的。在普通加载中,访问是顺序的 - 一个字节接一个字节地进行,没有任何回溯或寻找。 - hpaulj
2
您可以将数据集拆分成多个部分,以便逐步上传和处理吗? - Happy-Monad
1
使用您在帖子中提到的范围标头手动读取.npy文件的部分有多容易?.npy文件中的数据结构是[10000:50:50:50:1],其中10000维可以分割成较小的文件。 - DΦC__WTF
2
如果您可以将文件分割得更细,那将是我最理想的选择。如果您能够通过这种方式避免内存耗尽,问题将立即得到解决。公平地说,我不知道如何将范围头应用于您的用例,但认为分享这些信息是个好主意。 - Happy-Monad
显示剩余4条评论
1个回答

0

你可以使用 b.getvalue() 将 BytesIO 转换为 bytes

x_file = BytesIO(file_io.read_file_to_string(filename + '.npy', binary_mode = True))
x = np.load(x_file.getvalue(), mmap_mode = 'r')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接