Если вы используете библиотеку fastai для обучения своих моделей PyTorch, вы используете API блока данных, понимаете вы это или нет.

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

Как действительно понять, что это за классы и что происходит (и почему) на каждом этапе?

Могу я предложить, что сработало для меня… создание ваших собственных подклассов ItemBase и ItemList, следуя учебнику Custom ItemList в документации fastai. Это то, что я называю путем к нирване блоков данных, и именно этот подход я попытался продемонстрировать в коде (доступном в этом репозитории GitHub) и из которого я выделяю уроки, извлеченные из статьи, которая вам предстоит.

ПРИМЕЧАНИЕ. Я твердо верю, что можно больше узнать об использовании этой структуры, сначала прочитав и запустив связанный код, а затем закодировав его вручную (без копирования и вставки), чем с помощью любого другие средства. Это не означает, что чтение документации, выделение и подчеркивание важных понятий не важно (поверьте мне, я делаю больше, чем от меня справедлива), только то, что для того, чтобы это прочно закрепилось в вашем мозгу, вы должны сделай это. Так что получите код, запустите его и полюбите код. Используя его и содержание этой статьи, поставьте перед собой цель продемонстрировать индивидуальное понимание, кодируя все самостоятельно.

ОБНОВЛЕНИЕ: Часть 2 уже доступна. См. Записную книжку yelp-01-custom-itemlist здесь.

API с высоты 50 000 футов

Что такое API блока данных?

API блока данных fastai определяет механизм цепочки для преобразования необработанных данных (например, в файлах изображений, файлах .csv, пандах DataFrames и т. Д.) В необходимые PyTorch Datasets и Dataloaders, которые передаются в forwardфункцию вашего nn.Module подкласса. Менее чем в 10 строках кода вы можете определить все необходимое для разделения данных на наборы данных для обучения, проверки и, при необходимости, тестирования, применить преобразования и упаковать соответствующие загрузчики данных в нечто, называемое DataBunch для обучения. API также предоставляет способ сохранить ваши преобразования и предварительную обработку для использования в будущих наборах данных / загрузчиках данных, которые вы позже захотите использовать во время вывода.

Как работает API блока данных?

Вот пример того, как это работает, из основной документации:

data = (ImageItemList.from_folder(path)
                     .split_by_folder()
                     .label_from_folder()
                     .add_test_folder()
                     .transform(tfms, size=64)
                     .databunch())

По сути, процесс таков:

  1. Определите источник ваших входных данных (то есть ваши значения X) с помощью подкласса ItemList, имеющего отношение к вашим данным. Это может быть что угодно, что у вас есть (например, .csv, DataFrame pandas, текстовый файл, изображения и т. Д.). Есть несколько встроенных ItemList подклассов, которые вы можете использовать "из коробки" для графических, табличных, совместных и текстовых данных. Вы также можете создать свой собственный, как мы сделаем здесь, создав подкласс одного из этих встроенных классов ItemList или самого ItemList class.
  2. Определите, как вы хотите разделить входные данные на наборы данных для обучения и проверки, используя для этого один из встроенных механизмов.
  3. Определите источник ваших целей (то есть ваши значения y) и объедините их с входными данными ваших наборов данных для обучения и проверки в форме объектов fastai LabelList. LabelList является подклассом класса PyTorch Dataset.
  4. Добавьте тестовый набор данных (необязательно).
  5. Добавьте преобразования к вашим LabelList объектам (необязательно). Здесь вы можете применить увеличение данных к одному или к обоим вашим входным данным и целям.
  6. Создайте загрузчики данных PyTorch из наборов данных, определенных выше, и упакуйте их в fastai DataBunch.

Как только это будет сделано, у вас будет все необходимое для обучения, проверки и тестирования любого PyTorch nn.Module с помощью библиотеки fastai. У вас также будет все необходимое, чтобы впоследствии сделать выводы на основе будущих данных.

API с высоты 1000 футов

Что это за классы и что происходит и почему на каждом этапе описанного выше API?

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

База предметов:

Класс ItemBase определяет, как выглядит элемент в ваших входных данных или ваших целях. Например, наш пример кода включает настраиваемый подкласс input ItemBase, в котором элемент определяется как состоящий как из табличных (непрерывные и категориальные данные), так и из числовых текстовых токенов. Если бы мы решали задачу классификации, наши целевые элементы были бы определены как подкласс Category ItemBase (см. Его определение здесь).

Здесь следует помнить, что ваш ввод (ваши x) и ваша цель (ваши y) являются элементами, как определено подклассами отдельныеItemBase.

ItemList:

ItemList определяет коллекции «элементов» (например, ItemBase объектов), включая способ их индивидуальной выборки и отображения. Отдельные ItemList классы используются для определения ваших входных данных (ваших значений X), а также ваших целей (ваших значений y). В библиотеке вы найдете несколько встроенных ItemList подклассов для каждого из них, которые, вероятно, можно использовать в большинстве случаев.

