Градиентные спуски: batch и stochastic gradient descents. Из всех методов локальной оптимизации является наиболее простым в реализации. Имеет довольно слабые условия сходимости, но при этом скорость сходимости достаточно мала

где f i – функция, подсчитанная на i-м батче, i выбирается случайным образом;

Шаг обучения является гиперпараметром; при слишком больших значениях алгоритм обучения будет расходиться, при слишком маленьких – будет сходиться медленно.

Стохастический градиентный спуск с инерцией

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

(14)
(15)

Как несложно догадаться, гиперпараметр инерции μ имеет такое название из-за того, что, подобно так называемой ньютоновой силе инерции, т.е. силе противодействия, «сопротивляется» изменениям градиента и смягчает изменения весовых коэффициентов на протяжении обучения. Такой алгоритм обучения называется стохастическим градиентным спуском с инерцией или SGDМ (stochastic gradient descent with momentum).

Метод адаптивного градиента

Метод адаптивного градиента (Adagrad – от англ. «adaptive gradient algorithm») основан на идее масштабирования. Он перемасштабирует скорость обучения для каждого настраиваемого параметра в отдельности, при этом учитывая историю всех прошлых градиентов для этого параметра. Для этого каждый элемент градиента делится на квадратный корень от суммы квадратов предыдущих соответствующих элементов градиента. Такой подход эффективно уменьшает скорость обучения для тех весовых коэффициентов, которые имеют большое значение градиента, а также со временем снижает скорость обучения для всех параметров, так как сумма квадратов неуклонно увеличивается для всех параметров при каждой итерации. При задании нулевого начального масштабирующего параметра g = 0 формула для пересчета весовых коэффициентов имеет вид (деление выполняется поэлементно).

SVM

Метод опорных векторов (англ. SVM, support vector machine) -- набор схожих алгоритмов обучения с учителем, использующихся для задач классификации и регрессионного анализа. Принадлежит к семейству линейных классификаторов, может также рассматриваться как специальный случай регуляризации по Тихонову. Особым свойством метода опорных векторов является непрерывное уменьшение эмпирической ошибки классификации и увеличение зазора, поэтому метод также известен как метод классификатора с максимальным зазором.

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

Часто в алгоритмах машинного обучения возникает необходимость классифицировать данные. Каждый объект данных представлен как вектор (точка) в -мерном пространстве (последовательность p чисел). Каждая из этих точек принадлежит только одному из двух классов. Нас интересует, можем ли мы разделить точки гиперплоскостью размерностью Это типичный случай линейной разделимости. Таких гиперплоскостей может быть много. Поэтому вполне естественно полагать, что максимизация зазора между классами способствует более уверенной классификации. То есть можем ли мы найти такую гиперплоскость, чтобы расстояние от неё до ближайшей точки было максимальным. Это бы означало, что расстояние между двумя ближайшими точками, лежащими по разные стороны гиперплоскости, максимально. Если такая гиперплоскость существует, то она нас будет интересовать больше всего; она называется оптимальной разделяющей гиперплоскостью, а соответствующий ей линейный классификатор называется оптимально разделяющим классификатором.

Формально можно описать задачу следующим образом.

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

Вектор -- перпендикуляр к разделяющей гиперплоскости. Параметр равен по модулю расстоянию от гиперплоскости до начала координат. Если параметр равен нулю, гиперплоскость проходит через начало координат, что ограничивает решение.

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

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

Это может быть также записано в виде:

В случае линейной разделимости классов, проблема построения оптимальной разделяющей гиперплоскости сводится к минимизации при условии (1). Это задача квадратичной оптимизации, которая имеет вид:

По теореме Куна -- Таккера эта задача эквивалентна двойственной задаче поиска седловой точки функции Лагранжа.


Где -- вектор двойственных переменных

Сведем эту задачу к эквивалентной задаче квадратичного программирования, содержащую только двойственные переменные:


Допустим мы решили данную задачу, тогда и можно найти по формулам:

В итоге алгоритм классификации может быть записан в виде:

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

