首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在不耗尽内存的情况下,分批从大型.h5数据集中读取数据,并使用ImageDataGenerator和model.fit进行预处理?

如何在不耗尽内存的情况下,分批从大型.h5数据集中读取数据,并使用ImageDataGenerator和model.fit进行预处理?
EN

Stack Overflow用户
提问于 2020-06-16 07:09:21
回答 1查看 817关注 0票数 0

摘要:试图使用TF/Keras处理大型数据集时内存不足。我知道批处理是solution...just的一个主要组件,不知道如何实现。

问题:如何从一个非常大的.h5数据集中批量读取数据,标准化/删除平均值,然后拆分数据,所有这些都不会耗尽内存?

上下文:构建了一个研究自然发生地震信号的无监督深嵌入聚类的工作流程。这个问题特别是在数据的预处理中,即为训练/验证自动编码器/解码器准备数据。

的数据: ~6e6谱图的地震探测从一个阵列。尺寸:(m,n,o) = (6e6,66,301) =(样品,freq_bins,time_bins)。

数据存储在一个数据集中的.h5文件中。

.h5文件占用磁盘上的~1TB。

硬件:双Intel XeonE5-2683 v4 2.1 GHz,40 16高速缓存,16核,2台泰坦GPU,528 16内存

当前预处理过程:

  1. 集成了一个由M个随机指数组成的numpy阵列X,按递增顺序排序,并对.h5数据集进行迭代切片。(旁白:这里最快的方法是用块保存.h5数据集,以便以后阅读,然后使用一个简单的" for“循环来访问数据。花式索引和"read_direct“花费了相当长的时间从X遍历不必要的数据(freq和time值,以及最后的46个数据桶),并添加第四个轴"p",作为”振幅bin“。最终形状:(m,n,o,p) = (M,64,256,1).
  2. Remove均值和标准化数据。
  3. 将X拆分成训练/验证集。

代码语言:javascript
复制
# Define sample size:
M = int(1e6)
# Load spectrograms into X:
with h5py.File(train_dataname, 'r') as f:
    DataSpec = '/30sec/Spectrogram'
    dset = f[DataSpec]
    m, n, o = dset.shape
    index = sorted(np.random.choice(m, size=M, replace=False))
    X = np.empty([M, n, o])
    for i in range(M):
        X[i,:,:] = dset[index[i],:,:]

# Remove the frequency and time vectors from the data, trim time bins to len=256:
X = X[:,1:-1,1:256]

# Add amplitude dimension:
X = X[..., np.newaxis]
m, n, o, p = X.shape

# Remove mean & standardize data:
datagen = tf.keras.preprocessing.image.ImageDataGenerator(
    samplewise_center=True,
    samplewise_std_normalization=True)
datagen.fit(X)
X = datagen.standardize(X)

# Split data into training/validation:
X_train, X_val = train_test_split(X, test_size=0.2, shuffle=True, random_state=812)

# Free up memory:
del X

详细问题:

当M~ 1e6时,X约占RAM的30% (总RAM为528 up )。运行上面的代码会产生下面的内存错误。难怪我内存不足,因为操作是在复制整个数组.

代码语言:javascript
复制
---------------------------------------------------------------------------
MemoryError                               Traceback (most recent call last)
<ipython-input-10-fb00ad200706> in <module>
----> 1 datagen.fit(X)

~/Anaconda/anaconda3/envs/AEC-DEC/lib/python3.6/site-packages/keras_preprocessing/image/image_data_generator.py in fit(self, x, augment, rounds, seed)
    943             np.random.seed(seed)
    944 
--> 945         x = np.copy(x)
    946         if augment:
    947             ax = np.zeros(

~/Anaconda/anaconda3/envs/AEC-DEC/lib/python3.6/site-packages/numpy/lib/function_base.py in copy(a, order)
    790 
    791     """
--> 792     return array(a, order=order, copy=True)
    793 
    794 # Basic operations

MemoryError:

我想要做的事情(需要您的帮助!):我知道我的解决方案是批处理的,但是我不确定如何实现它,也不知道如何将它与一种高效的方法结合起来,而不必将M谱图读入数组,然后进行批处理。我已经确定了model.fit_generator方法,现在似乎反对model.fit;我还读过关于hdf5matrix实用程序的文章。在一个问题中指出:我如何从一个非常大的.h5数据集中成批读取数据,标准化/删除平均值,然后拆分数据,所有这些都不会耗尽内存?

虽然我花了很多时间试图解决这个问题,但我不清楚如何把所有的部分组合在一起,这就是为什么我正在寻找一些经过深思熟虑的指导来推动我朝着正确的方向前进。提前感谢您的帮助!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-06-16 21:00:12

您必须避免将X的内存占用增加一倍的进程。(我知道,这是显而易见的)。这是一个很大的数组,您需要加倍使用X = X[:,1:-1,1:256] (或者X = X[..., np.newaxis])所需的内存。

它们的关键是按照最终需要的大小/形状分配X (以避免复制)。然后修改逻辑,将数据从dset (f['/30sec/Spectrogram'])加载到中间数组(下面是ds_arr),根据需要进行修改,然后加载到X中。

我想出了另一种方法。这可能不是计算效率最高的,但避免了X的副本。

代码语言:javascript
复制
# Define sample size:
M = int(1e6)
# Load spectrograms into X:
with h5py.File(train_dataname, 'r') as f:
    DataSpec = '/30sec/Spectrogram'
    dset = f[DataSpec]
    m, n, o = dset.shape        
    index = sorted(np.random.choice(m, size=M, replace=False))

# new code:     
    X = np.empty([M, n-1, o-46, 1])
    for i in range(M):
        ds_arr=dset[index[i],1:,1:256]   
        ds_arr=ds_arr[..., np.newaxis]
        X[i,:,:,:] = ds_arr

# Remove mean & standardize data:

仔细检查我的切片符号。我不完全确定要从第二个索引中删除哪个值(第一个还是最后一个值?)。当我使用ds_arr=dset[index[i],1:-1,1:256]时,遇到了一个广播错误。错误信息是:

代码语言:javascript
复制
ValueError: could not broadcast input array from shape (63,255,1) into shape (64,255,1) 
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62402825

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档