Добавление больших массивов в .h5 занимает много времени и места - PullRequest
0 голосов
/ 28 декабря 2018

Я хотел создать файл, содержащий огромный массив размером (50000,1998,101).

count = 0
X_data = []
Y_data = []
X_file = tables.open_file('train_X.h5', mode='w')
Y_file = tables.open_file('train_Y.h5', mode='w')
x_atom = tables.Float64Atom()
y_atom = tables.Float64Atom()
x_ds = X_file.create_earray(X_file.root, 'X_array', x_atom,(0,1998,101))
y_ds = Y_file.create_earray(Y_file.root, 'Y_array', y_atom,(0,497,1))
print(x_ds.shape)
for i in range(50000):
    print("iter",i)
    b =  np.random.randint(53)
    x, y =  create_training_example(background_new[b], elitas, negatives,i) 
    x = np.swapaxes(x,0,1) #shape (1998, 101)
    y = np.swapaxes(y,0,1) #shape (497, 1)
    x=np.expand_dims(x,0)
    y=np.expand_dims(y,0)
    x_ds.append(x)
    y_ds.append(y)
X_file.close()
Y_file.close()
print("Finished")

Приведенный выше код занимает огромное количество времени на самой итерации 2000, и его там убивают.Файл h5 с 600 массивами занимает около 1,2 ГБ. Почему он занимает такое большое пространство и время? Есть ли способ создать большой набор данных для такого большого массива путем добавления массивов?

Заранее спасибо

Ответы [ 2 ]

0 голосов
/ 02 января 2019

Изображение ниже представляет собой график набора данных (синего цвета), используемого (как сообщает Pytables), и прошедшего времени (красного цвета) для примера, который я выложил выше.Он показывает билинейное поведение при создании / записи до 20 000 наборов данных (EArrays).Обратите внимание на «излом», как только размер DS mem превышает 2,5 ГБ.
Примечание: мой первый набор статистики был от запуска на локальном диске с резервным копированием MS OneDrive. Это, кажется, является причиной нерегулярных ударов и покачиваний (неPytables chunking). Я перезапустил на другом диске, и получил более плавное поведение. Оба были запущены на Windows-7 с 24 ГБ ОЗУ.
Изображение ниже показывает статистику от 2-го запуска. enter image description here

Изображение ниже показывает статистику с 1-го запуска. Небольшие колебания / неровности в данных синхронизации не связаны с разбиением на Pytables. Производительность записи большого набора данных примерно на 15% нижес резервным копированием MS OneDrive.

enter image description here

0 голосов
/ 28 декабря 2018

@ Дженнингс, вы уже добавляете массивы x и y к массивам x_ds и y_ds.Так что это не совсем решение вашей проблемы.Я не могу запустить твой код без твоей функции create_training_example.Однако я использовал его для создания простого примера, который использует тот же метод для создания train_x.h5 (только) и заполнения массивов, созданных с помощью np.arange().reshape().Я создал 2000 массивов формы (1998, 101).Это может быть хорошим прокси для поведения, которое вы видите.Код работает «достаточно быстро» на моем ноутбуке (с 24 ГБ ОЗУ) и создает файл train_X.h5, который составляет 3,9 ГБ.Исходя из вашего поста, это кажется подходящим (600 массивов ~ = 1,2 ГБ).Очевидно, вы получите гораздо больший файл, если создадите 50 000 массивов (может быть ~ 100 ГБ?)

Возможно, у вас проблема с аппаратными ресурсами.Я предлагаю вам запустить мой пример, чтобы посмотреть, как он себя ведет.После того, как вы получите эту точку данных, вы можете решить, что исследовать дальше.Некоторые идеи:

  1. Создание train_X.h5 и train_Y.h5 отдельно.
  2. Заполнение наборов данных Earray 500 массивами за раз (измените код, чтобы открыть обучающие файлы в режиме добавления)

Код ниже (изменено 1/2/2019): увеличен диапазон () и добавлен вывод статистики ОЗУ и синхронизации:

import numpy as np
import tables
import time
X_file = tables.open_file('train_X.h5', mode='w')
x_atom = tables.Float64Atom()
x_ds = X_file.create_earray(X_file.root, 'X_array', x_atom,(0,1998,101))
print(x_ds.shape)
start = time.clock()
for i in range(20000):
    x = np.arange(1998*101).reshape(1998, 101)
    x=np.expand_dims(x,0)
    x_ds.append(x)
    if ( ((i+1) % 100) == 0 ) :
        print('iter=',i,'DS Mem Size  = ', x_ds.size_in_memory, 'Elapsed time =', (time.clock() - start))

print ('Elapsed time =', (time.clock() - start) )
X_file.close()
print("Finished")
...