В случае линейной неразделимости классов, для того, чтобы алгоритм мог работать, позволим ему допускать ошибки на обучающей выборке. Введем набор дополнительных переменных, характеризующих величину ошибки на объектах. Возьмем за отправную точку (2), смягчим ограничения неравенства, так же введём в минимизируемый функционал штраф за суммарную ошибку:

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

Аналогично, по теореме Куна-Таккера сводим задачу к поиску седловой точки функции Лагранжа:


По аналогии сведем эту задачу к эквивалентной:


На практике для построения машины опорных векторов решают именно эту задачу, а не (3), так как гарантировать линейную разделимость точек на два класса в общем случае не представляется возможным. Этот вариант алгоритма называют алгоритмом с мягким зазором (soft-margin SVM), тогда как в линейно разделимом случае говорят о жёстком зазоре (hard-margin SVM).

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

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

Если есть основания полагать, что выборка почти линейно разделима, и лишь объекты-выбросы классифицируются неверно, то можно применить фильтрацию выбросов. Сначала задача решается при некотором C, и из выборки удаляется небольшая доля объектов, имеющих наибольшую величину ошибки. После этого задача решается заново по усечённой выборке. Возможно, придётся проделать несколько таких итераций, пока оставшиеся объекты не окажутся линейно разделимыми.

Алгоритм построения оптимальной разделяющей гиперплоскости, предложенный в 1963 году Владимиром Вапником и Алексеем Червоненкисом -- алгоритм линейной классификации. Однако в 1992 году Бернхард Босер, Изабелл Гийон и Вапник предложили способ создания нелинейного классификатора, в основе которого лежит переход от скалярных произведений к произвольным ядрам, так называемый kernel trick (предложенный впервые М.А. Айзерманом, Э.М. Браверманном и Л.В. Розоноэром для метода потенциальных функций), позволяющий строить нелинейные разделители. Результирующий алгоритм крайне похож на алгоритм линейной классификации, с той лишь разницей, что каждое скалярное произведение в приведённых выше формулах заменяется нелинейной функцией ядра (скалярным произведением в пространстве с большей размерностью). В этом пространстве уже может существовать оптимальная разделяющая гиперплоскость. Так как размерность получаемого пространства может быть больше размерности исходного, то преобразование, сопоставляющее скалярные произведения, будет нелинейным, а значит функция, соответствующая в исходном пространстве оптимальной разделяющей гиперплоскости, будет также нелинейной.

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

Наиболее распространённые ядра:

1. Линейное ядро:

2. Полиномиальное (однородное):

3. RBF функция:

4. Сигмоид:

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

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

Стохастический Градиентный Спуск

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

Найдём алгоритм, аппроксимирующий зависимость. В случае линейного классификатора искомый алгоритм имеет вид:

где играет роль функции активации (в простейшем случае можно положить).

Согласно принципу минимизации эмпирического риска для этого достаточно решить оптимизационную задачу:

Где - заданная функция потерь.

Для минимизации применим метод градиентного спуска (gradient descent). Это пошаговый алгоритм, на каждой итерации которого вектор изменяется в направлении наибольшего убывания функционала (то есть в направлении антиградиента):

Где - положительный параметр, называемый темпом обучения (learning rate).

Возможны 2 основных подхода к реализации градиентного спуска:

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

2. Стохастический (stochastic/online), когда на каждой итерации алгоритма из обучающей выборки каким-то (случайным) образом выбирается только один объект. Таким образом вектор настраивается на каждый вновь выбираемый объект.

Можно представить алгоритм стохастического градиентного спуска в виде псевдокода следующим образом:

· - обучающая выборка

· - темп обучения

· - параметр сглаживания функционала

1. Вектор весов

1) Инициализировать веса

2) Инициализировать текущую оценку функционала:

3) Повторять:

1. Выбрать объект из случайным образом

2. Вычислить выходное значение алгоритма и ошибку:

3. Сделать шаг градиентного спуска

4. Оценить значение функционала:

4) Пока значение не стабилизируется и/или веса не перестанут изменяться.

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

