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

Я всегда был в состоянии удивления, когда запускал рекордные записные книжки Jupyter, предоставленные Джереми, и читал лекции: как это возможно, что я так легко победил, всего в нескольких строках кода, результаты, полученные командой блестящих профессоров и докторантов престижных университетов, у которых на годы больше опыта, чем у меня? Конечно, это не так просто, как кажется. Большая часть тяжелой работы была проделана невероятной библиотекой fast.ai, самоуверенной библиотекой, которая включает в себя результаты новейших исследований и по возможности делает выбор по умолчанию для пользователей. освобождая меня от всевозможных ловушек и лазеек при выборе из бесконечного набора фреймворков, архитектур и оптимизаторов с последующей тонкой настройкой гиперпараметров, каждый шаг которой играет важную роль в успешном обучении модели глубокого обучения.

Иллюзия компетентности

Однако, как почти всегда, с большой абстракцией приходит большое невежество; это создает иллюзию компетентности, которая быстро дает сбой перед лицом реальных проблем. Записная книжка урока 1 посвящена построению модели классификации домашних животных из 37 категорий с использованием CNN. Поскольку легенда гласит, что любая статья с милыми изображениями домашних животных привлечет внимание людей, я помещу ее здесь.

Вот пример фрагмента кода из записной книжки:

data = ImageDataBunch.from_name_re(path_img, fnames, pat, ds_tfms=get_transforms(), size=224, bs=bs
                                  ).normalize(imagenet_stats)

А пока сосредоточьтесь на ds_tfms=get_transforms() и не обращайте внимания на остальные детали. Здесь ds_tfms обозначает преобразование набора данных, более известное как увеличение данных, которое генерирует копии изображений, каждое из которых изменяется таким образом, что оно выглядит немного иначе визуально, но все же отчетливо относится к той категории, к которой оно должно принадлежать. Если вам кажется, что это звучит отрывочно, значит, вы правы. Однако, что касается урока 1, я достиг такого уровня понимания; У меня было приблизительное представление о том, что он делает, и я предположил, что он работает. Это прекрасно подошло для набора данных классификации домашних животных в Оксфорде, но привело меня прямо к кораблекрушению, когда позже я работал над созданным мной самостоятельно, коллекцией изображений автомобилей, помеченных в соответствии с углами или видами. Вот несколько примеров, на каждом из которых обозначены разные углы:

Замечу, что я пометил эти 1000 с лишним изображений с нуля за несколько часов, используя потрясающую платформу для подготовки данных Platform.ai, созданную, опять же, нашим замечательным Джереми Ховардом. Я настоятельно рекомендую вам это проверить. Это чертовски круто, и пока это можно использовать бесплатно.

Расследование

Поскольку это также проблема классификации изображений, я в основном скопировал и вставил коды из записной книжки урока 1 с небольшими изменениями. Однако тренировка с треском провалилась и даже не смогла достичь точности выше 80%. Это в высшей степени необычно, поскольку сама задача чрезвычайно проста: фотографии различаются только по очень основным геометрическим свойствам. Я начал просматривать коды, особенно сосредотачиваясь на черных ящиках, которые, как я предполагал, работали раньше. В конце концов я начал исследовать get_transforms() и изучил его документацию.

def get_transforms(do_flip:bool=True, flip_vert:bool=False, max_rotate:float=10.0, max_zoom:float=1.1, max_lighting:float=0.2, max_warp:float=0.2, p_affine:float=0.75, p_lighting:float=0.75, xtra_tfms:Optional[Collection[Transform]]=None) → Collection[Transform]

Аргумент по умолчанию do_flip:bool=True мне кажется очень подозрительным. Вот еще несколько документов:

do flip: если True, случайное отражение применяется с вероятностью 0,5

flip vert: требуется do flip = True. Если True, изображение можно перевернуть по вертикали или повернуть на 90 градусов, в противном случае применяется только горизонтальный переворот.

Также есть демонстрация трансформации, конечно, с милыми фотографиями домашних животных:

Таким образом, очевидно, что преобразования по умолчанию перевернут мои изображения по горизонтали с вероятностью 50%. Это. Подходит для котят, так как котенок, перевернутый по горизонтали, по-прежнему остается котенком, но для моего конкретного набора данных метка зависит от самого горизонтального угла обзора самого автомобиля. В результате преобразования изображений полностью испортят метки изображений. Неудивительно, что обучение не работает. После добавления дополнительного аргумента к вызову функции get_transforms(do_flip=False) обучение прошло как обычно, и я получил 96% -ную точность проверки.

Урок

Какой урок здесь? Как было сказано в начале этой статьи, fast.ai - очень самоуверенная библиотека с множеством встроенных предположений, поэтому она способна работать на очень высоком уровне с множеством наборов данных и задач глубокого обучения прямо из коробки. Например, увеличение данных по умолчанию очень хорошо работает с большинством наборов данных классификации изображений. Однако для определенных наборов данных, которые не соответствуют предположениям, например, что горизонтальная ориентация не меняет метки изображений, будет значительно хуже. Чтобы иметь возможность использовать библиотеку для большего количества наборов данных, нам неизбежно нужно заглядывать в черные ящики и понимать, что делает библиотека.

Однако вопрос здесь в том, когда заглядывать в черные ящики. В подходе к обучению сверху вниз есть много достоинств. Если мы просто заглянем в каждый черный ящик, с которым сталкиваемся, то процесс обучения ничем не отличается от восходящего. Моя стратегия заключается в том, чтобы делать это только тогда, когда черный ящик не работает должным образом. В духе старой мудрой поговорки «если не сломалось, не чини», я бы предложил здесь: «Если абстракция не сломана, не смотри в нее». Говоря языком машинного обучения, процесс разбиения абстракции и точной настройки нашего понимания подобен обучению модели с большим количеством данных. В начале обучения, когда модель обработала только небольшой набор данных, она плохо обобщается; когда мы только начали изучать и использовать абстракцию, мы переосмыслили наше понимание черного ящика по тем немногим примерам, которые мы видели.

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

В следующий раз при изучении материала сверху вниз, если вы столкнетесь с трудностями при применении его к реальной проблеме, не паникуйте, не сомневайтесь в подходе к обучению или даже сразу переключитесь обратно на кроличью нору обучения снизу вверх. Напомните себе, что это неотъемлемая и действительно самая полезная часть процесса обучения сверху вниз, точно так же, как решение сложных задач для изучения математики. Проведите исследование, прочтите документацию, разберитесь в исходном коде или даже погрузитесь в математическую теорию, лежащую в основе, пока вы не уточните свое понимание абстракции, достаточное для решения проблемы. Вы значительно лучше поймете концепцию и то, как вы растете. В то же время, в отличие от восходящего подхода, когда вы не имеете ни малейшего понятия, почему вы изучаете все материалы до самого конца, у вас всегда будет мотивация и чувство цели на протяжении всего процесса обучения, как и каждая частичка Ваша работа направлена ​​на решение стоящей перед вами проблемы. Для меня обучение сверху вниз было гораздо более приятным и полезным опытом. Я надеюсь, что вам это тоже понравится. Удачного обучения сверху вниз.