Неправильная логика кода для обработки большого количества файлов - PullRequest
1 голос
/ 22 марта 2019

Я новичок и новичок в Python и обработке изображений. Для проекта колледжа я пытался тренировать распознавание символов для регионального языка. У меня очень большой набор данных (около 90000 изображений). Часть кода ниже предназначена для извлечения изображений в набор данных. Однако, когда я запускаю код, он исчерпывает мою 8-Гб оперативную память, и мой компьютер зависает. Это может быть связано с обработкой большого количества изображений.

Характеристики моего ПК: Intel Core I5 ​​8-го поколения 8 ГБ оперативной памяти NVIDIA Geforce GTX 1060 6GB.

Есть ли обходной путь для этого, чтобы я мог запустить его на моем ПК? Любая помощь будет оценена.

%matplotlib inline


root_dir = os.getcwd()
img_dir = os.path.join(root_dir, 'images')

pixels = np.array(['pixel_{:04d}'.format(x) for x in range(1024)])
flag = True

for char_name in sorted(os.listdir(img_dir)):
    char_dir = os.path.join(img_dir, char_name)
    img_df = pd.DataFrame(columns=pixels)

    for img_file in sorted(os.listdir(char_dir)):
        image = pd.Series(imageio.imread(os.path.join(char_dir, img_file)).flatten(), index=pixels)
        img_df = img_df.append(image.T, ignore_index=True)

    img_df = img_df.astype(np.uint8)
    img_df['character'] = char_name

    img_df.to_csv('data.csv', index=False, mode='a', header=flag)
    flag=False

    print('=', end='')


df = pd.read_csv('data.csv')

df['character_class'] = LabelEncoder().fit_transform(df.character)
df.drop('character', axis=1, inplace=True)
df = df.astype(np.uint8)

1 Ответ

0 голосов
/ 22 марта 2019

Хотя я не являюсь основной причиной вашей проблемы, я добавлю некоторые заметки из моего опыта работы с большими наборами данных.

  1. Текстовые файлы, в том числе CSV, дороги в планедисковое пространство, память (строки) и обработка (чтение, анализ и приведение к другим типам).Каждый раз, когда pandas читает файл CSV, он читает его построчно, анализирует следующий и создает объекты python.Это отнимает много времени.
  2. Большие текстовые файлы, особенно большие .csv файлы, плохо работают с пандами.Я действительно не могу указать точную причину, но я не мог загрузить более 2 ГБ CSV-файла в информационный кадр с 16 ГБ оперативной памяти.
  3. Хорошая сериализация данных всегда лучше, чем обычная.Однако pickle - это довольно общий метод сериализации объектов Python, который хорошо работает со многими типами объектов.Конечно, у него есть уязвимости, бла-бла-бла.Для чистой исследовательской работы с питоном это отличный простой способ сохранить ваши объекты.DataFrame от Panda интегрировал его среди других способов сохранения вашего объекта.Используйте `df.to_pickle ('/ path / to / file.pkl')
  4. Огромный файл - это единственная точка отказа.Я думаю, что лучше иметь несколько файлов и использовать подходящее средство чтения данных для вашей задачи.

Сказав это, вот мой

%matplotlib inline


root_dir = os.getcwd()
img_dir = os.path.join(root_dir, 'images')

pixels = np.array(['pixel_{:04d}'.format(x) for x in range(1024)])
flag = True
chars = sorted(os.listdir(img_dir))

for char_name in chars:
    char_dir = os.path.join(img_dir, char_name)
    img_df = pd.DataFrame(columns=pixels)

    for img_file in sorted(os.listdir(char_dir)):
        image = pd.Series(imageio.imread(os.path.join(char_dir, img_file)).flatten(), index=pixels)
        img_df = img_df.append(image.T, ignore_index=True)

    img_df = img_df.astype(np.uint8)
    img_df['character'] = char_name

    img_df.to_pickle(f'{char_name}_data.pkl')
    flag=False

    print('=', end='')


df = pd.concat([pd.read_pickle(f'{char_name}_data.pkl') for char_name in chars],axis=0)

df['character_class'] = LabelEncoder().fit_transform(df.character)
df.drop('character', axis=1, inplace=True)
df = df.astype(np.uint8)

В качестве альтернативы, вы можетеиспользуйте один файл, добавив свой фрейм данных и сохранив окончательный вариант:

%matplotlib inline


root_dir = os.getcwd()
img_dir = os.path.join(root_dir, 'images')

pixels = np.array(['pixel_{:04d}'.format(x) for x in range(1024)])
df = pd.DataFrame(columns=['character'] + pixels.tolist())
for char_name in sorted(os.listdir(img_dir)):
    char_dir = os.path.join(img_dir, char_name)
    img_df = pd.DataFrame(columns=pixels)

    for img_file in sorted(os.listdir(char_dir)):
        image = pd.Series(imageio.imread(os.path.join(char_dir, img_file)).flatten(), index=pixels)
        img_df = img_df.append(image.T, ignore_index=True)

    img_df = img_df.astype(np.uint8)
    img_df['character'] = char_name
    df.append(image_df)
    print('=', end='')

df.to_pickle('data.pkl')
df = pd.read_pickle('data.pkl')

df['character_class'] = LabelEncoder().fit_transform(df.character)
df.drop('character', axis=1, inplace=True)
df = df.astype(np.uint8)

Пожалуйста, дайте мне знать, если это решит вашу проблему.Это кажется небольшой проблемой, но я знаю, что такие вещи могут отнимать много времени для отладки.

PS Поскольку вы используете магию, я предполагаю, что вы используете Jupyter.Ваша машина +/- ноутбук;Я бы предложил закрыть все работающие ядра в вашем ноутбуке / лаборатории jupyter и использовать только одно при работе с большими данными.

...