Выводы

В рамках решаемой задачи нам потребуется воспользоваться алгоритмом преобразования исходных данных TF-IDF, который позволит нам повысить весомость редких событий и снизить вес частых событий. Полученные после преобразования данные мы будем передавать классификаторам, которые подходят для решения стоящей перед нами задачи, а именно: Наивный Байесовский Классификатор или Машина Опорных Векторов с Линейным ядром, обученная по методу стохастического градиентного спуска. Также мы осуществим проверку эффективности Машины Опорных Векторов с нелинейными ядрами, обученной по методу пакетного градиентного спуска. Однако, данный тип классификатора не кажется подходящим для поставленной задачи в силу слишком сложного ядра и склонности к переобучаемости, при которой классификатор плохо справляется с данными, которые не использовались для обучения классификатора.

программный машинный предобработка данный

Стохастический градиент оценивается по формуле :

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

Если в качестве взять орты, т. то эта оценка при как легко заметить из (3.3.22), дает точное значение градиента.

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

Градиентный поиск (3.3.21) является частным случаем по крайней мере двух алгоритмов случайного поиска. Первый алгоритм:

где - по-прежнему единичный случайный -мерный вектор. Это известный градиентный алгоритм случайного поиска . Второй алгоритм имеет вид (3.3.23), но оценка градиента вычисляется по формуле

При как легко заметить, оба алгоритма вырождаются, в градиентный алгоритм поиска (3.3.21).

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

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

Так, алгоритм случайного поиска с линейной тактикой (3.3.12) является стохастической моделью алгоритма наискорейшего спуска:

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

оператор случайного шага заменяет громоздкий оператор оценки градиента, например, по формуле (3.3.22).

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

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

Алгоритмическая простота случайного поиска делает его привлекательным в первую очередь для потребителей . Опыт показывает, что известные алгоритмы случайного поиска являются лишь «канвой», на которой пользователь в каждом конкретном случае «вышивает узоры» новых алгоритмов, отражающих не только его вкусы и наклонности (что нельзя не учитывать), но и специфику оптимизируемого объекта. Последнее создает благоприятную основу для реализации известного принципа, что алгоритм должен конструироваться «под объект». Наконец, алгоритмическая простота случайного поиска обусловливает простоту его аппаратурной реализации. Это не только дает возможность строить простые, компактные и надежные оптимизаторы с неограниченным числом оптимизируемых параметров , но и позволяет довольно просто организовать их оптимальный синтез на ЭВМ .

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Размещено на http://www.allbest.ru/

Министерство образования и науки РФ

Федеральное государственное автономное образовательное учреждение

Высшего образования

«КАЗАНСКИЙ (ПРИВОЛЖСКИЙ) ФЕДЕРАЛЬНЫЙ УНИВЕРСИТЕТ»

ВЫСШАЯ ШКОЛА ИНФОРМАЦИОННЫХ ТЕХНОЛОГИЙ И ИНФОРМАЦИОННЫХ СИСТЕМ

КУРСОВАЯ РАБОТА

Стохастический градиентный спуск. Варианты реализации

Введение

Градиентный спуск -- метод нахождения локального экстремума (минимума или максимума) функции с помощью движения вдоль градиента.

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

Градиентный спуск является популярным алгоритмом для широкого спектра моделей машинного обучения, в том числе нахождение опорных векторов, логистической регрессии и графических моделей. В сочетании с алгоритмом обратного распространения, это стандартный алгоритм для обучения искусственных нейронных сетей. Стохастический градиентный спуск конкурирует с алгоритмом L-BFGS, который также широко используется. Стохастический градиентный спуск был использован, по крайней мере, в 1960 для обучения линейных регрессионных моделей, первоначально под названием Adaline.

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

1. Стохастический градиентный спуск

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

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

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

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

1.1 Предпосылки

Статистические оценки и машинное обучение рассматривают задачу минимизации функции, которая имеет вид:

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

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

Проблема минимизации сумм возникает также в минимизации эмпирического риска. В этом случае,это значение функции потерь при i-омнаборе, и эмпирический риск.

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

