Сегодня мы узнаем о загрузке данных и оптимизаторах.

Послойное последовательное изменение единиц (LSUV)

07a_lsuv.ipynb

Перед тем, как перейти к темам урока, рассмотрим еще один метод инициализации.



Как мы видели, получить дисперсию, равную единице, с помощью модели довольно сложно, потому что даже мелочи могут это испортить. Основная идея LSUV состоит в том, чтобы позволить компьютеру принимать все эти решения.

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

Это LSUV делается один раз перед тренировкой. Если вы используете небольшие мини-партии, вы также можете использовать более одной. Мы делаем только прямой проход, поэтому в одной мини-партии нет ничего особенного.

Основы API блока данных

08_data_block.ipynb

Тестировать модель с полноразмерными изображениями ImageNet неразумно, потому что это требует много времени и вычислительной мощности. Было доказано, что использование меньших изображений, таких как 32x32, говорит нам почти столько же, сколько использование обычных изображений. Джереми пошел дальше и создал две уменьшенные версии ImageNet, которые содержали всего десять тысяч классов. Результаты показали, что вещи, которые хорошо работали с этими наборами данных, также дали хорошие результаты в полноразмерных наборах данных.



ImageNet достаточно большой, чтобы не умещаться, вероятно, ни в одной из наших ОЗУ, поэтому нам нужен способ считывать его партиями.

Получить файлы

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

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

Мы могли бы просто поместить все файлы в ListContainer, но было бы намного лучше, если бы мы могли получить изображение сразу, когда мы вызываем функцию get. ImageList делает это, наследуя ItemList, который наследует ListContainer. ItemList - это просто функция, которая получает элементы, путь и преобразования. Преобразования вызываются по порядку (если есть), и данные будут обновлены, так что старые данные будут перезаписаны. Подробнее о компоновке: https://en.wikipedia.org/wiki/Function_composition_(computer_science) ImageList, с другой стороны, это функция, которая открывает нам изображения при вызове get.

Давайте возьмем пример функции преобразования. Часто в наборе данных могут быть черно-белые изображения, которые могут вызвать некоторые проблемы. Проблема в том, что RGB будет 3-канальным изображением, тогда как BW будет 1-канальным изображением. Ниже приведены два способа решить эту проблему. Либо путем создания класса или функции.

Раздельная проверка установлена ​​

Затем давайте создадим класс, который будет использовать это для разделения данных.

Ярлык

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

Вопрос: что, если ваши данные о тренировках не содержат всех категорий? Джереми решил создать еще одну категорию, в которую будут добавлены все невидимые категории.

Преобразовать в тензор

Мы пока не можем использовать их, потому что они представлены в формате PIL, а не в тензорном формате.

DataBunch

Несколько слов о CNN.

Так будет выглядеть наше первое ядро. Поскольку мы используем изображения RGB, c-in равно 3, но в общем случае мы умножаем число 9*c-in на каждом шаге. Мы не хотим, чтобы результат был чем-то большим, потому что это не будет пустой тратой нашего времени.

Раньше люди использовали ядра 5x5 и 7x7, но сегодня мы знаем, что гораздо лучше иметь ядра 3x3.

Оптимизаторы

09_optimizers.ipynb

Каждая библиотека там (я полагаю, за исключением Fastai) использует оптимизаторы как разные вещи. Это означает, что добавление нового требует много бесполезной работы. Джереми собирается показать, что должен быть только один оптимизатор, который затем можно немного изменить для вызова с разными именами.

Снижение веса было тем, что побудило параметры быть небольшими числами. Мы используем то, что называется регуляризацией L2, которая показана ниже ...

loss_with_wd = loss + (wd/2) * (weights**2).sum()

… Или вы также можете использовать эту другую форму, которая на самом деле называется снижением веса:

weight.grad += wd * weight

Теперь давайте добавим импульс. Нам нужно снова немного изменить класс оптимизатора, чтобы сохранить предыдущие значения параметров.

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

Далее мы рассмотрим несколько графиков с разными способами вычисления импульса.

Мы можем создать Адама, используя информацию, которую мы узнали.

LAMB - это новая статья, вышедшая недавно, и ее определенно стоит прочитать.

Https://arxiv.org/pdf/1904.00962.pdf

Бегун

09b_learner.ipynb

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

Индикаторы выполнения

09c_add_progress_bar.ipynb

Сильвен Гуггер создал библиотеку под названием fastprogress, которую мы собираемся использовать. Я не буду копировать сюда записную книжку, потому что там не было ничего интересного. Мы просто создаем обратный вызов с именем ProgressCallback, который затем используем и получаем хорошие индикаторы выполнения.

Увеличение данных

10_augmentation.ipynb

Существует множество различных техник изменения размера. PIL рекомендует использовать PIL.Image.ANTIALIAS, когда размер изображения будет уменьшен. Джереми подчеркнул, что важно проверить их и увидеть результаты. Иногда различные методы могут изменить данные таким образом, что исчезнет какая-то важная функция. Еще одна важная вещь, о которой упоминал Джереми, - это то, что увеличение данных может быть медленным. Он объяснил, как переворачивание байтов даст нам те же результаты, что и переключение числа с плавающей запятой, но намного быстрее.

RandomResizeCrop - это то, что использовал почти каждый победитель Kaggle (конкурса изображений). То же самое можно использовать и в других областях, например в тексте. Выбор случайного размера партии очень поможет при обучении. Джереми говорит, что искажение перспективы - лучшая версия этого.

Вопрос: Что будет, если объект исчезнет после увеличения? Это, безусловно, добавит шума в набор данных, но это не имеет значения. Мы изучили приемы, которые решают проблемы, вызываемые шумом.

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





Примечания к уроку 8
Примечания к уроку 9
Примечания к уроку 10
Примечания к уроку 11
Примечания к 12 уроку
Заметки к 13 уроку
Заметки к 14 уроку

~ Ланкинен