В этой статье мы стремимся расширить наши возможности по визуализации градиентного спуска до множественной линейной регрессии. Это продолжение статьи Анимация градиентного спуска: 1. Простая линейная регрессия. Как и раньше, наша цель - настроить модель, подогнать ее под наши обучающие данные, используя пакетный градиентный спуск, сохраняя при этом значения параметров для каждой эпохи. После этого мы можем использовать наши сохраненные данные для создания анимации с помощью модуля Python celluloid.

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

Настройка модели

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

с участием

и b, представляющий точку пересечения оси Y («смещение») нашей плоскости регрессии. Наша цель - найти гиперплоскость, которая минимизирует средний квадрат расстояния между точками обучающих данных и этой гиперплоскостью. Градиентный спуск позволяет нам определить оптимальные значения для параметров нашей модели θ, состоящих из наших весов w и члена смещения b, чтобы минимизировать среднеквадратичная ошибка между наблюдаемыми точками данных y и точками данных, которые мы предсказали с помощью нашей регрессионной модели (ŷ). Во время обучения мы стремимся обновлять значения наших параметров в соответствии со следующей формулой, пока не достигнем сходимости:

где ∇ J (θ) представляет градиент нашей функции стоимости J по отношению к параметрам нашей модели θ. Скорость обучения представлена ​​как α. Частные производные для каждого веса и члена смещения такие же, как в нашей модели простой линейной регрессии. На этот раз, однако, мы хотим создать (мульти) линейную модель регрессии, гибкую в зависимости от количества переменных-предикторов, и ввести матрицу весов для одновременной корректировки всех весов. Кроме того, мы сохраняем значения наших параметров в массивах непосредственно во время самого процесса подбора, что в вычислительном отношении быстрее, чем использование циклов for и списков, как мы делали в предыдущей статье. Я решил произвольно установить начальные значения параметров для веса (ов) на 3 и на -1 для смещения. В Python мы импортируем некоторые библиотеки и настраиваем нашу модель:

После этого мы намерены подогнать нашу модель к некоторым произвольным обучающим данным. Хотя наша модель теоретически может обрабатывать любое количество переменных-предикторов, я выбрал обучающий набор данных с двумя переменными-предикторами. Мы намеренно используем очень маленькую скорость обучения, α = 0,001, чтобы избежать слишком больших шагов в нашей анимации. Поскольку в этой статье основное внимание уделяется анимации, а не статистическому выводу, мы пока просто игнорируем предположения о линейной регрессии (например, отсутствие мультиколлинеарности и т. Д.).

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

Теперь мы, наконец, можем создать нашу первую анимацию. Как и раньше, мы хотим начать с визуализации значений, которые наша функция стоимости и параметры принимают по отношению к эпохе, при построении соответствующей плоскости регрессии в 3-D. Как описано ранее, мы намерены наносить на график только значения для выбранных эпох, поскольку наибольшие шаги обычно наблюдаются в начале градиентного спуска. После каждого цикла for мы делаем снимки наших графиков. С помощью функции анимации камеры мы можем превращать снимки в анимацию. Чтобы получить желаемую плоскость регрессии, мы вводим координатную сетку (M1, M2) через numpy.meshgrid и определяем функцию pred_meshgrid () для вычисления соответствующих z-значений по отношению к параметрам модели при определенном эпоха. Пунктирные соединительные линии, показанные в следующих анимациях, могут быть получены с помощью линейных графиков между точками обучающих данных и прогнозируемыми точками. Возвращая окончательные значения параметров (см. Закомментированный код!), Которые мы получили в нашей анимации, мы обеспечиваем приблизительную визуализацию сходимости модели, несмотря на то, что не использовали весь диапазон значений параметров, которые мы сохранили в процессе подбора.

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

Модель фиксированного перехвата:

При создании более сложных анимаций градиентного спуска, особенно в 3-D, мы должны сосредоточиться на двух параметрах модели, сохраняя третий параметр «фиксированным». Как правило, нас больше интересуют веса, а не член смещения нашей модели множественной линейной регрессии. Чтобы визуализировать, как затраты неуклонно снижаются с нашими скорректированными весами (w₀, w₁), мы должны настроить новую модель линейной регрессии, в которой член смещения b фиксирован. Это легко сделать, установив начальное значение для b на предопределенное значение b_fixed и удалив часть кода, где b обновляется в новая модель. b_fixed может принимать любое значение. В этом случае мы просто устанавливаем его на значение пересечения по оси Y, к которому сходилась предыдущая модель:

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

Контурный сюжет

Контурные графики позволяют нам визуализировать трехмерные поверхности на двухмерных плоскостях с помощью контурных линий и контуров с заливкой (= contourfs). В нашем случае мы хотим нанести w₀ и w₁ на оси x и y соответственно с затратами J в качестве контуров. Мы можем пометить определенные уровни контуров на графике с помощью контурной функции Matplotlib. Поскольку мы знаем, что наши окончательные затраты составляют примерно 76, мы можем установить наш последний уровень контура на 80.

Когда Y-пересечение было разрешено варьироваться, мы увидели значительные изменения значений параметров и затрат с более поздними эпохами, которые мы не хотели упускать на наших графиках регрессии и параметров. Однако при фиксированном b большая часть «действия», по-видимому, ограничивается первыми 400 эпохами. Таким образом, мы ограничиваем количество эпох, которые мы намерены визуализировать в следующих анимациях, до 400, что требует меньших вычислительных затрат и приводит к более привлекательной анимации. Чтобы подтвердить это впечатление, мы можем сравнить окончательные значения параметров, модель фиксированного перехвата, возвращенную после 100 000 эпох, со значениями параметров, которые мы получаем после 400 эпох (см. Закомментированный код ниже!). Поскольку значения параметров и стоимости обычно совпадают, будет справедливо сказать, что мы визуализировали сходимость модели, несмотря на ограничение количества визуализируемых эпох.

Поверхностный участок

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

Теоретически построение траектории градиентного спуска в плоскости x-y - как мы это делали с контурным графиком - соответствует реальной траектории градиентного спуска. В отличие от приведенного выше графика поверхности, градиентный спуск на самом деле вообще не включает перемещение в z-направлении, поскольку могут изменяться только параметры. Более подробное объяснение см. Здесь. Наконец, я хочу отметить, что создание анимации с использованием целлулоида может занять очень много времени. В частности, анимация с использованием участков поверхности может занять до 40 минут, чтобы вернуть желаемый результат. Тем не менее, я предпочел Celluloid другим пакетам (например, matplotlib.animation) из-за его простоты и ясности. Как всегда, приветствуются творческий вклад и конструктивная критика!

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

Спасибо за Ваш интерес!

Ссылки:





Приложение: