摘要:试图使用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内存
当前预处理过程:
# 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 )。运行上面的代码会产生下面的内存错误。难怪我内存不足,因为操作是在复制整个数组.
---------------------------------------------------------------------------
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数据集中成批读取数据,标准化/删除平均值,然后拆分数据,所有这些都不会耗尽内存?
虽然我花了很多时间试图解决这个问题,但我不清楚如何把所有的部分组合在一起,这就是为什么我正在寻找一些经过深思熟虑的指导来推动我朝着正确的方向前进。提前感谢您的帮助!
发布于 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的副本。
# 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]时,遇到了一个广播错误。错误信息是:
ValueError: could not broadcast input array from shape (63,255,1) into shape (64,255,1) https://stackoverflow.com/questions/62402825
复制相似问题