Почему использование базы данных (redis, SQL) поможет при загрузке больших данных, а в ОЗУ не хватает памяти? - PullRequest
0 голосов
/ 04 января 2019

Мне нужно взять 100 000 изображений из каталога, поместить их все в один большой словарь, где ключи - это идентификаторы изображений, а значения - это массивы пикселей изображений. Создание этого dict занимает 19 ГБ моей оперативной памяти, и у меня всего 24 ГБ. Затем мне нужно упорядочить словарь по ключу и в конце взять только значения этого упорядоченного словаря и сохранить его в виде одного большого массива. Мне нужен этот большой массив NumPy, потому что я хочу отправить его в функцию sklearn train_test_split и разделить все данные для обучения и тестирования наборов по их метке. Я нашел этот вопрос, где у них та же проблема с нехваткой ОЗУ на шаге, где после создания словаря 19 ГБ я пытаюсь отсортировать слова: Как отсортировать БОЛЬШОЙ словарь , и люди предлагают использовать базу данных.

def save_all_images_as_one_numpy_array():
    data_dict = {}
    for img in os.listdir('images'):
        id_img = img.split('_')[1]
        loadimg = load_img(os.path.join('images', img))
        x = image.img_to_array(loadimg)
        data_dict[id_img] = x

data_dict = np.stack([ v for k, v in sorted(data_dict.items(), key = lambda x: int(x[0]))])
mmamfile = open_memmap('trythismmapfile.npy', dtype=np.float32, mode='w+',shape=data_dict.shape)
mmamfile[:] = data_dict[:]


def load_numpy_array_with_images():
    a = open_memmap('trythismmapfile.npy', dtype=np.float32, mode='r')

При использовании np.stack я складываю каждый массив numpy в новый массив, и здесь у меня заканчивается ОЗУ. Я не могу позволить себе купить больше оперативной памяти. Я думал, что могу использовать Redis в Docker-контейнере, но я не понимаю, почему и как использование базы данных решит мою проблему?

1 Ответ

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

Причина использования БД помогает, потому что библиотека БД хранит данные на жестком диске, а не в памяти.Если вы посмотрите документацию для библиотеки, которую предлагает связанный ответ, то увидите, что первым аргументом является имя файла, демонстрирующее использование жесткого диска.
https://docs.python.org/2/library/bsddb.html#bsddb.hashopen

Однако связанныйречь идет о сортировке по значению , а не по ключу.Сортировка по ключу будет занимать гораздо меньше памяти, хотя у вас, вероятно, будут проблемы с памятью при обучении вашей модели.Я бы предложил попробовать что-то вроде

# Get the list of file names
imgs = os.listdir('images')

# Create a mapping of ID to file name
# This will allow us to sort the IDs then load the files in order
img_ids = {int(img.split('_')[1]): img for img in imgs}

# Get the list of file names sorted by ID
sorted_imgs = [v for k, v in sorted(img_ids.items(), key=lambda x: x[0])]

# Define a function for loading a named img
def load_img(img):
    loadimg = load_img(os.path.join('images', img))
    return image.img_to_array(loadimg)

# Iterate through the sorted file names and stack the results
data_dict = np.stack([load_img(img) for img in sorted_imgs])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...