где это размер шага (иногда называемый скоростью обучения в машинном обучении).

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

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

1.2 Итерационный метод

В стохастическом градиентном спуске, истинный градиент приближенно выражается градиентом на данном примере:

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

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

1) Выбрать исходный вектор параметра и скорость обучения.

2) Повторять до тех пор, пока не будетприблизительно получено минимальное:

2.1) Случайно перетасовать примеры в обучающем наборе.

2.2) Для i = 1,2,...,n, делать:

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

1.3 Варианты реализации

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

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

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

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

В рамках данной работы будут рассмотрены следующие варианты реализации стохастического градиентного спуска:

1. 4 Momentum

Momentum, так же известный как метод импульса, появился благодаря американскому психологу Дэвиду Рамелхарту, а также на основе работ Джеффри Хинтонаи Роналда J Уильям саприизучении метода обратного распространения. Стохастический градиентный спуск с импульсом запоминает обновления на каждой итерации, и определяет следующее обновление в виде линейной комбинации градиента и предыдущего обновления:

Что приводит к:

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

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

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

1.5 AdaGrad

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

Примеры таких применений включают обработку естественного языка и распознавание образов.

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

где градиент при итерации m.

Диагональ задается в виде:

Вектор обновляется после каждой итерации. Формула для обновления теперь выглядит так:

или записывается в виде обновления предварительного параметра,

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

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

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

1.6 RMSProp

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

где это параметр экспоненциального взвешивания, или параметр «забывания» («forgetting factor»)

Параметры обновляются с помощью формулы ниже:

RMSProp показал отличную адаптацию скорости обучения в различных приложениях. RMSProp можно рассматривать как обобщение Rprop и так же он способен работать с таким вариантом градиентного спуска как mini-batch, который противопоставлен обычному градиентному спуску.

2. Реализация стохастического градиентного спуска

На данном этапе будут выполнены реализации нескольких вариантов стохастического градиентного в виде программного кода на языке программирования Python.

2.1 Реализация стандартного стохастического градиентного спуска

Во-первых, нужен набор данных. В данном случае создаетсянабор данных с помощью библиотеки Scikit-Learn:

градиент стохастический алгоритм обучение

from sklearn.datasets import make_moons

from sklearn.cross_validation import train_test_split

X, y = make_moons(n_samples=5000, random_state=42, noise=0.1)

X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)

Вот что мы получили:

Рисунок 1 - Графическое представление набора данных

Далее, определяется модель нейронной сети. Это будет три слоя сети (один скрытый слой):

import numpy as np

def make_network(n_hidden=100):

