Документирование моего путешествия через fast.ai: ОБЗОР ТЕОРИИ. СКОРОСТЬ ОБУЧЕНИЯ И ФУНКЦИИ АКТИВАЦИИ.

Для проекта Урок 3.1 я решил рассмотреть некоторые из основных теорий, которые сделали возможными все замечательные приложения, которые мы смогли создать с помощью Fastai Library. Код доступен здесь.

1. Скорость обучения.

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

Сейчас мы сосредоточимся на скорости обучения. Помните, что:

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

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

А теперь обратите внимание на следующее. Если мы нанесем наши потери, используя библиотеку Fastai:

plot.recorder.plot_losses()

мы получим график, подобный этому:

Как мы видим, убыток сначала увеличивается, а затем снижается.

Причину этого можно найти, построив нашу скорость обучения, используя библиотеку Fastai:

learn.recorder.plot()

Сюжет, подобный этому, можно ожидать:

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

learn.fit_one_cycle(12, lrs)

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

К настоящему времени вы наверняка спросите: почему это так важно?

Ответ: формы функции потерь. Рассмотрим следующее: в большинстве случаев наши функции потерь выглядят не так:

Они не имеют форму идеальной параболы.

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

Как видите, у него есть глобальные и локальные, максимумы и минимумы. В нем есть долины и вершины. Одним словом, он более неровный, чем мы привыкли себе представлять.

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

Эта концепция снижения скорости обучения называется отжигом скорости обучения. Но прорыв в увеличении скорости во время старта является новым и был разработан Лесли Смит. Вы можете найти некоторые из его статей здесь: http://www.cs.stir.ac.uk/~lss/lsspapers.html.

2. Функции активации.

Мы должны помнить, что имеем дело с «глубокими нейронными сетями», которые содержат серию матричных умножений или сверток.

Эти свертки являются просто линейными функциями. Секрет заключается в том, что мы делаем после каждой свертки. Вот и все нелинейности. Точнее, после каждой свертки мы применяем функция активации.

Функция активации берет результат свертки и помещает его в такую ​​функцию, как «Выпрямленная линейная единица» или ReLU (для тех, кто в «команде»):

Например, ReLU сохраняет значения, которые равны или выше нуля, и заменяет отрицательные результаты нулями.

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

Теорема утверждает, что если мы объединим свертки (линейные функции) и функции активации (нелинейности), мы можем получить результат, который может сколь угодно точно аппроксимировать непрерывные функции, если матрица достаточно велика или если у нас достаточно эти матрицы.

Если функция не является непрерывной, мы можем добавить еще один слой, который будет имитировать вывод прерывистой функции.

3. Заключительные шаги.

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

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