Чтение больших файлов HDF5
Я новичок в использовании файлов HDF5, и я пытаюсь читать файлы с формами (20670, 224, 224, 3)
. Всякий раз, когда я пытаюсь сохранить результаты из hdf5 в списке или другой структуре данных, это занимает так много времени, что я прерываю выполнение, или это приводит к сбою моего компьютера. Мне нужно уметь читать 3 набора файлов hdf5, использовать их данные, манипулировать ими, использовать их для обучения модели CNN и делать прогнозы.
Мы будем благодарны за любую помощь по чтению и использованию этих больших файлов HDF5.
В настоящее время я читаю файл hdf5 так:
db = h5py.File(os.getcwd() + "/Results/Training_Dataset.hdf5")
training_db = list(db['data'])
3 ответа
Сбои, вероятно, означают, что у вас заканчивается память. Как и предложил Виньеш Пиллэй, я бы попытался разбить данные на части и работать над небольшими частями за раз. Если вы используете метод pandas read_hdf, вы можете использовать параметры итератора и chunksize для управления разбиением на части:
import pandas as pd
data_iter = pd.read_hdf('/tmp/test.hdf', key='test_key', iterator=True, chunksize=100)
for chunk in data_iter:
#train cnn on chunk here
print(chunk.shape)
Обратите внимание, что для этого требуется, чтобы hdf был в формате таблицы
Мой ответ обновлен 2020-08-03, чтобы отразить код, который вы добавили в свой вопрос. Как отметил @Tober, у вас заканчивается память. Чтение набора данных формы (20670, 224, 224, 3) станет списком объектов 3.1G. Если вы прочитаете 3 набора изображений, потребуется еще больше оперативной памяти. Я предполагаю, что это данные изображения (может быть, 20670 изображений формы (224, 224, 3))? Если это так, вы можете читать данные по фрагментам с помощью обоихh5py
а также tables
(Pytables). Это вернет данные в виде массива NumPy, который вы можете использовать напрямую (нет необходимости манипулировать с другой структурой данных).
Базовый процесс будет выглядеть так:
with h5py.File(os.getcwd() + "/Results/Training_Dataset.hdf5",'r') as db:
training_db = db['data']
# loop to get images 1 by 1
for icnt in range(20670) :
image_arr = training_db [icnt,:,:,:}
# then do something with the image
Вы также можете прочитать несколько изображений, установив первый индекс в диапазон (скажем, icnt:icnt+100
), затем обработайте цикл соответствующим образом.
Ваша проблема возникает из-за нехватки памяти. Таким образом, виртуальные наборы данных пригодятся при работе с большими наборами данных, такими как ваш. Виртуальные наборы данных позволяют отображать несколько реальных наборов данных в один набор данных с возможностью среза через слой интерфейса. Подробнее о них можно прочитать здесь https://docs.h5py.org/en/stable/vds.html
Я бы порекомендовал вам начать с одного файла за раз. Во-первых, создайте файл виртуального набора данных из ваших существующих данных, например
with h5py.File(os.getcwd() + "/Results/Training_Dataset.hdf5", 'r') as db:
data_shape = db['data'].shape
layout = h5py.VirtualLayout(shape = (data_shape), dtype = np.uint8)
vsource = h5py.VirtualSource(db['data'])
with h5py.File(os.getcwd() + "/virtual_training_dataset.hdf5", 'w', libver = 'latest') as file:
file.create_virtual_dataset('data', layout = layout, fillvalue = 0)
Это создаст виртуальный набор ваших существующих обучающих данных. Теперь, если вы хотите манипулировать своими данными, вы должны открыть свой файл в
with h5py.File(os.getcwd() + "/virtual_training_dataset.hdf5", 'r+', libver = 'latest') as file:
# Do whatever manipulation you want to do here
Еще одна вещь, которую я хотел бы посоветовать, это убедиться, что ваши индексы при нарезке