Сводка: Недостаточно памяти при попытке обработать большой набор данных с помощью TF / Keras. Я знаю, что пакетная обработка является основным компонентом решения ... просто не понимаю, как это реализовать.
Вопрос: Как я могу считывать данные из чрезвычайно большого набора данных .h5 партиями, стандартизировать / удалить среднее значение, а затем разделить данные без нехватки памяти?
Контекст: Создание рабочего процесса для исследования неконтролируемой глубокой встроенной кластеризации (DE C ) естественных сейсмических c сигналов. Эта проблема конкретно связана с предварительной обработкой данных, то есть подготовкой данных для обучения / проверки автокодировщика / декодера.
Данные: ~ 6e6 спектрограмм сейсмических сигналов c обнаружения из массива. Размеры: (m, n, o) = (6e6, 66, 301) = (samples, freq_bins, time_bins). Данные хранятся в файле .h5 в одном наборе данных. Файл .h5 занимает на диске ~ 1 ТБ.
Аппаратное обеспечение: Dual Intel Xeon E5-2683 v4 2,1 ГГц, кэш 40 МБ, 16 ядер, 2 GPU Titan, 528 ГБ RAM
Текущая процедура предварительной обработки: 1. Соберите массив numpy, X, состоящий из M спектрограмм, выбрав M случайных индексов, отсортированных в порядке возрастания, и итеративно нарезав набор данных .h5. (Кроме того: самый быстрый подход здесь заключался в том, чтобы сохранить набор данных .h5 с фрагментами, оптимизированными для последующего чтения, а затем использовать простой "for" l oop для доступа к данным. Необычное индексирование и read_direct заняли значительно больше времени, чтобы пройти набор данных.) 2. Обрежьте ненужные данные из X (значения частотных и временных интервалов, а также последние 46 временных интервалов данных) и добавьте 4-ю ось, «p», как «интервал амплитуды». Окончательная форма: (m, n, o, p) = (M, 64,256,1). 3. Удалите среднее и стандартизируйте данные. 4. Разделите 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))
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 занимает примерно 30% ОЗУ (общий объем ОЗУ составляет 528 ГБ). Выполнение приведенного выше кода приводит к ошибке памяти, указанной ниже. Неудивительно, что у меня заканчивается память, учитывая, что операция копирует весь массив ...
---------------------------------------------------------------------------
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:
Что я пытаюсь сделать (и мне нужна ваша помощь!): Я знаю, что мое решение связано с пакетной обработкой, но я не уверен, как его реализовать, а также как связать его с эффективным способом чтения .h5 без необходимости считывать спектрограммы M в массив, а затем выполнять пакетный процесс. Я определил подход model.fit_generator, который теперь кажется устаревшим в пользу model.fit; и я читал об утилите hdf5matrix. Задано в вопросе: как я могу считывать данные из очень большого набора данных .h5 партиями, стандартизировать / удалить среднее значение, а затем разделить данные, и все это без нехватки памяти?
Сколько времени я потратил на то, чтобы понять это, я не понимаю, как собрать все части вместе, поэтому я ищу какое-нибудь продуманное руководство, которое подтолкнет меня в правильном направлении. Заранее благодарим за помощь!