Давайте обсудим как происходит обучение в машинном обучении.
Оптимизация - важная часть машинного обучения. В основе почти каждого алгоритма машинного обучения лежит алгоритм оптимизации.
Градиентный спуск - один из самых популярных и широко используемых алгоритмов оптимизации. Его цель - найти минимум функции с помощью итеративного алгоритма.
- Учитывая модель машинного обучения с параметрами (весами и смещениями) и функцией стоимости (или функцией потерь), чтобы оценить, насколько хороша конкретная модель, наша проблема обучения сводится к поиску хорошего набора весов / параметров для нашей модели, которая минимизирует функцию стоимости.
Изучение модели линейной регрессии означает оценку значений коэффициентов, используемых в представлении, с данными, которые у нас есть.
Теория. Для функции, определенной набором параметров, градиентный спуск начинается с начального набора значений параметров и итеративно перемещается к набору значения параметров, которые минимизируют функцию. Эта итеративная минимизация достигается с помощью исчисления, делающего шаги в отрицательном направлении функции градиент.
Об алгоритме в двух словах
На приведенном ниже рисунке показана общая трехмерная функция J. Здесь только два θ, чтобы построить понятный график.
Высота или вертикальная ось показывает J, то есть результат. Минимизация этой функции означает поиск самых низких значений J, которые соответствуют синим углубленным областям.
Что это значит ??
Предположим, что функция на картинке выше представляет собой пересеченную местность холмистого ландшафта, когда вы стоите на центральной горе. Ваша задача - как можно быстрее спуститься с горы маленькими шажками до тех пор, пока вы не сможете спуститься дальше.
- Вы начинаете оглядываться, спрашивая себя: в каком направлении мне идти, чтобы сделать небольшой шаг вниз по склону? Вы находите лучший вариант с учетом вашего текущего положения, делаете шаг и снова задаете себе тот же вопрос. Повторяйте процесс до тех пор, пока вы не сможете спускаться дальше, то есть пока не найдете минимум.
Неровная местность аналогична функции стоимости (или функции потерь). Минимизация функции затрат аналогична попытке спуститься с холма. Ощущение наклона местности вокруг вас аналогично вычислению градиента, а выполнение шага аналогично одной итерации обновления параметров.
На рисунке 2 ниже показан эксперимент с «маленькими шагами» с двумя разными маршрутами. Ваше исходное положение на холме соответствует начальным значениям, заданным для θ0, θ1. Черный маршрут имеет немного другую начальную точку по сравнению с белым, что раскрывает интересное свойство алгоритма градиентного спуска: изменение начального значения θ может привести к другому минимуму . Это говорит о том, что ваша функция может иметь разные минимумы. (Проверьте дальше: глобальные минимумы и локальные минимумы)
Градиентный спуск - это итерационный метод.
Определение алгоритма градиентного спуска
Полная формула градиентного спуска выглядит следующим образом:
Термин α представляет собой число, называемое скоростью обучения. Он в основном контролирует размер шага при спуске с холма. Чем больше α, тем больше шаги. Оставшаяся часть является производной функции J; Вскоре я углублюсь в это.
Короче говоря, градиентный спуск работает следующим образом: для каждого θ функции стоимости J вычислите значение θ путем вычитания из сама производная функции, умноженная на число α. Промыть и повторить до схождения. Позже мы увидим концепцию конвергенции. А пока подумайте об этом как о точке в вашем спуске, в которой вы еще не достигли оптимального результата, но на самом деле вы довольно близко, если не на нем.
Правильный способ реализации алгоритма градиентного спуска требует одновременного обновления θ.
Есть две тонкие вещи, которые отвечают за обучение:
- В каком направлении спускаться? Наклон кривой (или линии, если на то пошло) дает нам положительное значение, когда кривая увеличивается, и отрицательное значение, когда кривая уменьшается. Кроме того, обратите внимание, что в определенной точке, когда кривая увеличивается, обязательно будут минимумы слева от нее, и наоборот. Объединив эти два факта, мы получаем: «Когда наклон кривой положительный, двигайтесь влево, а когда наклон отрицательный, двигайтесь вправо, потому что именно там находятся минимумы»
- Сколько опускаться за один шаг? Это наша скорость обучения ⍺. Интуитивно, чтобы заставить алгоритм работать быстрее, мы могли бы выбрать как можно большее значение. Хотя эта логика кажется правильной, существует риск превышения минимума и, тем самым, замедления сходимости алгоритма или, что еще хуже, расхождения. Следовательно, шаг в одной итерации, на который спускается алгоритм градиентного спуска, - это скорость обучения.
Примечание. Скорость обучения ⍺ также называется гиперпараметром. Гиперпараметр - это параметр, значение которого устанавливается до начала процесса обучения. Напротив, значения других параметров получаются посредством обучения. Более того, не существует заранее определенного метода выбора правильного набора гиперпараметров для данной модели. Единственный способ установить гиперпараметр - пробовать.
Однако иногда можно встретить передовые практики гиперпараметров и начать процесс обучения, выбрав их. Вот почему процесс поиска гиперпараметров иногда называют настройкой гиперпараметров.
Как работает алгоритм градиентного спуска?
Давайте теперь попробуем понять, что делает каждая часть алгоритма градиентного спуска. Я собираюсь использовать более простой пример только с одним параметром θ: он очень поможет с визуализацией.
Вы также можете заметить черную точку на кривой: это начальное значение θ, установленное во время инициализации градиентного спуска. Это просто случайное значение. Функция градиентного спуска будет сдвигать эту точку до тех пор, пока не достигнет минимума, то есть основания параболы. Посмотрим как.
- Ключевой частью алгоритма является производная: она в основном вырабатывает наклон касательной к черной точке. Как только значение наклона известно, алгоритм добавляет или вычитает это значение, чтобы переместить точку ближе к минимуму.
На рисунке 3 выше наклон касательной линии положительный, поэтому ее производная будет положительной. Производная в точке - это просто число, назовем ее d, d≥0. Тогда обновление до θ будет:
θ :=θ − α ⋅ d
Мы вычитаем положительное число из θ, что делает его меньше. Точка сместится влево, как вы можете видеть на крайнем правом графике на рисунке 3.
→ → Процесс продолжается до тех пор, пока алгоритм не достигнет минимума. Но что это значит? Минимум, а именно основание параболы, - это точка, в которой касательная имеет наклон ноль: идеально горизонтальная линия.
Производная такой горизонтальной линии равна 0 (назовем ее d, d = 0), поэтому алгоритм в конечном итоге ничего не добавит к θ, например:
θ := θ − α ⋅ d
то есть
θ := θ − 0
В этот момент θ больше не смещается: минимум достигнут.
Подводные камни "α", скорости обучения
Параметр α (скорость обучения) определяет, насколько большим будет шаг во время градиентного спуска.
- Это число, которое умножает производную при обновлении θ. Чем выше скорость обучения, тем быстрее алгоритм спустится до точки минимума.
Определение хорошего значения для α требует некоторого планирования. Если он слишком мал, алгоритму потребуется много крошечных маленьких шагов, чтобы добраться до минимума, как показано на рисунке ниже, слева. Таким образом, градиентный спуск может быть медленным.
Если α слишком велико, алгоритм может пропустить точку минимума, а именно он не сможет сходиться, как показано на рисунке ниже, справа. Хуже того, он может расходиться, то есть все дальше и дальше от минимума, занимая бесконечное количество времени.
Хорошая новость заключается в том, что как только вы найдете подходящее значение скорости обучения, алгоритм постепенно достигнет минимума. По мере того, как θ скользит к минимуму, наклон касательной линии становится все меньше, пока не достигнет 0. Таким образом, нет необходимости настраивать α, которое может оставаться фиксированным для весь процесс.
Конвергенция
Что мы подразумеваем под конвергенцией? Проще говоря, это случай, когда нет смысла обновлять параметры с помощью градиентного спуска, потому что функция стоимости остается постоянной в течение довольно долгого времени.
Практически можно построить график изменения функции стоимости на каждой итерации вышеупомянутого цикла, и, если реализация верна, вы увидите кривую, более или менее похожую на эту:
Очевидно, мы видим, что после 4000 итераций функция стоимости стагнирует. Так мы определяем конвергенцию.
Резюме
Как применить алгоритм градиентного спуска:
- Определите свою функцию затрат.
- Выберите случайные начальные значения для параметров, θ
- Найдите производную функции затрат J.
- Выбор подходящей скорости обучения α.
- Обновляйте свои параметры, пока не сойдетесь. Именно здесь вы нашли оптимальные значения θ, при которых функция затрат J минимальна.
Типы алгоритмов градиентного спуска
- Пакетный градиентный спуск
В обычном алгоритме градиентного спуска, чтобы вычислить градиент функции стоимости, нам нужно просуммировать (желтый кружок!) стоимость каждого образца. Если у нас есть 3 миллиона выборок, мы должны пройти 3 миллиона раз или использовать скалярное произведение.
Вот код Python:
def gradientDescent(X, y, theta, alpha, num_iters): """ Performs gradient descent to learn theta """ m = y.size # number of training examples for i in range(num_iters): y_hat = np.dot(X, theta) theta = theta - alpha * (1.0/m) * np.dot(X.T, y_hat-y) return theta
Вы видите np.dot(X.T, y_hat-y)
выше? Это векторизованная версия «перебора (суммирования) 3 миллионов выборок».
Подождите ... просто чтобы приблизиться к минимуму на один шаг, неужели нам действительно нужно рассчитывать каждую стоимость 3 миллиона раз?
Но если вы используете Stochastic GD, в этом нет необходимости!
- Стохастический градиентный спуск (SGD)
По сути, в SGD мы используем градиент стоимости 1 пример на каждой итерации вместо использования суммы градиента стоимости ВСЕ Примеры.
def SGD(f, theta0, alpha, num_iters): """ Arguments: f -- the function to optimize, it takes a single argument and yield two outputs, a cost and the gradient with respect to the arguments theta0 -- the initial point to start SGD from num_iters -- total iterations to run SGD for Return: theta -- the parameter value after SGD finishes """ start_iter = 0 theta= theta0 for iter in xrange(start_iter + 1, num_iters + 1): _, grad = f(theta) theta = theta - (alpha * grad) # there is NO dot product! return theta
- Мини-пакетный градиентный спуск
Несколько замечаний:
а) В SGD перед циклом for вам необходимо случайным образом перемешать обучающие примеры.
б) В SGD, поскольку он использует только один пример за раз, его путь к минимумам более шумный (более случайный), чем путь градиента партии. Но это нормально, поскольку мы безразличны к пути, пока он дает нам минимум И меньше времени на обучение.
c) Мини-пакетный градиентный спуск использует n точек данных (вместо 1 выборки в SGD) на каждой итерации.