Класс ItemList также служит прототипом для создания отдельных ItemList экземпляров для ваших наборов данных для обучения, проверки и, при необходимости, тестирования. В некотором смысле, когда вы создаете ItemList, вы также создаете шаблон для создания из него экземпляров для обучения, проверки и, при необходимости, ItemList тестирования. Например, приведенная ниже функция «split» вернет отдельный экземпляр ItemList как для обучающего, так и для проверочного набора в объекте ItemLists.

ImageItemList.from_folder(path)
             .split_by_folder()

Списки предметов:

Коллекция ItemList экземпляров для ваших входных данных или целей.

LabelList:

LabelList - это набор данных PyTorch, который объединяет ваши входные и целевые ItemList классы (входные ItemList + цели ItemList = LabelList). Вы получите LabelList экземпляр для каждого из ваших обучающих и проверочных ItemList экземпляров, возвращаемых в LabelLists объекте, когда ваша функция «label» работает с вашим ItemLists объектом.

Например:

ImageItemList.from_folder(path)
             .split_by_folder()
             .label_from_folder()

В конце split_by_folder у вас есть объект ItemLists, содержащий два ItemList объекта (один для представления ваших обучающих элементов, а другой - для вашей проверки). Когда вы вызываете label_from_folder для этого ItemLists объекта, он создает необходимые ItemList экземпляры для ваших целей и объединяет их с входными ItemList экземплярами, чтобы сформировать LabelList экземпляров для каждого вашего обучения. и наборы данных проверки. Эти LabelList объекты упаковываются и возвращаются в форме объекта LabelLists.

Вы можете указать, какой ItemList подкласс использовать для ваших целей, с помощью аргумента label_cls. Если вы этого не сделаете, он определит, какой тип использовать, на основе ваших целевых значений.

Предварительная обработка.
Здесь также выполняются любые PreProcessor классы, которые вы передали в свой ItemList класс. Эти классы определяют, что вы хотите сделать с вашими данными один раз, прежде чем они будут преобразованы в наборы данных / загрузчики данных PyTorch. Примеры включают такие вещи, как разметка и нумерация текста, заполнение пропущенных значений в таблицах и т. Д.

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

Вы можете определить PreProcessor по умолчанию или набор PreProcessors, который вы хотите запускать, перегрузив переменную класса _processor в вашем пользовательском ItemList.

LabelLists:

Набор LabelList экземпляров, который вы получаете в результате вашей функции «маркировки». Опять же, LabelList` является PyTorch Dataset и, по сути, определяет вещи, ваши входные данные и, необязательно, цели, передаваемые в forward функцию вашей модели.

Преобразует:

Преобразования определяют увеличение данных, которое вы хотите выполнить для одного или обоих ваших входных и целевых наборов данных.

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

DataBunch:

DataBunch - это набор загрузчиков данных PyTorch, возвращаемых при вызове функции databunch. Он также определяет, как они создаются на основе ваших обучающих, проверочных и, при необходимости, LabelList экземпляров.

Итак, в итоге:

  • Вы определите отдельный ItemList как для ваших входных данных, так и для ваших целей.
  • Объект ItemLists представляет собой набор ItemList объектов (у вас будет ItemList экземпляр для каждого из ваших наборов данных… обучение, проверка и, при необходимости, тестирование).
  • LabelList объединяет ваши входные ItemList экземпляры с вашими целевыми ItemList экземплярами. LabelList подклассы PyTorch Dataset для предоставления входных данных и, при необходимости, целей, которые передаются в forward функцию вашего nn.Module подкласса.
  • Объект LabelLists представляет собой набор LabelList объектов (у вас будет LabelList экземпляр для наборов данных для обучения и проверки после выполнения функции метки).
  • Любая предварительная обработка происходит во время обработки построения объекта LabelLists. Предварительная обработка определяется вашим обучающим набором данных и применяется к вашему набору данных проверки. Если вы добавите набор тестов, как мы это делаем выше, к вашему тесту будет применена та же предварительная обработка, что и к вашему набору проверки.
  • Преобразования применяются к вашим входным данным и / или целям после того, как у вас есть окончательный набор LabelLists (который теперь может включать LabelList для вашего тестового набора данных, если он был добавлен, как указано выше).
  • Последним шагом в API является создание вашего DataBunch и объекта, который определяет, как PyTorch DataLoaders создаются из ваших LabelList объектов (т.е. вашего PyTorch Datasets), и делает их доступными для обучения.

Опять же, возьмите и запустите код, сохраняя эту статью под рукой во время работы с ней. В прилагаемой записной книжке много аннотаций, поскольку я кодирую и тестирую биты построчно (API блоков данных можно объединять в цепочки, но часто проще отлаживать и разрабатывать, реализуя его построчно, как я). Помните, что pdb.set_trace - ваш друг, и распечатайте форму вещей и содержимое других вещей по мере необходимости, чтобы улучшить ваше собственное понимание этого прекрасного API.

Ресурсы для справок на вашем пути к просветлению

Эта история публикуется в Noteworthy, куда ежедневно приходят более 10 000 читателей, чтобы узнать о людях и идеях, формирующих наши любимые продукты.

Подпишитесь на нашу публикацию, чтобы увидеть больше историй о продуктах и ​​дизайне, представленных командой Journal.