model = dict(W1=np.random.randn(n_feature, n_hidden),

W2=np.random.randn(n_hidden, n_class)

Также определяется две операции: прямое распространение и обратное распространение. Сначала сделаем первый вариант:

return np.exp(x) / np.exp(x).sum()

def forward(x, model):

h = x @ model["W1"]

prob = softmax(h @ model["W2"])

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

ReLU определяется как f(x)=max(0,x), но, вместо того, чтобы делать np.max(0, x), есть ловкий трюк реализации: x = 0.

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

Теперь определяется вторая операция. Обратное распространение выглядит следующим образом:

def backward(model, xs, hs, errs):

dW2 = hs.T @ errs

dh = errs @ model["W2"].T

dh = 0

return dict(W1=dW1, W2=dW2)

Создаётся основа алгоритма. Выполняется реализация функцииsgd. Выглядит она так:

def sgd(model, X_train, y_train, batch_size):

for iter in range(n_iter):

print("Iteration {}".format(iter))

X_train, y_train = shuffle(X_train, y_train)

for i in range(0, X_train.shape, batch_size):

X_train_mini = X_train

y_train_mini = y_train

model = sgd_step(model, X_train_mini, y_train_mini)

return model

Выполняется реализация функции sgd_step. Выглядит она так:

def sgd_step(model, X_train, y_train):

grad = get_batch_grad(model, X_train, y_train)

model = model.copy()

for layer in grad:

model += learning_rate * grad

Выполняется реализация функции get_batch_grad. Выглядит она так:

def get_batch_grad(model, X_train, y_train):

xs, hs, errs = , ,

for x, cls_idx in zip(X_train, y_train):

h, y_pred = forward(x, model)

y_true = np.zeros(n_class)

y_true = 1.

err = y_true - y_pred

errs.append(err)

return backward(model, np.array(xs), np.array(hs), np.array(errs))

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

2.2 Реализация Momentum

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

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

def momentum(model, X_train, y_train, batch_size):

velocity = {k: np.zeros_like(v) for k, v in model.items()}

gamma =.9

X_mini, y_mini = batches

for layer in grad:

velocity = gamma * velocity + alpha * grad

model += velocity

Включается новая переменная velocity, которая будет накапливать импульс для каждого параметра. Обновление переменной будет происходить слагаемым alpha*grad на каждом новом шаге градиентного спуска. Так же происходит небольшое уменьшение с помощью коэффициента gamma значения переменной velocity, которая была вычислена на предыдущем шаге.

2.3 Реализация AdaGrad

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

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

Выполняется реализация данного метода. Вся программа готова, нужно лишь изменить основную функцию. Называться она будетadagrad. Функция представлена ниже:

def adagrad(model, X_train, y_train, batch_size):

batches = get_batch(X_train, y_train, batch_size)

for iter in range(1, n_iter + 1):

idx = np.random.randint(0, len(batches))

X_mini, y_mini = batches

grad = get_batch_grad(model, X_mini, y_mini)

cache[k] += grad[k]**2

return model

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

2.4 Реализация RMSProp

Можно заметить, что в накопительной части Adagrad, значение cache[k] += grad[k]**2 монотонно возрастает в следствие суммы и квадрата. Это может быть проблематичным, так как скорость обучения будет монотонно убывать к очень крошечной скорости обучения.

Для борьбы с этой проблемой, RMSProp раскладывает прошлое накопленное значение градиента, так чтобы рассматривалась только часть последних градиентов. Теперь, вместо того, чтобы рассматривать все последние градиенты, RMSProp ведет себя как скользящая средняя.

Выполняется реализация данного метода. Вся программа готова, нужно лишь изменить основную функцию. Называться она будетrmsprop. Функция представлена ниже:

def rmsprop(model, X_train, y_train, batch_size):

cache = {k: np.zeros_like(v) for k, v in model.items()}

gamma =.9

batches = get_batch(X_train, y_train, batch_size)

for iter in range(1, n_iter + 1):

idx = np.random.randint(0, len(batches))

X_mini, y_mini = batches

grad = get_batch_grad(model, X_mini, y_mini)

cache[k] = gamma * cache[k] + (1 - gamma) * (grad[k]**2)

model[k] += alpha * grad[k] / (np.sqrt(cache[k]) + eps)

Основное отличие в вычислении значения cache[k] и теперь накопленное значение градиента не будет агрессивно монотонно возрастать.

3. Тестирование и сравнение

В данной главе будет проводиться тестирование реализации и анализ полученных результатов.

3.1 Тестирование стандартного стохастического градиентного спуска

На данном этапе будет проводиться тестирование стандартного стохастического градиентного спуска. Процедура будет выполняться 100 раз и затем будет вычислено среднее значение точности.

n_experiment = 100

accs = np.zeros(n_experiment)

for k in range(n_experiment):

model = make_network()

model = sgd(model, X_train, y_train, minibatch_size)

prob = forward(x, model)

y = np.argmax(prob)

Выполнив данный код, я получил следующие значения:

Средняя точность: 0.8765040000000001

Таким образом, можно сделать вывод, что в среднем точность выполнения 87%.

3.2 Тестирование Momentum

На данном этапе будет проводиться тестирование стохастического градиентного спуска на основе реализации Momentum. Процедура будет выполняться 100 раз и затем будет вычислено среднее значение точности.

Программа для тестирования приведена ниже:

n_experiment = 100

accs = np.zeros(n_experiment)

for k in range(n_experiment):

model = make_network()

model = momentum(model, X_train, y_train, minibatch_size)

y_pred = np.zeros_like(y_test)

for i, x in enumerate(X_test):

prob = forward(x, model)

y = np.argmax(prob)

accs[k] = (y_pred == y_test).sum() / y_test.size

print("Средняя точность: {}, Полученное значение: {}".format(accs.mean(), accs.std()))

Средняя точность:

1) 0.3152, при alpha = 0.5

2) 0.8554666666666666, при alpha = 1e-2

3) 0.8613333333333334, при alpha = 1e-5

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

3.3 Тестирование AdaGrad

На данном этапе будет проводиться тестирование стохастического градиентного спуска на основе реализации AdaGrad. Процедура будет выполняться 100 раз и затем будет вычислено среднее значение точности.

Программа для тестирования приведена ниже:

n_experiment = 100

accs = np.zeros(n_experiment)

for k in range(n_experiment):

model = make_network()

model = adagrad(model, X_train, y_train, minibatch_size)

y_pred = np.zeros_like(y_test)

for i, x in enumerate(X_test):

prob = forward(x, model)

y = np.argmax(prob)

accs[k] = (y_pred == y_test).sum() / y_test.size

print("Средняя точность: {}, Полученное значение: {}".format(accs.mean(), accs.std()))

Выполнив данный код, получены следующие значения:

Средняя точность:

1) 0.8754666666666667, при alpha = 0.5

2) 0.8786666666666667, при alpha = 1e-2

3) 0.504, при alpha = 1e-5

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

3.4 Тестирование RMSProp

На данном этапе будет проводиться тестирование стохастического градиентного спуска на основе реализации RMSProp. Процедура будет выполняться 100 раз и затем будет вычислено среднее значение точности.

Программа для тестирования приведена ниже:

n_experiment = 100

accs = np.zeros(n_experiment)

for k in range(n_experiment):

model = make_network()

model = rmsprop(model, X_train, y_train, minibatch_size)

y_pred = np.zeros_like(y_test)

for i, x in enumerate(X_test):

prob = forward(x, model)

y = np.argmax(prob)

accs[k] = (y_pred == y_test).sum() / y_test.size

print("Средняя точность: {}, Полученное значение: {}".format(accs.mean(), accs.std()))

Выполнив данный код, получены следующие значения:

Средняя точность:

1) 0.8506666666666667, при alpha = 0.5

2) 0.8727999999999999, при alpha = 1e-2

3) 0.30693333333333334, при alpha = 1e-5

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

Заключение

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

Однако при использовании небольшого значения скорости обучения происходит обратное, например, 1e-5. Для стандартного варианта стохастического градиентного спуска и метода импульса достаточно малые значения позволяют им хорошо работать. С другой стороны, если скорость обучения очень мала, и происходит ее нормализация в адаптивных методах скорости обучения, то она становится еще меньше, что влияет на скорость сходимости. Это делает обучение очень медленным, и данные методы работают хуже, чем стандартный стохастический градиентный спуск с тем же числом итераций.

Список использованных источников

1. Machinelearning - Стохастический градиентный спуск

2. Искусственный интеллект по-русски - Градиентные спуски

3. Вики учебник - Реализации алгоритмов/Градиентный спуск

4. Stanford University - Adaptive Subgradient Methods

5. Cambridge University Press - Online Algorithms and Stochastic Approximations

6. Sanjoy Dasgupta and David Mcallester - On the importance of initialization and momentum in deep learning [Электронный ресурс].

Размещено на Allbest.ru

...

