Прекратите использовать flow_from_directory и используйте вместо него flow_from_dataframe.

Как видно из моей предыдущей статьи, исследовательские проекты могут быть трудными из-за недостатка организации. Так много ресурсов вокруг, что иногда замедляют процесс исследования.

В этой статье я собираюсь сосредоточиться на наборах данных, состоящих из изображений, особенно на тех, которые предназначены для задач классификации изображений. Мы увидим, как запуск тренингов Keras на таких наборах данных дает некоторые преимущества при использовании фреймов данных Pandas.

Keras предоставляет возможность использовать большие наборы данных при работе с нейронными сетями: на этапе обучения или оценки. Это модуль предварительной обработки Keras, который имеет несколько методов для загрузки данных с диска и их динамической предварительной обработки. Самый распространенный метод - flow_from_directory(), который представляет собой очень простой рабочий процесс, поскольку вам просто нужно разделить файлы изображений по папкам для каждого класса. Генератор примет каждую папку как классы для обучения. Да, это довольно просто, но это требует разработки трудоемких скриптов для копирования или перемещения изображений с одной стороны на другую для каждой версии обучающего набора данных.

  • Но что, если вы решите внести некоторые изменения для конкретного эксперимента, например разделить один класс на два? - Управление версиями набора данных
  • Что, если вы хотите составить набор данных с изображениями, полученными из двух или более наборов данных? - Комбинация нескольких наборов данных
  • Что, если вы хотите обучить две метки одновременно, потому что ваша сетевая модель имеет два выхода? - Проблемы с несколькими задачами

Мы увидим, как использование библиотеки Pandas поможет решить эти проблемы.

У Keras есть функция генератора, которая предназначена для использования фрейма данных Pandas для загрузки данных с диска: flow_from_dataframe(). Этот фрейм данных должен иметь столбец, в котором вы указываете имя файла изображения для каждого элемента. С помощью этого параметра и параметра directory Keras будет составлять путь для каждого файла изображения следующим образом: os.path.join(directory, <filename_column>)
На этом этапе вы можете забыть идею организации файлов в папках классов, и вместо этого вы можете просто разместить их все в та же папка.

В каждом из следующих разделов делается попытка ответить на один из трех предыдущих вопросов с помощью метода thisflow_from_dataframe().

Управление версиями набора данных

Мой рабочий процесс при работе с наборами данных заключается в том, что я вручную создаю систему управления версиями: каждая версия является результатом любых изменений, которые я вношу для конкретного эксперимента: добавление дополнительных данных, модификации меток, исправления и т. Д.

Это приводит к наличию разных версий наборов данных, которые более четко представлены фреймами данных, вместо того, чтобы создавать отдельную папку, в которую копируются изображения с новой структурой классов. Самое сильное в этом то, что файлы большого размера (изображения) все еще находятся в том же каталоге. Следовательно, у вас может быть несколько версий набора данных (файлов csv), состоящих из разных комбинаций одних и тех же изображений.

Комбинация нескольких наборов данных

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

Давайте посмотрим на пример:

Предположим, у вас есть набор данных 1 и набор данных 2 со следующими путями к изображениям:

/media/datasets/dataset_1/train/image_1.png
/media/datasets/dataset_1/train/image_2.png
/media/datasets/dataset_2/train/0289323/image_1.png
/media/datasets/dataset_2/train/3453453/image_1.png

Набор данных 1 имеет структуру, в которой все изображения находятся в одном каталоге: dataset_1 / train / *. Однако набор данных 2 отличается, в нем есть подпапки, а само имя файла изображения повторяется («image_1.png»), поэтому нам нужно добавить эту подпапку в столбец имени файла. Это будут два фрейма данных и соответствующие им вызовы методов Keras:

Чтобы создать объединенную версию (набор данных 3), нам просто нужно добавить путь, по которому оба пути становятся разными: «dataset_1 /» и «dataset_2 /».

В этом примере мы должны установить параметр каталога в flow_from_dataframe() на общий путь, чтобы Keras мог составлять пути, которые работают для обоих наборов данных.

Я предлагаю создать папку, например, dataset_3, с символическими ссылками на оба набора данных:

~/datasets $ mkdir dataset_3
~/datasets $ cd dataset_3
~/datasets/dataset_3 $ ln -s ~/datasets/dataset_1/train dataset_1
~/datasets/dataset_3 $ ln -s ~/datasets/dataset_2/train dataset_2
~/datasets/dataset_3 $ ls -l
dataset_1 -> /home/sruiz/datasets/dataset_1/train
dataset_2 -> /home/sruiz/datasets/dataset_2/train

Это сделано только для организационных целей, поскольку базовый путь, по которому различаются оба набора данных, будет: / home / datasets / dataset_3 вместо более общего: / home / datasets. Но , это также может быть очень полезно, если наборы данных расположены в разных местах и ​​не имеют общего базового пути - и вы не хотите их перемещать.

Многозадачные задачи

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

Для такого рода задач нам нужны две метки для каждого входа на этапе обучения. Таким образом, подход разделения файлов по папкам для каждой метки, хотя это возможно, предполагает наличие одной папки для каждой комбинации меток. Что-то это могло привести к созданию большого количества папок.

Преимущество фрейма данных в том, что у вас может быть столбец для метки кошка / собака и еще один для цвета кожи. При использовании метода flow_from_dataframe() с вашей сетью с двумя выходами вам просто нужно указать в параметре y_col, какие столбцы являются метками:

Спасибо за прочтение.

Серхио Руис (@serchu)