Градиентный спуск на пальцах

Почему производная – это направление движения.

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

Этот механизм называется градиентным спуском.

circle-info

Сам метод градиентного спуска в его современном виде сформировался не в одной работе, а постепенно. Его математические основы уходят к методу наискорейшего спуска (method of steepest descent), который подробно исследовали в 1840-х годах Огюстен-Луи Кошиarrow-up-right. В XX веке метод получил развитие в оптимизации и численных методах, а затем стал ключевым инструментом машинного обучения и нейросетей.

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

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

Ошибка как ландшафт

Представим себе очень простую ситуацию. У нас есть модель с одним параметром ww. Мы меняем ww и каждый раз считаем ошибку L(w)L(w). Например, это может быть MSE.

Если нарисовать график зависимости ошибки от ww, то мы увидим кривую. Где-то ошибка больше, где-то меньше, а в одной точке – минимальна.

В этот момент полезно сменить абстракцию. Перестать думать об ошибке как о формуле и начать думать о ней как о ландшафте.

Значение параметра ww – это положение по горизонтали. Значение ошибки L(w)L(w) – это высота.

Мы как будто идем по гористой местности и хотим спуститься в самую низкую точку – в минимум.

12.1 График ошибки как холм

Почему "спуск"

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

Все, что мы можем сделать – посмотреть под ноги и понять, куда склон уходит сильнее.

Вот здесь и появляется производная.

Производная как наклон

Производная функции L(w)L(w) по ww – это, по сути, наклон кривой в текущей точке.

Формально:

L(w)=dLdwL^′(w) = \frac{dL}{dw}

Но без формального определения это означает следующее:

  • если производная положительная, то при увеличении ww ошибка растет

  • если производная отрицательная, то при увеличении ww ошибка уменьшается

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

Геометрически производная – это тангенс угла наклона касательной к графику.

12.2 График функции и касательная, показывающая наклон

Почему производная – это направление движения

Допустим, мы стоим в точке w0w_0.

Если dLdw>0\frac{dL}{dw} > 0, значит график "идет вправо - вверх". Чтобы спускаться, нам нужно двигаться влево, то есть уменьшать ww.

Если dLdw<0\frac{dL}{dw} < 0, график "идет вправо - вниз". Значит, выгодно двигаться вправо, увеличивая ww.

Обратите внимание на важный момент: мы не идем по производной, мы идем против нее.

Именно поэтому шаг градиентного спуска выглядит так:

wnew=woldηdLdww_{new} = w_{old} - \eta \cdot \frac{dL}{dw}

Здесь η\eta (эта буква называется "эта") – это скорость обучения, или learning rate.

Она отвечает за то, насколько длинный шаг мы делаем.

Интуиция шага

Можно читать эту формулу буквально словами: "Возьми текущее значение параметра и сдвинь его в сторону, противоположную градиенту функции в этой точке. Сделай это на величину, пропорциональную этому наклону".

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

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

Что будет, если шаг слишком большой

Интуиция подсказывает, что можно "ускориться" и взять очень большое значение η\eta. Но тут нас поджидает классическая ловушка.

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

12.3 График с перескакиванием минимума

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

Отсюда и главный практический вывод: learning rate – один из самых чувствительных параметров в обучении моделей.

Если хочется увидеть это ещё проще и интуитивнее – разберём "на пальцах".

chevron-rightИнтуитивное объяснение производной, градиента и градиентного спускаhashtag

Давайте очень просто, почти "на пальцах".

1. Сначала про производную

Представьте горку.

Функция – это форма горки.

Производная – это насколько крутой склон в конкретной точке.

  • если производная положительная → вы идёте вверх

  • если отрицательная → вниз

  • если 0 → вы на вершине или в яме

circle-info

То есть производная – это насколько быстро меняется функция при изменении одной переменной.

2. Теперь про градиент

А теперь представьте, что вы не на линии, а на поверхности (как в 3D).

Например, у вас есть функция потерь: L(w1,w2)L(w₁, w₂).

Это уже не линия, а "ландшафт" – холмы и впадины.

Градиент – это вектор (стрелка), который показывает, куда идти, чтобы функция росла быстрее всего.

Он состоит из частных производных: L=(dLdw1,dLdw2)∇L = (\frac{dL}{dw_1}, \frac{dL}{dw_2})

Это означает:

  • dLdw1\frac{dL}{dw_1} – насколько круто в направлении w1w_1

  • dLdw2\frac{dL}{dw_2} – насколько круто в направлении w2w_2

circle-info

Градиент = это вектор частных производных функции по всем её переменным.

3. Связь (самое главное)

Важно понять, что производная – это частный случай градиента.

  • 1 переменная → есть просто производная

  • много переменных → появляется градиент (вектор из производных)

4. На примере функции потерь

Возьмём простую функцию: L(w)=(w3)2L(w) = (w - 3)^2

График этой функции выглядит как "чашка", минимум в точке w=3w = 3.