Подобные документы

    Необходимые условия экстремума. Разработка машинного алгоритма и программы многомерной оптимизации для градиентного метода с использованием метода равномерного поиска. Проверка необходимых и достаточных условий экстремума для найденной точки минимума.

    курсовая работа , добавлен 25.09.2013

    Программная реализация приложения для вычисления заданных функций. Процедура поиска минимума функции. Применение методов Хука-Дживса и градиентного спуска для решения задачи. Исследование функции в окрестности базисной точки, определение ее координат.

    контрольная работа , добавлен 02.02.2014

    Оптимизация решения задачи с помощью алгоритма отжига. Анализ теории оптимизации как целевой функции. Метод градиентного спуска. Переменные и описание алгоритма отжига. Представление задачи коммивояжера через граф. Сведение задачи к переменным и решение.

    курсовая работа , добавлен 21.05.2015

    Обучение простейшей и многослойной искусственной нейронной сети. Метод обучения перцептрона по принципу градиентного спуска по поверхности ошибки. Реализация в программном продукте NeuroPro 0.25. Использование алгоритма обратного распространения ошибки.

    курсовая работа , добавлен 05.05.2015

    Решение задачи на тему максимизации функций многих переменных. Описание метода дихотомии, его применение для решения нелинейных уравнений. Решение данной задачи с использованием метода покоординатного спуска. Составление алгоритмов, листинг программы.

    курсовая работа , добавлен 01.10.2009

    Идентификация объектов методом наименьших квадратов. Анализ коэффициентов парной, частной и множественной корреляции. Построение линейной модели и модели с распределенными параметрами. Итерационный численный метод нахождения корня (нуля) заданной функции.

    курсовая работа , добавлен 20.03.2014

    Основа технологии использования программного комплекса LabVIEW, достоинства системы. Программирование, основанное на архитектуре потоков данных. Методы нахождения экстремума. Использование метода Гаусса-Зейделя для поиска максимума двумерной функции.

    контрольная работа , добавлен 18.03.2011

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

    лекция , добавлен 04.03.2009

    Постановка задачи и ее формализация. Поиск значений интерполяционного многочлена в точках x1 и x2. Поиск минимума функции F(x) на отрезке . Проверка условий сходимости методов. Тестирование программных модулей. Детализированная схема алгоритма.

    курсовая работа , добавлен 04.02.2011

    Численные методы в задачах без ограничений. Схема методов спуска. Среда редактора Visual Basic. Использование объектов ActiveX в формах. Блок-схема алгоритма моделирования. Задачи оптимизирования детерменированных функций с единственной точкой экстремума.

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

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

  • Смысл ГС — объяснение всего алгоритма;
  • Различные вариации алгоритма;
  • Реализация кода: написание кода на языке Phyton.

Что такое градиентный спуск

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

Итак, градиентный спуск нужен для минимизации функции потерь.

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


Поиск минимума функции

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

На рисунке мы видим график функции потерь (названный «Ошибка» с символом «J») с одним весом. Теперь, если мы вычислим наклон (обозначим это dJ/dw) функции потерь относительно одного веса, то получим направление, в котором нужно двигаться, чтобы достичь локальных минимумов. Давайте пока представим, что наша модель имеет только один вес.

Функция потерь

Важно: когда мы перебираем все учебные данные, мы продолжаем добавлять значения dJ/dw для каждого веса. Так как потери зависят от примера обучения, dJ/dw также продолжает меняться. Затем делим собранные значения на количество примеров обучения для получения среднего. Потом мы используем это среднее значение (каждого веса) для настройки каждого веса.

Также обратите внимание: Функция потерь предназначена для отслеживания ошибки с каждым примером обучениям, в то время как производная функции относительного одного веса – это то, куда нужно сместить вес, чтобы минимизировать ее для этого примера обучения. Вы можете создавать модели даже без применения функции потерь. Но вам придется использовать производную относительно каждого веса (dJ/dw).

Теперь, когда мы определили направление, в котором нужно подтолкнуть вес, нам нужно понять, как это сделать. Тут мы используем коэффициент скорости обучения, его называют гипер-параметром. Гипер-параметр – значение, требуемое вашей моделью, о котором мы действительно имеем очень смутное представление. Обычно эти значения могут быть изучены методом проб и ошибок. Здесь не так: одно подходит для всех гипер-параметров. Коэффициент скорости обучения можно рассматривать как «шаг в правильном направлении», где направление происходит от dJ/dw.

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

