У нас есть поверхность потерь и желание попасть на её дно. Беда в том, что всю поверхность мы не видим — только щупаем её под ногами в одной точке. Сегодня мы найдём инструмент, который из этого локального ощупывания выжимает точное направление вниз: градиент. Из него вырастет главный алгоритм обучения — градиентный спуск.

Спуск вслепую

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

Ровно в таком положении находится обучение сети. Поверхность потерь из прошлого урока висит над миллионномерным пространством весов, и увидеть её целиком невозможно. Зато в текущей точке можно вычислить, как потеря меняется при малом сдвиге каждого веса, — то есть ощупать склон. Инструмент, превращающий это ощупывание в точную стрелку «вниз», и есть градиент.

От наклона к вектору

В одном измерении всё просто. Производная f(x)f'(x) — это наклон: её знак говорит, растёт функция или убывает, а величина — насколько круто. Чтобы спускаться, шагаем против наклона: если склон идёт вверх вправо (f>0f'>0), идём влево, и наоборот. Правило одного шага:

xxηf(x),x \leftarrow x - \eta\, f'(x),

где η>0\eta>0 — длина шага. Минус разворачивает нас навстречу спуску: там, где производная положительна, вычитание уводит xx влево, к меньшим значениям.

В пространстве многих весов у функции нет одного наклона — у неё есть наклон вдоль каждой оси отдельно. Наклон вдоль оси wiw_i, посчитанный так, будто остальные веса заморожены, называют частной производной L/wi\partial L/\partial w_i. Собрав все частные производные в один вектор, получаем градиент:

L=(Lw1, Lw2, , Lwm).\nabla L = \left(\frac{\partial L}{\partial w_1},\ \frac{\partial L}{\partial w_2},\ \ldots,\ \frac{\partial L}{\partial w_m}\right).

Градиент — это вектор, каждая координата которого говорит, как быстро растёт потеря, если чуть подвинуть соответствующий вес. Он живёт в том же пространстве, что и веса, и указывает направление в нём.

Почему градиент — самый крутой подъём

Ключевое свойство, ради которого всё затевалось: из всех направлений, в которые можно шагнуть, градиент указывает то, вдоль которого функция растёт быстрее всего. А значит, L-\nabla L — направление, вдоль которого она быстрее всего убывает. Не «одно из направлений вниз», а самое крутое из них. Поэтому шаг против градиента — оптимальный локальный ход к минимуму.

У этого есть красивое геометрическое лицо. Проведём на поверхности потерь линии уровня — как на топографической карте, где соединены точки равной высоты. Тогда градиент в каждой точке перпендикулярен линии уровня, проходящей через неё. Это логично: вдоль линии уровня высота не меняется вовсе, значит, самый быстрый рост — поперёк неё, по кратчайшему пути между уровнями. Куда гуще линии уровня, там склон круче и градиент длиннее; где они расходятся, склон полог и градиент короток. У дна долины линии уровня замыкаются в точку, а градиент обращается в ноль — та самая стационарность из урока о минимумах.

Рисунок шире экрана — проведите по немуОткрыть целиком ↗
Топографическая карта чашеобразной функции с концентрическими линиями уровня; в нескольких точках нарисованы стрелки градиента, каждая перпендикулярна линии уровня и направлена наружу к росту, а противоположная стрелка указывает внутрь к минимуму; там, где линии гуще, стрелки длиннее
Рис. 22.1. Линии уровня и стрелки градиента

Линии уровня потерь (как высоты на карте) и стрелки градиента. Каждая стрелка перпендикулярна своей линии уровня и смотрит в сторону роста; её противоположность (пунктир) — путь вниз. Где линии гуще, склон круче и стрелка длиннее. В центре, у минимума, линии стягиваются в точку, а градиент гаснет до нуля.

Градиентный спуск: правило шага

Теперь собственно алгоритм. Стоим в точке ww, вычисляем градиент, делаем шаг против него, повторяем:

wwηL(w).w \leftarrow w - \eta\,\nabla L(w).

Это градиентный спуск — сердце обучения почти всех современных моделей. Каждый шаг чуть сдвигает все веса в сторону меньшей потери; повторяя тысячи и миллионы раз, скатываемся ко дну. Множитель η\eta называют скоростью обучения (или темпом): он задаёт длину шага. Весь алгоритм умещается в одну строку, и вся мощь глубокого обучения — это она, исполненная над огромными сетями с хитро посчитанными градиентами.

Заметьте, чего спуску не нужно: ни вида всей поверхности, ни формулы её минимума. Только локальный градиент в текущей точке — то самое ощупывание склона под ногами. Оттого спуск и работает там, где поверхность потерь необозрима, а минимум аналитически не находится, — то есть в любой нейросети.

На реальных данных: спуск к линии жизни

Проверим спуск на живой задаче. Возьмём Gapminder за 2007 год из урока о Хеббе: по горизонтали логарифм ВВП на душу, по вертикали ожидаемая продолжительность жизни, обе величины приведены к общему масштабу. Будем искать прямую y^=w0+w1x\hat y = w_0 + w_1 x, минимизирующую среднеквадратичную ошибку — потерю из урока о потерях. Потеря зависит от двух весов, наклона w1w_1 и сдвига w0w_0, и над плоскостью (w0,w1)(w_0,w_1) висит поверхность — и, поскольку MSE выпукла, это чаша с единственным дном (урок о выпуклости).

