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

时间:2019-06-13 05:01:40

标签: python numpy tensorflow tensorflow-datasets

我已经处理并保存了大量的视频和音频文件数据集(大约8到9 GB的数据) 数据保存为2个numpy数组,每个模态一个 文件的形状为(示例数,最大时间长度,功能长度)

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

以前的方法:

我尝试了2种方法

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

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

但是,两种方法都加载了RAM并迫使VM重新启动

代码:

# 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)
  

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

2 个答案:

答案 0 :(得分:0)

您可能应该使用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()

这也是将阵列保存为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')

最后,可能会有一些代码错误,因此一旦我在计算机上阅读,便会继续阅读。

答案 1 :(得分:0)

通过tensorflow 2.0数据集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)

输出:

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'>