Дифференциальное и матричное исчисление
Практика блока
Свой автоград с нуля, MLP на нём и численная проверка градиентов
Блок закрывается кодом, и здесь он важнее обычного: автоград — единственный способ убедиться, что правило цепочки понято, а не прочитано.
1. micrograd: автоград скаляров
Задача: класс Value, хранящий число, ссылки на родителей и локальную производную.
Минимальный интерфейс — три вещи:
- Прямой проход через перегруженные операторы:
+,*,tanh,exp,**. Каждая операция создаёт новыйValue, запоминая, из кого он получен. - Топологическая сортировка графа от выхода к входам.
- Обратный проход:
gradвыхода равен единице, дальше каждый узел добавляетupstream * localк градиентам родителей.
Три места, где ошибаются, и все три уже встречались в блоке:
+=, а не=. Узел, использованный дважды, получает вклад по каждому пути. Урок про правило цепочки, диамант.- порядок обхода. Узел обрабатывается только после всех своих потребителей — обратный топологический порядок, иначе градиент утечёт недосчитанным.
- ReLU в нуле. Возвращайте ноль и знайте, что это соглашение, а не производная.
Ниже тот же граф, что вы соберёте руками. Пройдите обратный проход по шагам и сверьте со своим кодом узел за узлом — это самый быстрый способ найти расхождение:
2. MLP на своём автограде
Соберите слой из Value, сеть из слоёв, обучите на игрушечной задаче — например
на четырёх точках XOR или на предсказании знака. Нужно ровно это:
- forward: , ;
- лосс: квадратичный или кросс-энтропия;
- шаг:
p.data -= lr * p.gradпо всем параметрам; - обнуление градиентов перед каждым шагом. Забытое
zero_grad— та же ошибка накопления, только между итерациями. Лосс при этом обычно не падает, а разлетается.
Цель не в качестве модели, а в том, чтобы лосс убывал и вы понимали, почему.
3. Backprop на бумаге и сверка с кодом
Возьмите двухслойную сеть и выпишите градиенты вручную, пользуясь формулами из урока про матричное дифференцирование:
Знак — поэлементное умножение, и оно здесь не случайно: якобиан диагонален, а VJP с диагональной матрицей это и есть поэлементное умножение. Тот самый случай из урока про VJP, где сборка матрицы была бы расточительством.
Сверьте эти формулы с тем, что выдал ваш автоград. Совпадение — хороший знак; но надёжнее следующий пункт.
4. Численная проверка градиентов
Единственный способ убедиться, что автоград верен, — сравнить с центральной разностью:
Практические детали, без которых проверка врёт:
- для двойной точности. Меньше — теряются значащие цифры в разности, больше — растёт ошибка аппроксимации. Мы считали это в первом уроке.
- сравнивайте относительную ошибку , а не абсолютную: у больших градиентов абсолютная разница велика сама по себе.
- порог: относительная ошибка ниже — почти наверняка верно, выше — почти наверняка ошибка.
- ReLU проверять не стоит около нуля: там производной нет, и численная разность
честно покажет расхождение, которое не является ошибкой. Проверяйте на
tanh.
Именно эту проверку и реализуете в задаче ниже — на сети, которая целиком считается руками.
Экзамен блока
Прочитайте раздел с методом в статье про Adam (Kingma, Ba). К этому моменту в формулах не должно остаться незнакомого: градиент, экспоненциальные средние, поправка на смещение. Оптимизация как таковая — блок 5, но читаться формулы должны уже сейчас.
Источники
- Karpathy — micrograd — Автодифференцирование скаляров в сотне строк
- Karpathy — Neural Networks Zero to Hero, лекция 1 — Пошаговый разбор micrograd и обучения MLP
Проверки
0 из 2Как проверять градиенты
Вы написали автоград и хотите убедиться, что он верен. Отметьте все верные утверждения о численной проверке.
Обратный проход двухслойной сети
Реализуйте
mlp_backward(w1, b1, w2, b2, x, y)для сети с одним скрытым нейроном:Верните список
[L, dL/dw1, dL/db1, dL/dw2, dL/db2].Выведите обратный проход сами, звено за звеном:
Множитель — производная , выраженная через уже посчитанное значение. Это то самое вычислительное удобство из урока про активации.
Написав код, обязательно сверьте его с центральной разностью по каждому из четырёх параметров — именно так проверяются настоящие реализации.
Загрузка редактора…
Ctrl/⌘ + Enter