Модуль 4. Производные и оптимизация¶
После этого модуля вы сможете
- Читать градиент как направление наискорейшего роста и объяснить, почему спуск идёт против него.
- Применить цепное правило руками — ту самую операцию, из которой в модуле 8 соберётся backprop.
- Проверить аналитический градиент численным. Это главный приём отладки обучения.
- Показать на графике, что делает слишком большой шаг и что делает слишком маленький.
- Объяснить зигзаг спуска через число обусловленности из модуля 3.
Время: около двух недель. Пререквизиты: модуль 3.
Ноутбук: notebooks/04-derivatives-and-optimisation.ipynb
Зачем это¶
Регрессия в модуле 3 решилась точно: одно уравнение, ответ. Это редкая удача. У почти всех остальных задач курса точного решения нет — ни у нейросети, ни у политики в RL, ни у рекомендательной модели.
Остаётся один приём, и он же последний: начать с плохого ответа и улучшать его маленькими шагами, пока улучшать нечего. Всё обучение в этом курсе — это он. Разница между методами сводится к тому, как считать направление шага и какой длины его делать.
Производная¶
Производная — скорость изменения функции. Насколько вырастет \(f\), если чуть увеличить \(x\).
Определение через предел важно для одной вещи: производную всегда можно посчитать численно, подставив маленькое \(h\) вместо предела. Это медленно и неточно, но не требует вывода формулы, и поэтому это идеальный способ проверить формулу, которую вы вывели.
Приём называется gradient check, и в модуле 8 он спасёт вам не один день. Аналитическая формула и численная оценка обязаны совпасть в нескольких знаках. Не совпали — ошибка в выводе, а не в данных.
Что понадобится из таблицы производных:
| \(f(x)\) | \(f'(x)\) |
|---|---|
| \(x^n\) | \(nx^{n-1}\) |
| \(e^x\) | \(e^x\) |
| \(\ln x\) | \(1/x\) |
| \(\sigma(x) = \frac{1}{1+e^{-x}}\) | \(\sigma(x)(1 - \sigma(x))\) |
Последняя строка — сигмоида. Её производная выражается через неё саму, и это одна из причин, почему она так долго была любимой функцией активации.
Градиент¶
У функции многих переменных производная берётся по каждой отдельно. Собранные в вектор, частные производные образуют градиент:
Одно свойство делает его полезным: градиент указывает направление наискорейшего роста, а его длина равна скорости роста в этом направлении.
Отсюда весь метод. Хотите минимум — идите против градиента:
\(\eta\) — длина шага, learning rate. Всё обучение в курсе — эта строка, повторённая миллионы раз.
Почему именно наискорейший рост
Изменение \(f\) при маленьком шаге \(\delta\) равно \(\nabla f \cdot \delta\) — скалярное произведение из модуля 3. При фиксированной длине шага оно максимально, когда \(\delta\) сонаправлен с \(\nabla f\). Максимальный рост — вдоль градиента, максимальное падение — против.
Здесь скалярное произведение из прошлого модуля работает не как метафора, а как доказательство.
Цепное правило¶
Функция от функции. Производная — произведение производных:
Это самое важное правило в курсе. Нейросеть — это композиция: слой от слоя от слоя. Обратное распространение ошибки — цепное правило, применённое по этой композиции справа налево, и ничего сверх этого в нём нет.
Разберём на функции потерь
Логистическая регрессия: \(z = w \cdot x\), предсказание \(p = \sigma(z)\), потеря \(L = -\big(y\ln p + (1-y)\ln(1-p)\big)\).
Нужна \(\partial L/\partial w\). Идём по цепочке справа налево:
Перемножаем:
Всё сократилось. Градиент — ошибка предсказания, умноженная на вход. Такой же вид получится у линейной регрессии и у последнего слоя сети с softmax: это не совпадение, а свойство правильно подобранной пары «функция активации плюс функция потерь».
Градиентный спуск и длина шага¶
Направление известно. Остаётся длина шага, и она решает всё.
Слишком маленький \(\eta\). Спуск сходится, но медленно. Тысячи шагов там, где хватило бы десятков. Обидно, но не страшно.
Слишком большой \(\eta\). Шаг перелетает минимум и попадает выше, чем был. Следующий
перелетает сильнее. Потеря растёт, потом становится nan. Это не «модель не учится» — это
арифметика расходящейся последовательности.
Правильный \(\eta\) находится подбором, и подбирают его по графику потерь: потеря должна падать монотонно и быстро. График — не украшение отчёта, а рабочий инструмент.
Первое, что делать, когда обучение не идёт
Уменьшите шаг в десять раз и запустите снова. В большинстве случаев это диагноз: пошло — был слишком велик, не пошло — ищите ошибку в градиенте, и ищите её через gradient check.
Овраг¶
Теперь почему одного шага не хватает.
Возьмите функцию, у которой минимум лежит на дне длинного узкого оврага. Градиент на склоне указывает поперёк оврага, а не вдоль него. Спуск бьётся от стенки к стенке и продвигается к минимуму медленно.
Крутизна стенок относительно пологости дна — это число обусловленности из модуля 3. Чем оно больше, тем уже овраг и тем сильнее зигзаг.
Отсюда два лечения, и оба встретятся дальше в курсе.
Нормализация признаков. Приводит облако к круглому виду, уменьшает \(\kappa\), распрямляет траекторию. Вот зачем данные масштабируют. Не «так принято», а потому, что иначе спуск идёт зигзагом.
Момент. Шаг накапливает инерцию:
Колебания поперёк оврага гасят друг друга, движение вдоль дна накапливается. Одна лишняя строка, а сходимость на плохо обусловленных задачах ускоряется в разы.
Стохастический спуск¶
Последний кусок. Считать градиент по всему набору данных дорого: миллион объектов — миллион слагаемых на каждый шаг.
SGD считает градиент по случайному подмножеству — батчу. Оценка получается шумной, зато шагов в секунду делается на порядки больше.
Шум здесь не только цена, но и польза. Точный градиент застревает в первом же локальном минимуме. Шумный из мелкого минимума вытряхивается и уходит дальше.
Размер батча — обмен между качеством оценки градиента и числом шагов. Из модуля 2 известен курс: шум оценки падает как \(\sqrt{\text{размер батча}}\). Батч вчетверо больше даёт вдвое менее шумный градиент и вчетверо более дорогой шаг.
Практика¶
Часть 1. Ноутбук¶
Откройте notebooks/04-derivatives-and-optimisation.ipynb.
Что внутри:
- Численная производная против аналитической. Подбираем \(h\): слишком большое — ошибка аппроксимации, слишком маленькое — ошибка округления.
- Gradient check на логистической потере. Тот самый приём для модуля 8.
- Спуск на квадратичной функции, траектория на линиях уровня.
- Перебор шага: сходимость, медленная сходимость, расходимость в
nan. - Овраг: та же задача с числом обусловленности 50. Зигзаг видно глазами.
- Момент на той же задаче. Считаем, во сколько раз меньше шагов.
- SGD против полного спуска на регрессии: шаги в секунду против гладкости.
Часть 2. Своя регрессия, но спуском¶
Возьмите регрессию из модуля 3, где ответ уже известен точно.
- Решите её градиентным спуском с нуля, без
lstsq. - Сравните веса с точным решением. Насколько близко и за сколько шагов.
- Отмасштабируйте признаки и повторите. Сколько шагов теперь.
- Посчитайте число обусловленности до и после масштабирования. Соотнесите с числом шагов.
Смысл упражнения в том, что правильный ответ известен заранее. Дальше в курсе так не будет никогда, и опыт «спуск сошёлся туда, куда надо» стоит получить сейчас.
Задание¶
- Выведите производную сигмоиды из определения. Убедитесь, что получается \(\sigma(1-\sigma)\).
- Выведите \(\partial L/\partial w\) для линейной регрессии с квадратичной потерей. Сравните с логистической из текста.
- Реализуйте gradient check как функцию: принимает функцию, аналитический градиент и точку, возвращает относительное расхождение. Она пригодится в модуле 8.
- Найдите наибольший шаг, при котором спуск на \(f(x) = x^2\) ещё сходится. Ответ должен быть точным числом, а не подобранным.
- Постройте задачу с числом обусловленности около 1000 и покажите, во сколько раз момент сокращает число шагов.
Проверка себя¶
- Почему спуск идёт против градиента, а не вдоль?
- Что происходит при слишком большом шаге и как это выглядит на графике потерь?
- Сформулируйте цепное правило и объясните, почему без него не существует обучения сетей.
- Почему в градиенте логистической регрессии всё сокращается до \((p-y)x\)?
- Что такое gradient check и почему это первое, что нужно сделать при подозрении на ошибку?
- Как число обусловленности связано с зигзагом спуска?
- Зачем нормализуют признаки — геометрический ответ, а не «так принято».
- Чем шум SGD полезен, а не только вреден?
Дальше¶
Часть I закончена. Теперь есть язык: утверждение и база сравнения, параметр и оценка, вектор и матрица, градиент и шаг. Дальше он применяется.
В части II появляются первые настоящие модели — линейные, деревья, бустинг. Они же будут базовыми линиями для всего, что придёт после. Половину заявленных прорывов обыгрывает правильно настроенный бустинг, и увидеть это своими руками надо до того, как начнутся нейросети.
Обучение — это одна строка: шаг против градиента. Всё остальное в курсе — как считать направление и какой длины делать шаг.