Как я могу прочитать в наборе данных изображения в виде массива с эффективным использованием памяти? - PullRequest
0 голосов
/ 01 мая 2019

Я пытаюсь загрузить набор данных изображений в виде массива.Как я могу сделать это так, чтобы я не подчеркивал ограничения ОЗУ на моей локальной машине или создавал массив, который требует слишком много памяти?Большой набор изображений - это обучающий набор, который составляет около 2 ГБ изображений.

Это предназначено для обучения остаточной нейронной сети, для которой входные данные должны быть массивом.Я использовал модули glob, PIL, skimage, sklearn и numpy, пытаясь загрузить изображения, но я делаю это, вероятно, наивно, поскольку ~ 2 ГБ изображений становится массивом ~ 17 (!) ГБ.Я пытался найти решения, примеры и тому подобное, но я довольно плохо знаком с Python, поэтому процесс идет очень медленно.

Код, используемый для загрузки изображений наивно:

import glob
from skimage.transform import resize
import numpy as np
from sklearn import datasets
from PIL import Image

def root_2_numpy(data_root):
    """
    Load raw images and output a numpy array of all images and numpy array of labels
    Also preprocesses each image to (224,224) using anti-aliasing
    """
    # load images into numpy array
    all_image_paths = list(data_root.glob('*/*'))  # get image paths
    all_image_paths = [str(path) for path in all_image_paths]  # convert to string
    image_ds = np.zeros([len(all_image_paths), 224, 224,3])  # initialize image dataset
    for i in range(len(all_image_paths)):
        print(i)
        im = Image.open(all_image_paths[i])  # read image as RGB using matplotlib
        if im.mode == 'RGBA' or im.mode == 'L' or im.mode == 'CMYK':
            im = im.convert('RGB')
        elif im.mode =='P':
            im = im.convert('RGBA')
            im = im.convert('RGB')
        im = np.array(im)
        im = resize(im, (224,224), anti_aliasing=True)  # resize image using skimage
        image_ds[i,:,:,:] = im

    # load labels into numpy array
    label_ds = datasets.load_files(data_root, load_content=False, shuffle=False)  # get labels
    n_classes = len(label_ds.target_names)
    Y_ds = np.eye(len(label_ds.target_names))[label_ds.target.reshape(-1)]

    return image_ds, Y_ds, n_classes

Я ожидалэто возвращает массивный массив размером ~ 2 ГБ, который имеет размерность (N, W, H, C) для количества изображений, ширины изображения, высоты изображения и 3 каналов для изображений.Здесь не проблема, но я также ожидаю, что у меня будут данные для меток, которые являются именами категорий в корне.

Помимо эффективной загрузки данных, я был бы очень признателен за пониманиекак мой код создает такой большой массив NumPy.Когда я пишу это, у меня возникает ощущение, что это происходит при преобразовании типов изображений для изображений, отличных от RBG, и, возможно, при создании большего количества изображений, чем предполагалось.

1 Ответ

0 голосов
/ 01 мая 2019

Тип данных по умолчанию для массива, создаваемого numpy.zeros, - 64-битная с плавающей запятой. Таким образом, image_ds = np.zeros([len(all_image_paths), 224, 224,3]) создает массив, который в 8 раз больше, чем вам нужно. Добавьте параметр dtype, чтобы image_ds имел тип данных uint8 (8-разрядные целые числа без знака):

image_ds = np.zeros([len(all_image_paths), 224, 224,3], dtype=np.uint8)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...