Производная: dLdw=2(w3)\frac{dL}{dw} = 2 (w - 3)

Что это значит:

  • если w > 3 → производная положительная → надо идти влево

  • если w < 3 → отрицательная → идти вправо

  • если w = 3 → 0 → ты в минимуме

Вот это и использует градиентный спуск.

circle-info

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

5. Если параметров несколько

Теперь функция: L(w1,w2)=(w13)2+(w2+1)2L(w₁, w₂) = (w₁ - 3)² + (w₂ + 1)²

Градиент: L=(2(w13),2(w2+1))∇L = (2(w₁ - 3), 2(w₂ + 1))

А это уже та самая "стрелка", которая говорит:

  • куда двигать w1w_1

  • куда двигать w2w_2

6. Интуитивное объяснение для ребёнка

  • Производная – это "насколько круто вперёд/назад"

  • Градиент – это "стрелка в пространстве: куда идти, чтобы быстрее всего подняться"

  • Градиентный спуск – это "идти в противоположную сторону от стрелки, чтобы быстрее всего спуститься вниз"

Коротко

  • производная = изменение по одной оси

  • градиент = изменения по всем осям сразу

  • т.е. градиент = набор производных

Связка с теорией (очень просто)

На каждом шаге обучения происходит одно и то же:

w=wηdLdww = w - \eta \frac{dL}{dw}

или

w=wlearning_rateпроизводнаяw = w − learning\_rate * производная

То есть:

  • производная говорит "куда вверх"

  • мы идём в противоположную сторону → вниз

И это вся суть градиентного спуска.

Много параметров – тот же принцип

До этого мы говорили про один параметр ww. В реальных же моделях параметров может быть десятки, тысячи или даже миллионы.

Но идея не меняется.

Ошибка становится функцией многих переменных:

L(w1,w2,,wn)L(w_1, w_2, \dots, w_n)

Производная превращается в градиент – вектор из частных производных:

L=(Lw1,Lw2,,Lwn)\nabla L = \left( \frac{\partial L}{\partial w_1}, \frac{\partial L}{\partial w_2}, \dots, \frac{\partial L}{\partial w_n} \right)

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

И снова никакой магии. Мы просто идем вниз по самому крутому склону.

12.4 3D-поверхность ошибки и вектор градиента

Почему без производных никуда

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

Производная отвечает на простой вопрос: "Если я слегка изменю параметры, как изменится ошибка?"

Градиентный спуск – это не более чем повторение одного и того же цикла:

  1. посчитай текущую ошибку

  2. посчитай производные

  3. сделай шаг в сторону уменьшения ошибки

Этот цикл и есть "обучение".

Перед тем как мы перейдём к реализации, давайте освежим в памяти ещё раз:

Ошибка это:

errori=yiy^ierror_i = y_i − \hat{y}_i

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

L=(yiy^i)2L = (y_i - \hat{y}_i)^2

Производные:

По ww:

Lw=2xi(yiy^i)\frac{\partial L}{\partial w} = -2 x_i (y_i - \hat{y}_i)

По bb:

Lb=2(yiy^i)\frac{\partial L}{\partial b} = -2 (y_i - \hat{y}_i)

Реализация на PHP – с нуля

Начнём с минимального примера: один признак, один вес. Оценка стоимости квартиры по её площади.

Этот код обучает простейшую линейную регрессию методом градиентного спуска.

Модель имеет вид:

y=wx+by = w x + b

где

  • xx – один признак (площадь),

  • yy – целевая величина (цена),

  • ww – вес (насколько цена растёт при увеличении площади),

  • bb – смещение (базовая цена).

Код:

  1. берёт набор пар (x,y)(x, y),

  2. начинает с нулевых параметров ww и bb,

  3. много раз (эпох – epochs) считает ошибку,

  4. вычисляет, как нужно изменить ww и bb, чтобы ошибка уменьшалась,

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

В итоге мы получаем линию, максимально близкую к точкам. Важно, что здесь нет никакой "магии ML". Это обычный цикл, обычная математика и аккуратная работа с числами.

Векторная версия

Когда признаков больше, удобнее мыслить векторами.

Здесь bias уже включён как дополнительный признак со значением 1. Это эквивалентно предыдущей формуле, просто записано в расширенном векторном виде.

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

  • одинаково работает для линейных моделей, логистической регрессии, SVM, нейросетей,

  • упрощает backprop,

  • позволяет хранить всё в матрицах,

  • убирает условные ветки из кода и формул.

На практике почти все линейные модели в библиотеках делают именно так.

Подведём итог

Если вынести за скобки формулы, градиентный спуск – это про ориентирование в пространстве ошибок. Производная – это наш компас. Она не говорит, где именно находится глобальный минимум, но всегда подсказывает, куда идти прямо сейчас.

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

Именно это и делает градиентный спуск.

circle-info

Чтобы самостоятельно протестировать этот код, воспользуйтесь онлайн-демонстрациейarrow-up-right для его запуска.

Last updated