将大数据加载到 TensorFlow 2.0 中,而不将其加载到 RAM 上

Ani*_*B H 8 python numpy tensorflow tensorflow-datasets

我已经处理并保存了一个大型视频和音频文件数据集(大约8到9GB的数据)数据被保存为2个numpy数组,每种模式一个文件的形状是(number_of_examples,maximum_time_length,feature_length)

我想使用这些数据来训练我的神经网络来执行分类任务 我正在使用 TensorFlow 2.0 Beta 版本 我在 Google Colab 上运行所有代码(安装 tf-2.0 beta 后) 每次我在 tf.data 中加载数据时使用虚拟机的整个 RAM,并且会话被迫重新启动。

以前的方法:

我尝试了两种方法

1)将两个变量全部加载到RAM中并将其转换为张量

2)将数据加载为内存映射数组(从磁盘)并将其加载到 tf.data

然而,这两种方法都会加载 RAM 并强制虚拟机重新启动

代码:

# Access the Audio memory from disk without loading
X_audio = np.memmap('gdrive/My Drive/Codes/audio_data.npy', dtype='float32', mode='r').reshape(2198,3860,74)

# Access the Video memory from disk without loading
X_video = np.memmap('gdrive/My Drive/Codes/video_data.npy', dtype='float32', mode='r').reshape(2198,1158,711)

# Load labels
with open('gdrive/My Drive/Codes/label_data_3','rb') as f:
    Y = pkl.load(f)

dataset = tf.data.Dataset.from_tensor_slices((X_audio, X_video, Y)).shuffle(2198).batch(32)
Run Code Online (Sandbox Code Playgroud)

错误:您的会话在使用所有可用 RAM 后崩溃

Pra*_*rni 8

使用tensorflow 2.x.x数据集 API,您可以使用tf.data.Dataset.from_generator生成器函数创建数据集。该生成器函数将通过 numpy memap 完成读取工作。

下面的代码创建一个虚拟数据文件,然后从磁盘上的文件中一次读取一个示例。它可以轻松更新以读取多个示例以增加 IO 吞吐量(如果您需要在下面的代码示例中实现这一点,请告诉我)。

# imports
import numpy as np
import pathlib
import tensorflow as tf

# create huge numpy array and save it to disk
file = pathlib.Path("huge_data.npy")
examples = 5000
example_shape = (256, 256)
huge_data_shape = (examples, *example_shape)
huge_data_dtype = np.float64

# create file if does not exist
if not file.is_file():
    print("creating file with random data and saving to disk")
    numpy_data = np.random.rand(*huge_data_shape).astype(huge_data_dtype)
    np.save(file, numpy_data)

# memmap the file
numpy_data_memmap = np.load(file, mmap_mode='r')


# generator function
def data_generator():
    return iter(numpy_data_memmap)


# create tf dataset from generator fn
dataset = tf.data.Dataset.from_generator(
    generator=data_generator,
    output_types=huge_data_dtype,
    output_shapes=example_shape,
)

# consume huge dataset
for i, ex in enumerate(dataset):
    print(i, ex.shape, ex.dtype)

Run Code Online (Sandbox Code Playgroud)

输出:

0 (256, 256) <dtype: 'float64'>
1 (256, 256) <dtype: 'float64'>
2 (256, 256) <dtype: 'float64'>
3 (256, 256) <dtype: 'float64'>
...
4995 (256, 256) <dtype: 'float64'>
4996 (256, 256) <dtype: 'float64'>
4997 (256, 256) <dtype: 'float64'>
4998 (256, 256) <dtype: 'float64'>
4999 (256, 256) <dtype: 'float64'>
Run Code Online (Sandbox Code Playgroud)


Yng*_*Moe 1

您可能应该使用 HDF5 文件格式,这是在硬盘驱动器上存储多维数组的好方法。具体来说,我建议您使用该h5py包,它提供了在 Python 中使用 HDF5 文件的无缝接口。

现在,我还没有使用 TensorFlow 2,但在 TF1 中,我们可以从 Python 生成器创建 TensorFlow 数据集对象。下面,我们有一个生成器,它将加载 HDF5 文件并从数组中提取随机元素(沿第一个轴)。

import h5py
import random

def iterate_dataset(dataset_file, dataset_name):
    h5 = h5py.File(dataset_file, 'r')
    idxs = range(len(h5[dataset_name]))
    random.shuffle(idxs)

    for i in idxs:
        yield h5[dataset_name][i]
    h5.close()
Run Code Online (Sandbox Code Playgroud)

这里还有将数组保存为 HDF5 文件的代码

import h5py

def save_array(arr, dataset_file, dataset_name, compress=True)
    with h5py.File(dataset_file, 'a') as h5:
        if compress:
            dataset = h5.create_dataset(
                dataset_name,
                data=arr,
                chunks=(1, *arr.shape[1:]),
                compression='lzf'
            )
            return
        h5[dataset_name] = arr

save_array(data1, 'filename.hdf5', 'data1')
save_array(data2, 'filename.hdf5', 'data2')
Run Code Online (Sandbox Code Playgroud)

最后,可能会有一些代码错误,所以我会在我的计算机上阅读一遍。