Стартуем с заведомо плохой прямой, w0=1,5w_0=1{,}5, w1=1w_1=-1 (наклон вниз, хотя данные растут), и запустим спуск. Градиент MSE считается явной формулой, шаг за шагом путь скользит по стенке чаши к её дну, и за сорок шагов при η=0,3\eta=0{,}3 веса приходят к w0=0w_0=0, w1=0,81w_1=0{,}81. Наклон 0,810{,}81 — это в точности корреляция богатства и долголетия, которую мы уже видели у хеббовского нейрона в уроке 14: две дороги, спуск и правило Хебба, привели к одному числу. Спуск нашёл наилучшую прямую, ни разу не увидев всей поверхности потерь, — только скользя вниз по локальному градиенту.

Рисунок шире экрана — проведите по немуОткрыть целиком ↗
Слева контурная карта чашеобразной поверхности потерь над плоскостью наклона и сдвига; ломаная траектория спуска из плохой начальной точки скользит поперёк линий уровня к минимуму в центре; справа найденная прямая ложится на облако стран
Рис. 22.2. Путь градиентного спуска по чаше потерь

Слева — линии уровня потерь над весами (w0,w1)(w_0,w_1) для линейной модели на данных Gapminder; чёрная ломаная — путь спуска из плохого старта (1,5;1)(1{,}5;-1) к минимуму, каждый шаг поперёк линий уровня, против градиента. Справа — найденная прямая (наклон 0,810{,}81) на облаке стран: она ловит связь богатства и долголетия. Спуск довёл плохую прямую до наилучшей за сорок шагов.

Скорость обучения: между вялостью и срывом

Всё поведение спуска задаёт одно число — скорость обучения η\eta, и с ним та же история, что с усилением регулятора в уроке о кибернетике. Слишком маленький η\eta — шажки крохотные, спуск ползёт ко дну мучительно долго. Слишком большой — шаг проскакивает минимум, отлетает на другую стенку чаши выше, чем был, следующий шаг отбрасывает ещё дальше, и спуск не сходится, а расходится, улетая в бесконечность. Между вялостью и срывом лежит узкая полоса удачных η\eta, где спуск быстр и устойчив.

На нашей задаче Gapminder спуск сходится при η\eta до примерно единицы, а при η=1,05\eta=1{,}05 уже расходится: потеря за шестьдесят шагов не падает до 0,350{,}35, а взрывается до сотен тысяч. Порог устойчивости — тот же математический сюжет, что порог автоколебаний термостата: если шаг умножает отклонение на множитель больше единицы по модулю, получается разнос. Подбор η\eta — первое, чем занимаются, обучая сеть, и первое, что ломает обучение, если ошибиться.

Рисунок шире экрана — проведите по немуОткрыть целиком ↗
Четыре траектории спуска по одной параболе потерь: при малой скорости мелкие шаги медленно ползут к минимуму, при средней быстро сходятся, при большой перелетают и колеблются затухая, при слишком большой отлетают всё дальше и расходятся
Рис. 22.3. Четыре скорости обучения: от вялости до срыва

Спуск по одной и той же параболе потерь при четырёх скоростях. Малая η\eta ползёт ко дну крохотными шажками; средняя доходит быстро; большая перелетает минимум и колеблется, затухая; чрезмерная отлетает всё дальше и расходится. Скорость обучения — та же ручка между медлительностью и срывом, что усиление в контуре обратной связи.

Русская линия: оптимизация как ремесло

Градиентный спуск придумал ещё Коши в 1847 году, но в рабочий, надёжный инструмент его превратила во многом советская школа оптимизации. Борис Поляк дал спуску инерцию (метод тяжёлого шарика, 1964) и разработал теорию его сходимости; его ученик Юрий Нестеров в 1983 году построил ускоренный градиентный метод, доказуемо оптимальный по скорости для выпуклых задач, — им пользуются и сегодня в переднекрайних моделях. Наум Шор развивал субградиентные и эллипсоидные методы для негладких задач. Из этой традиции — привычки не просто спускаться, а спускаться доказуемо быстро — выросли современные оптимизаторы, на которых учатся все нейросети мира.

Лаборатория: скатитесь по склону сами

Линии уровня, стрелка градиента и путь спуска

Загружается живая иллюстрация…

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

Сборка: одна стрелка, весь алгоритм

Не видя всей поверхности потерь, обучение нащупывает дорогу вниз одним инструментом — градиентом. Он собирает частные производные, наклоны вдоль каждой оси, в единый вектор, который указывает наискорейший рост; шаг против него, wwηLw\leftarrow w-\eta\nabla L, — наилучший локальный ход к минимуму. Градиент перпендикулярен линиям уровня и гаснет у дна, а скорость обучения η\eta балансирует спуск между вялостью и срывом, как усиление в контуре обратной связи. На данных Gapminder спуск довёл плохую прямую до наилучшей за сорок шагов, придя к тому же наклону, что и правило Хебба. Осталась одна, но огромная трудность: в настоящей сети из миллионов весов, спрятанных за многими слоями, как вообще посчитать все эти частные производные? Ответ — обратное распространение ошибки, и это первый шаг, но прежде мы разберём, как спускаться, когда данных слишком много, чтобы считать градиент по всем сразу. С этого — стохастического спуска — продолжается механика обучения.

Задачи