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

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

Интуиция

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

Оптимизация функции потерь аналогична достижению дна долины!

Чтобы визуализировать это, я наложил оси x, y и z = f(x, y) на наше изображение, чтобы обозначить некоторую функцию потерь f(x, y). Стрелка представляет собой цель, которую мы пытаемся достичь: дно долины, достигнутое в координате (x, y), что приводит к минимальному результату f(x, y).

Понимание векторов градиента

Логично предположить, что самый быстрый способ подняться или спуститься с горы — это следовать по склону самой горы.

В 2D скорость изменения некоторой величины (в данном случае высоты) в точке будет просто производной (или мгновенным наклоном) y по отношению к x в этой точке. Это будет скаляр.

В 3D вы двигаетесь двумя способами: вперед-назад (ось X на этом рисунке) ИЛИ из стороны в сторону (ось Y). Следование естественному склону горы требует, чтобы ваше движение имело как компоненты x, так и y, как векторы, нарисованные ниже.

В 3D скорость изменения высоты должна рассчитываться отдельно для каждого компонента x и y:

  • Сохраняя y постоянным, мы находим скорость изменения высоты только по x в точке через ∂f/∂x, частную производную по x
  • Удерживая x постоянным, мы находим скорость изменения высоты только по y в точке через ∂f/∂y, частную производную по y

В заключение, если бы вы двигались в направлении вектора градиента (∂f/∂x, ∂f/∂y), вы бы следовали за склоном горы и двигались бы в направлении наибольшего подъема или спуска в зависимости от на какой стороне долины вы были.

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

Обновить правило

Различие между (x, y) и z = f(x, y) здесь важно. Например, в верхнем левом углу изображения и координата x, и координата y меньше, чем (x, y), соответствующее минимуму. Нам нужно увеличить оба x, y, чтобы уменьшить z.

  • Обобщая, для данной точки (x, y) в правой части рисунка гора наклоняется вверх - скорость изменения f (x, y) положительна по отношению к z. Если бы мы добавили этот вектор градиента, который указывает от минимума, к нашему (x, y), мы бы увеличили z и ушли бы вверх от нашей цели.

  • Следующий случай может быть более запутанным, но если мы возьмем (x, y) слева, скорость изменения f(x, y) по отношению к z будет отрицательной. Этот вектор градиента указывает на минимум, но добавление отрицательного вектора к (x, y) аналогично добавлению положительного вектора в противоположном направлении. Это также увеличило бы z и означало бы движение вверх от нашей цели.

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

Что, если мы тогда поменяем направление и будем двигаться с отрицательным градиентом?

В левой части изображения отрицательные векторы градиента станут положительными и будут увеличиваться (x, y), приближаясь к низу. Справа положительные векторы градиента станут отрицательными и уменьшатся (x, y), также шагая вниз. Правило обновления градиентного спуска основано на этом понятии:

x = x - a * ∂f/∂x оценивается как (x, y)

y = y - a * ∂f/∂y оценивается в (x, y)

Эти уравнения просто говорят, что в данной инициализированной точке мы вычисляем скорость изменения f(x, y) только относительно x и только относительно y. Затем мы масштабируем эти частичные значения с помощью некоторой скорости обучения, обозначаемой альфа (подробнее об этом позже), и вычитаем из нашей текущей точки (x, y).

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

Важно отметить, что мы должны сначала вычислить оба частичных числа, а не вычислять ∂f/∂x и изменять x, а затем находить ∂f/∂y. В противном случае мы бы нашли скорость изменения компонента для 2 разных точек (по склону горы в 2 разных местах).

Вот и все! Мы рассмотрели все, что делает алгоритм 3D-градиентного спуска: он инициализирует точку (x, y, f(x,y)), вычисляет частичные значения, одновременно обновляет x и y для движения в направлении минимума и повторяет этот процесс до сходимости. Различные модели будут определять сходимость по-разному: некоторые просто выполняют 100 итераций, в то время как другие продолжают до тех пор, пока обновление координат не уменьшит f(x, y) менее чем на 0,001.

Конвергенция

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

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

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

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

Алгоритм также потенциально может сойтись слишком рано. Если градиент в точке мал, т.е. наклон постепенный, небольшое число, умноженное на небольшую альфу, может не сильно изменить координату и, соответственно, не изменить f (x, y) более чем на 0,001, что компьютер проверяет на сходимость.

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

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

Хороший алгоритм градиентного спуска плавно и эффективно достигает минимума, в идеале глобального минимума:

Заключение

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

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

Это похоже на наши примеры выше, за исключением того, что вместо некоторой функции f(x, y), принимающей в качестве входных данных физическую координату в долине, наша функция f(m, b) вычисляет сумму квадратов невязок из заданных параметров регрессии — ее наклон и пересечение.

Во Части II мы объединим все, что узнали, с кодом и попытаемся сами оптимизировать линейную регрессию!

Рекомендации

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