Подробнее о градиентах

Кроме функции потерь градиентный спуск также требует градиент, который является dJ/dw (производная функции потерь относительно одного веса, выполненная для всех весов). dJ/dw зависит от вашего выбора функции потерь. Наиболее распространена функция потерь среднеквадратичной ошибки.

Производная этой функции относительно любого веса (эта формула показывает вычисление градиента для ):

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

Коэффициент скорости обучения

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

Однако проблема у большинства моделей возникает с коэффициентом скорости обучения. Давайте взглянем на обновленное выражение для каждого веса (j лежит в диапазоне от 0 до количества весов, а Theta-j это j-й вес в векторе весов, k лежит в диапазоне от 0 до количества смещений, где B-k — это k-е смещение в векторе смещений). Здесь alpha – коэффициент скорости обучения. Из этого можно сказать, что мы вычисляем dJ/dTheta-j (градиент веса Theta-j), и затем шаг размера alpha в этом направлении. Следовательно, мы спускаемся по градиенту. Чтобы обновить смещение, замените Theta-j на B-k.

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

Использование градиентного спуска

Что ж, вот и всё. Это всё, что нужно знать про градиентный спуск. Давайте подытожим всё в псевдокоде.

Примечание: Весы здесь представлены в векторах. В более крупных моделях они, наверное, будут матрицами.

От i = 0 до «количество примеров обучения»

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

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

3. Подобно ситуации с весами, добавьте градиент смещения к аккумулятивной переменной.

Теперь, ПОСЛЕ перебирания всех примеров обучения, выполните следующие действия:

1. Поделите аккумулятивные переменные весов и смещения на количество примеров обучения. Это даст нам средние градиенты для всех весов и средний градиент для смещения. Будем называть их обновленными аккумуляторами (ОА).

2. Затем, используя приведенную ниже формулу, обновите все веса и смещение. Вместо dJ / dTheta-j вы будете подставлять ОА (обновленный аккумулятор) для весов и ОА для смещения. Проделайте то же самое для смещения.

Это была только одна итерация градиентного спуска.

Повторите этот процесс от начала до конца для некоторого количества итераций. Это означает, что для 1-й итерации ГС вы перебираете все примеры обучения, вычисляете градиенты, потом обновляете веса и смещения. Затем вы проделываете это для некоторого количества итераций ГС.

Различные типы градиентного спуска

Существует 3 варианта градиентного спуска:

1. Мini-batch : тут вместо перебирания всех примеров обучения и с каждой итерацией, выполняющей вычисления только на одном примере обучения, мы обрабатываем n учебных примеров сразу. Этот выбор хорош для очень больших наборов данных.

2. Стохастический градиентный спуск : в этом случае вместо использования и зацикливания на каждом примере обучения, мы ПРОСТО ИСПОЛЬЗУЕМ ОДИН РАЗ. Есть несколько вещей замечаний:

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

3. Серия ГС : это то, о чем написано в предыдущих разделах. Цикл на каждом примере обучения.


Картинка, сравнивающая 3 попадания в локальные минимумы

Пример кода на python

Применимо к cерии ГС, так будет выглядеть блок учебного кода на Python.

Def train(X, y, W, B, alpha, max_iters): """ Performs GD on all training examples, X: Training data set, y: Labels for training data, W: Weights vector, B: Bias variable, alpha: The learning rate, max_iters: Maximum GD iterations. """ dW = 0 # Weights gradient accumulator dB = 0 # Bias gradient accumulator m = X.shape # No. of training examples for i in range(max_iters): dW = 0 # Reseting the accumulators dB = 0 for j in range(m): # 1. Iterate over all examples, # 2. Compute gradients of the weights and biases in w_grad and b_grad, # 3. Update dW by adding w_grad and dB by adding b_grad, W = W - alpha * (dW / m) # Update the weights B = B - alpha * (dB / m) # Update the bias return W, B # Return the updated weights and bias.

Вот и всё. Теперь вы должны хорошо понимать, что такое метод градиентного спуска.