Чтение больших файлов 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

Еще одна вещь, которую я хотел бы посоветовать, это убедиться, что ваши индексы при нарезке тип данных, иначе вы получите ошибку.

Другие вопросы по тегам