У нас есть поверхность потерь и желание попасть на её дно. Беда в том,
что всю поверхность мы не видим — только щупаем её под ногами в одной
точке. Сегодня мы найдём инструмент, который из этого локального
ощупывания выжимает точное направление вниз: градиент. Из него вырастет
главный алгоритм обучения — градиентный спуск.
Спуск вслепую
Вообразите, что вас высадили на склон в густом тумане и велели
спуститься в долину. Всей местности не видно, карты нет — но под ногами
вы чувствуете, куда склон уходит вниз, и в какую сторону он круче.
Разумная стратегия: определить направление наискорейшего спуска, шагнуть
туда, снова ощупать склон, снова шагнуть — и так, шаг за шагом,
скатиться на дно, ни разу не видя всей долины.
Ровно в таком положении находится обучение сети. Поверхность потерь
из прошлого урока висит над миллионномерным пространством
весов, и увидеть её целиком невозможно. Зато в текущей точке можно
вычислить, как потеря меняется при малом сдвиге каждого веса, — то есть
ощупать склон. Инструмент, превращающий это ощупывание в точную стрелку
«вниз», и есть градиент.
От наклона к вектору
В одном измерении всё просто. Производная f′(x) — это наклон: её знак
говорит, растёт функция или убывает, а величина — насколько круто.
Чтобы спускаться, шагаем против наклона: если склон идёт вверх вправо
(f′>0), идём влево, и наоборот. Правило одного шага:
x←x−ηf′(x),
где η>0 — длина шага. Минус разворачивает нас навстречу спуску:
там, где производная положительна, вычитание уводит x влево, к
меньшим значениям.
В пространстве многих весов у функции нет одного наклона — у неё есть
наклон вдоль каждой оси отдельно. Наклон вдоль оси wi, посчитанный
так, будто остальные веса заморожены, называют частной производной
∂L/∂wi. Собрав все частные производные в один вектор,
получаем градиент:
∇L=(∂w1∂L,∂w2∂L,…,∂wm∂L).
Градиент — это вектор, каждая координата которого говорит, как быстро
растёт потеря, если чуть подвинуть соответствующий вес. Он живёт в том
же пространстве, что и веса, и указывает направление в нём.
Почему градиент — самый крутой подъём
Ключевое свойство, ради которого всё затевалось: из всех направлений,
в которые можно шагнуть, градиент указывает то, вдоль которого функция
растёт быстрее всего. А значит, −∇L — направление, вдоль
которого она быстрее всего убывает. Не «одно из направлений вниз», а
самое крутое из них. Поэтому шаг против градиента — оптимальный
локальный ход к минимуму.
У этого есть красивое геометрическое лицо. Проведём на поверхности
потерь линии уровня — как на топографической карте, где соединены
точки равной высоты. Тогда градиент в каждой точке перпендикулярен
линии уровня, проходящей через неё. Это логично: вдоль линии уровня
высота не меняется вовсе, значит, самый быстрый рост — поперёк неё, по
кратчайшему пути между уровнями. Куда гуще линии уровня, там склон
круче и градиент длиннее; где они расходятся, склон полог и градиент
короток. У дна долины линии уровня замыкаются в точку, а градиент
обращается в ноль — та самая стационарность из
урока о минимумах.
Линии уровня потерь (как высоты на карте) и стрелки градиента. Каждая
стрелка перпендикулярна своей линии уровня и смотрит в сторону роста;
её противоположность (пунктир) — путь вниз. Где линии гуще, склон круче
и стрелка длиннее. В центре, у минимума, линии стягиваются в точку, а
градиент гаснет до нуля.
Градиентный спуск: правило шага
Теперь собственно алгоритм. Стоим в точке w, вычисляем градиент,
делаем шаг против него, повторяем:
w←w−η∇L(w).
Это градиентный спуск — сердце обучения почти всех современных моделей.
Каждый шаг чуть сдвигает все веса в сторону меньшей потери; повторяя
тысячи и миллионы раз, скатываемся ко дну. Множитель η называют
скоростью обучения (или темпом): он задаёт длину шага. Весь алгоритм
умещается в одну строку, и вся мощь глубокого обучения — это она,
исполненная над огромными сетями с хитро посчитанными градиентами.
Заметьте, чего спуску не нужно: ни вида всей поверхности, ни формулы
её минимума. Только локальный градиент в текущей точке — то самое
ощупывание склона под ногами. Оттого спуск и работает там, где
поверхность потерь необозрима, а минимум аналитически не находится, —
то есть в любой нейросети.
На реальных данных: спуск к линии жизни
Проверим спуск на живой задаче. Возьмём Gapminder за 2007 год из
урока о Хеббе: по горизонтали логарифм ВВП на душу, по
вертикали ожидаемая продолжительность жизни, обе величины приведены к
общему масштабу. Будем искать прямую y^=w0+w1x,
минимизирующую среднеквадратичную ошибку — потерю из
урока о потерях. Потеря зависит от двух весов, наклона
w1 и сдвига w0, и над плоскостью (w0,w1) висит поверхность —
и, поскольку MSE выпукла, это чаша с единственным дном
(урок о выпуклости).
Стартуем с заведомо плохой прямой, w0=1,5, w1=−1 (наклон вниз,
хотя данные растут), и запустим спуск. Градиент MSE считается явной
формулой, шаг за шагом путь скользит по стенке чаши к её дну, и за
сорок шагов при η=0,3 веса приходят к w0=0, w1=0,81.
Наклон 0,81 — это в точности корреляция богатства и долголетия,
которую мы уже видели у хеббовского нейрона в
уроке 14: две дороги, спуск и правило Хебба, привели к
одному числу. Спуск нашёл наилучшую прямую, ни разу не увидев всей
поверхности потерь, — только скользя вниз по локальному градиенту.
Рис. 22.2. Путь градиентного спуска по чаше потерь
Слева — линии уровня потерь над весами (w0,w1) для линейной модели
на данных Gapminder; чёрная ломаная — путь спуска из плохого старта
(1,5;−1) к минимуму, каждый шаг поперёк линий уровня, против
градиента. Справа — найденная прямая (наклон 0,81) на облаке стран:
она ловит связь богатства и долголетия. Спуск довёл плохую прямую до
наилучшей за сорок шагов.
Скорость обучения: между вялостью и срывом
Всё поведение спуска задаёт одно число — скорость обучения η, и с
ним та же история, что с усилением регулятора в
уроке о кибернетике. Слишком маленький η — шажки
крохотные, спуск ползёт ко дну мучительно долго. Слишком большой — шаг
проскакивает минимум, отлетает на другую стенку чаши выше, чем был,
следующий шаг отбрасывает ещё дальше, и спуск не сходится, а
расходится, улетая в бесконечность. Между вялостью и срывом лежит
узкая полоса удачных η, где спуск быстр и устойчив.
На нашей задаче Gapminder спуск сходится при η до примерно
единицы, а при η=1,05 уже расходится: потеря за шестьдесят шагов
не падает до 0,35, а взрывается до сотен тысяч. Порог устойчивости
— тот же математический сюжет, что порог автоколебаний термостата: если
шаг умножает отклонение на множитель больше единицы по модулю,
получается разнос. Подбор η — первое, чем занимаются, обучая сеть,
и первое, что ломает обучение, если ошибиться.
Рис. 22.3. Четыре скорости обучения: от вялости до срыва
Спуск по одной и той же параболе потерь при четырёх скоростях. Малая
η ползёт ко дну крохотными шажками; средняя доходит быстро; большая
перелетает минимум и колеблется, затухая; чрезмерная отлетает всё
дальше и расходится. Скорость обучения — та же ручка между медлительностью
и срывом, что усиление в контуре обратной связи.
Русская линия: оптимизация как ремесло
Градиентный спуск придумал ещё Коши в 1847 году, но в рабочий,
надёжный инструмент его превратила во многом советская школа
оптимизации. Борис Поляк дал спуску инерцию (метод тяжёлого шарика,
1964) и разработал теорию его сходимости; его ученик Юрий Нестеров в
1983 году построил ускоренный градиентный метод, доказуемо оптимальный
по скорости для выпуклых задач, — им пользуются и сегодня в
переднекрайних моделях. Наум Шор развивал субградиентные и эллипсоидные
методы для негладких задач. Из этой традиции — привычки не просто
спускаться, а спускаться доказуемо быстро — выросли современные
оптимизаторы, на которых учатся все нейросети мира.
Лаборатория: скатитесь по склону сами
Линии уровня, стрелка градиента и путь спуска
График шире экрана — листайте по горизонтали →
Загружается живая иллюстрация…
Порядок опытов. Перед вами карта линий уровня реальной поверхности
потерь. Кликните куда угодно — из этой точки протянется стрелка
градиента (перпендикулярно линиям уровня, в сторону роста) и побежит
ломаная спуска против неё, шаг за шагом ко дну. Меняйте скорость
обучения: при малой спуск ползёт крошечными шажками, при средней быстро
находит минимум, при слишком большой перелетает и расходится, улетая с
карты. Убедитесь, что стрелка всегда поперёк линий уровня и всегда
длиннее там, где склон круче. Вы своими руками проведёте то самое
спускание вслепую, из которого состоит обучение любой сети.
Сборка: одна стрелка, весь алгоритм
Не видя всей поверхности потерь, обучение нащупывает дорогу вниз одним
инструментом — градиентом. Он собирает частные производные, наклоны
вдоль каждой оси, в единый вектор, который указывает наискорейший рост;
шаг против него, w←w−η∇L, — наилучший локальный ход
к минимуму. Градиент перпендикулярен линиям уровня и гаснет у дна, а
скорость обучения η балансирует спуск между вялостью и срывом,
как усиление в контуре обратной связи. На данных Gapminder спуск довёл
плохую прямую до наилучшей за сорок шагов, придя к тому же наклону, что
и правило Хебба. Осталась одна, но огромная трудность: в настоящей сети
из миллионов весов, спрятанных за многими слоями, как вообще посчитать
все эти частные производные? Ответ — обратное распространение ошибки, и
это первый шаг, но прежде мы разберём, как спускаться, когда данных
слишком много, чтобы считать градиент по всем сразу. С этого —
стохастического спуска — продолжается механика обучения.