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

Прежде чем погрузиться в подробности, я хотел бы рассмотреть некоторые ключевые концепции, которые помогут нам понять градиентный спуск. Производная - это важная концепция исчисления, которая не менее важна при градиентном спуске. Есть два подхода к этому: либо производная точки, либо производная всей функции. Один - мгновенная скорость изменения функции; например, если у нас есть изогнутая линия и точка на изогнутой линии. У нас также будет другая линия, известная как касательная, которая просто касается кривой именно в этой точке. Наклон этой касательной - производная. Хотя у нас могут быть положительные и отрицательные наклоны от этих касательных, для машинного обучения нас очень интересует линия наклона «0». Эти «0» наклоны обозначают максимумы или минимумы. Также есть два типа максимумов и минимумов, глобальные и локальные, о которых мы поговорим позже.

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

Следующее важное понятие - функция потерь. Функция потерь помогает нам описать несоответствие между нашими выходными данными и нашим целевым значением, где мы стремимся максимально минимизировать ошибку. Это не следует путать с вспомогательными функциями, которые являются противоположными. Можно было бы максимизировать функцию полезности, например, более высокую оценку точности, тогда как для функции потерь, такой как MSE, мы хотим быть как можно ближе к 0.

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

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

Есть несколько подсказок, которые мы можем использовать, чтобы узнать, в каком направлении спускаться по этому склону. Учитывая первоначальное предположение, если наклон касательной к этой точке положительный, вы захотите переместиться влево, а если наклон касательной к этой точке был отрицательным, вы бы захотели переместиться вправо. Итак, человек движется в направлении, противоположном склону. Определяя, в каком направлении должен двигаться наш наклон, также учитывается размер шага. Размер шага, также известный как скорость обучения или «альфа», является важным числом, которое также имеет потенциальные подводные камни с этим алгоритмом. Если снова подумать о холме, то, если он очень крутой, нам предстоит долгий путь до подножия (глобальный минимум), поэтому можно было бы делать большие шаги по направлению к основанию. Но, продолжая делать большие шаги, можно было бы перескочить минимум, и тогда алгоритм продолжил бы подпрыгивать в «долине», постоянно ухудшаясь по мере того, как шаг и градиент продолжают увеличиваться. Другая потенциальная проблема - слишком маленький размер шага - алгоритму потребуется слишком много времени, чтобы найти минимум, и либо он займет слишком много времени, либо просто остановится, не достигнув его.

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

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

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

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