Что такое производная: наклон, предел, цепное правило — интерактивно

Производная функции ff в точке xx — это число

f′(x)=lim⁡h→0f(x+h)−f(x)h.f'(x) = \lim_{h \to 0} \frac{f(x+h) - f(x)}{h}.

Словами: насколько быстро меняется выход на единицу изменения входа, если мерить так близко к xx, что значение имеет только локальное поведение ff.

У того же числа есть второе прочтение, и оно полезнее первого. При малых hh

f(x+h)≈f(x)+f′(x) h.f(x+h) \approx f(x) + f'(x)\,h .

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

Маршрут повторяет первую лекцию курса Андрея Карпаты Neural Networks: Zero to Hero, где построение нейросети с нуля начинается именно с производной. Каждая панель ниже живая: измените что-нибудь — и числа пересчитаются; ни одно из них не вписано вручную.

В лекции используется парабола 3x2−4x+53x^2 - 4x + 5. На этой странице вместо неё нарочно неровная кривая: её наклон меняет величину и знак от места к месту, и впадин, в которые можно скатиться, больше одной:

f(x)=3sin⁡(2.5x)+0.4x2−1.5x.f(x) = 3\sin(2.5x) + 0.4x^2 - 1.5x .

У одной точки нет наклона

Через одну точку кривой проходит бесконечно много прямых. Какая из них «имеет наклон кривой»?

Тащите точку по кривой и поворачивайте прямую за круглую ручку. Издалека подходящими выглядят многие прямые. Врезка показывает маленькое окно вокруг точки под лупой, и там разница видна: неверная прямая при любом увеличении продолжает пересекать кривую под углом, а одна прямая с кривой сливается. Эта прямая и есть касательная, а её наклон равен f′(x)f'(x).

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

Легенда измеряет то, что видно в лупе: зазор между кривой и прямой, делённый на расстояние от точки, при Δx=0.1\Delta x = 0.1, 0.010.01 и 0.0010.001. При x=3x = 3 горизонтальная прямая даёт 2.64, 3.42, 3.492.64,\ 3.42,\ 3.49 — отношение подбирается к 3.503.50 и там остаётся, и любой другой неверный наклон так же застревает на своей ошибке. Поверните прямую до наклона 3.53.5 — и те же три числа станут −0.86, −0.08, −0.01-0.86,\ -0.08,\ -0.01: в десять раз меньше при каждом десятикратном увеличении. Сдвиньте точку: наклон, который только что подходил, больше не подходит. Производная — не одно число на всю кривую, а новое число в каждой точке.

Почему прямая ровно одна? Разложим кривую в окрестности xx. Зазор между ней и прямой с наклоном mm в расчёте на единицу расстояния uu равен

f(x+u)−(f(x)+m u)u=(f′(x)−m)+12f′′(x) u+…\frac{f(x+u) - \bigl(f(x) + m\,u\bigr)}{u} = \bigl(f'(x) - m\bigr) + \tfrac12 f''(x)\,u + \dots

При уменьшении uu исчезает всё, кроме первого слагаемого. Любая ошибка наклона переживает увеличение; только m=f′(x)m = f'(x) позволяет отношению уйти в ноль. Именно это, а не «прямая, которая касается кривой в одной точке», и есть касательная: прямая может коснуться кривой один раз и всё равно её пересечь, а касательная может кривую пересекать (в точке перегиба так и происходит).

От секущей к касательной: предел

Одна точка наклона не даёт, поэтому возьмём вторую. Точки xx и x+hx+h задают прямую — секущую, и её наклон равен отношению катетов оранжевого треугольника:

Δfh=f(x+h)−f(x)h.\frac{\Delta f}{h} = \frac{f(x+h) - f(x)}{h}.

Это тангенс угла наклона секущей к горизонтали, tan⁡α\tan\alpha, — подъём, делённый на смещение.

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

Кривая с точкой x и второй точкой x + h, соединёнными секущей; при уменьшении h секущая поворачивается к пунктирной касательной, а при увеличении масштаба кривая становится неотличимой от прямой.

При x=3x = 3 истинный наклон равен f′(3)=3.4998f'(3) = 3.4998. Секущая приближается к нему шаг за шагом:

шаг hhнаклон секущей Δf/h\Delta f / hошибка
1−3.146-3.1466.6
0.12.6382.6380.86
0.013.4163.4160.084
0.0013.4913.4910.0084

При h=1h = 1 у секущей даже неверный знак: она перепрыгивает через гребень сразу за x=3x = 3. Каждое следующее уменьшение hh в десять раз уменьшает ошибку в десять раз.

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

Производная как функция

Раз у каждой точки свой наклон, производная сама является функцией: x↦f′(x)x \mapsto f'(x). Напрямую через предел её вычисляют редко. Достаточно нескольких правил, каждое из которых один раз доказывается из определения:

Вместе они дают tanh⁡x=e2x−1e2x+1\tanh x = \dfrac{e^{2x} - 1}{e^{2x} + 1} — активацию первого нейрона в лекции: по правилам (tanh⁡x)′=1−tanh⁡2x(\tanh x)' = 1 - \tanh^2 x. Этот наклон равен 11 в нуле и затухает к 00 с ростом ∣x∣|x|, поэтому нейрон, загнанный глубоко в насыщение, почти не учится: любой пришедший к нему градиент умножается почти на ноль.

Для нашей кривой цепное правило превращает sin⁡(2.5x)\sin(2.5x) в cos⁡(2.5x)⋅2.5\cos(2.5x) \cdot 2.5, а остальное дифференцируется почленно:

f′(x)=7.5cos⁡(2.5x)+0.8x−1.5.f'(x) = 7.5\cos(2.5x) + 0.8x - 1.5 .

Именно по этой формуле построены пунктирные касательные на этой странице.

Там, где f′(x)=0f'(x) = 0, касательная горизонтальна. На показанном отрезке это происходит 7 раз; где f′f' меняет знак с минуса на плюс, у кривой локальный минимум — самый глубокий при x≈1.885x \approx 1.885, где f≈−4.406f \approx -4.406, — а где с плюса на минус, локальный максимум.

Не у всякой функции производная есть всюду. У ∣x∣|x| наклон −1-1 слева от 00 и +1+1 справа; у секущей в 00 нет единого предела, поэтому ∣x∣|x| там не дифференцируема. У функции активации ReLU, max⁡(0,x)\max(0, x), такой же излом, и библиотеки для нейросетей просто договариваются использовать там 00.

Приблизьте излом и убедитесь сами. Панель проводит из точки две секущие, влево и вправо, и hh привязано к масштабу. На гладкой кривой приближение распрямляет картинку, и две секущие складываются в одну прямую. В изломе ∣x∣|x| картинка не меняется никогда: при любом увеличении это та же галочка, левая секущая остаётся на −1-1, правая — на +1+1. Единого числа, которым могла бы быть производная, просто нет.

Излом |x| под лупой: левая и правая секущие из x = 0 сохраняют наклоны −1 и +1 при любом увеличении, а на гладкой x² сливаются в одну прямую; для ReLU показан 0, который библиотеки берут в изломе.

Насколько малым брать h на компьютере?

В точной арифметике чем меньше hh, тем лучше. На компьютере — нет.

Наклон секущей (f(x+h)−f(x))/h\bigl(f(x+h) - f(x)\bigr)/h, прямая разность, вычитает два почти равных числа. 64-битное число с плавающей точкой хранит около 16 значащих цифр, поэтому разность теряет столько из них, сколько их общих у f(x+h)f(x+h) и f(x)f(x). Оставшаяся ошибка округления затем делится на крошечное hh.

Две ошибки тянут в противоположные стороны:

Их сумма минимальна около h≈ε≈1.5⋅10−8h \approx \sqrt{\varepsilon} \approx 1.5 \cdot 10^{-8}.

Центральная разность (f(x+h)−f(x−h))/2h\bigl(f(x+h) - f(x-h)\bigr)/2h берёт точки с обеих сторон. Слагаемые с f′′f'' сокращаются, её ошибка усечения имеет порядок h2h^2, а наилучшее hh сдвигается вверх, примерно к ε3≈6.1⋅10−6\sqrt[3]{\varepsilon} \approx 6.1 \cdot 10^{-6}.

Панель вычисляет обе формулы в обычной 64-битной арифметике и строит график их ошибки в зависимости от hh; ведите по графику, чтобы менять hh.

График в логарифмическом масштабе по обеим осям: ошибка прямой и центральной разностей для f при x = 3 в зависимости от h; обе ошибки падают с уменьшением h, пока не начинает преобладать округление и они снова не растут; минимум прямой разности — около h = 1e-8, центральной — около 1e-5.

Читайте график справа налево — так, как уменьшается hh. Сначала обе линии падают с наклонами 1 и 2: каждое уменьшение hh в десять раз делит ошибку прямой разности на 10, а центральной — на 100. Затем верх берёт округление, и обе линии поворачивают вверх, в шум.

При x=3x = 3 прямая разность точнее всего при h≈4⋅10−9h \approx 4 \cdot 10^{-9}, с ошибкой 1.3⋅10−81.3 \cdot 10^{-8}. Центральная разность достигает 3⋅10−113 \cdot 10^{-11} при h≈4⋅10−6h \approx 4 \cdot 10^{-6} — примерно в 450 раз точнее, при hh в 1000 раз больше.

При h=10−16h = 10^{-16} обе оценки равны ровно 00: ближайшее к 3+10−163 + 10^{-16} число с плавающей точкой — само 33, поэтому f(x+h)−f(x)=0f(x+h) - f(x) = 0.

Поэтому численные производные используют, чтобы проверять аналитические, — это «проверка градиента» центральной разностью с hh около 10−510^{-5}, — а не чтобы обучать сети: каждая оценка стоит дополнительных вычислений функции на каждый вход, а ответ верен лишь примерно до десяти знаков.

Цепное правило на вычислительном графе

Настоящие формулы — это композиции простых операций. Разобьём

L=(a⋅b+c)⋅sL = (a \cdot b + c) \cdot s

на шаги: e=a⋅be = a \cdot b, d=e+cd = e + c, L=d⋅sL = d \cdot s. Это вычислительный граф.

Прямой проход вычисляет значения слева направо. При a=2, b=−3, c=10, s=−2a = 2,\ b = -3,\ c = 10,\ s = -2: e=−6, d=4, L=−8e = -6,\ d = 4,\ L = -8.

Обратный проход отвечает на другой вопрос: насколько изменится LL, если чуть сдвинуть данный узел? Это производная ∂L/∂node\partial L / \partial \text{node}, которую называют градиентом узла. Значение узла и его градиент — разные числа.

Каждой операции достаточно знать собственную локальную производную:

Скорости вдоль цепочки перемножаются. Лекция берёт пример Джорджа Симмонса: если машина едет вдвое быстрее велосипеда, а велосипед вчетверо быстрее пешехода, то машина быстрее пешехода в 2⋅4=82 \cdot 4 = 8 раз. Цепное правило точно так же перемножает локальные производные вдоль пути:

∂L∂a=∂L∂d⋅∂d∂e⋅∂e∂a=s⋅1⋅b=(−2)⋅1⋅(−3)=6.\frac{\partial L}{\partial a} = \frac{\partial L}{\partial d} \cdot \frac{\partial d}{\partial e} \cdot \frac{\partial e}{\partial a} = s \cdot 1 \cdot b = (-2)\cdot 1 \cdot(-3) = 6 .

Двигайте ползунок обратного прохода: каждое деление обрабатывает одну операцию, справа налево, и подписывает каждое пройденное ребро его локальной производной. Затем потащите любой вход вбок.

Вычислительный граф L = (a·b + c)·s со значением и градиентом каждого узла; ползунок обратного прохода обрабатывает по одной операции, двигаясь от выхода к входам, и подписывает рёбра локальными производными, а перетаскивание входа сравнивает изменение L с предсказанием градиента.

Всё начинается с ∂L/∂L=1\partial L / \partial L = 1: сдвиг выхода на ε\varepsilon меняет его на ε\varepsilon. В конце ∂L/∂a=6, ∂L/∂b=−4, ∂L/∂c=−2, ∂L/∂s=4\partial L/\partial a = 6,\ \partial L/\partial b = -4,\ \partial L/\partial c = -2,\ \partial L/\partial s = 4, а перетаскивание проверяет их по старинке. Сдвиньте aa с 22 до 2.52.5 — и LL изменится на 33, ровно на ∂L/∂a⋅Δa=6⋅0.5\partial L/\partial a \cdot \Delta a = 6 \cdot 0.5. Градиент и есть это предсказание: насколько сдвигается выход на единицу сдвига входа. Здесь оно точное, потому что LL линейна по каждому входу в отдельности; для кривой функции оно верно только для малых сдвигов — в этом и состоит всё содержание формулы f(x+h)≈f(x)+f′(x) hf(x+h) \approx f(x) + f'(x)\,h.

Теперь сдвиньте все четыре входа сразу. «Шаг по градиенту» прибавляет к каждому входу 0.010.01 его собственного градиента, и LL растёт с −8.00-8.00 до −7.29-7.29. Градиент предсказывал рост на 0.01⋅(62+42+22+42)=0.720.01 \cdot (6^2 + 4^2 + 2^2 + 4^2) = 0.72; настоящий — 0.710.71. Разница — это произведения входов, a⋅ba \cdot b и e⋅se \cdot s, которые меняются одновременно и которых предсказание первого порядка не видит: LL линейна по каждому входу в отдельности, но не по всем сразу. Шаг против градиента, наоборот, уменьшил бы LL — и в этом всё обучение, как покажет последний раздел.

«—», пока проход не дошёл до узла, означает «ещё не вычислено», а это не то же самое, что ноль. Сдвиньте ss до 00 — и все градиенты левее станут нулевыми, хотя значение ни одного из этих узлов не равно нулю: когда последний множитель равен нулю, ничто выше по графу не может сдвинуть LL.

Это и есть обратное распространение ошибки (backpropagation). Один обратный проход даёт градиент единственного выхода по каждому узлу ценой небольшой константы, умноженной на стоимость прямого прохода. У сети одна функция потерь и миллионы параметров, и именно из-за этого соотношения её обучают назад, а не вперёд.

Одна переменная, несколько путей: градиенты складываются

А если значение используется больше одного раза? Возьмём

L=x⋅x+k⋅x.L = x \cdot x + k \cdot x .

Переменная xx входит в граф трижды: дважды как вход x⋅xx \cdot x и один раз в k⋅xk \cdot x. Каждое использование — отдельный путь к LL, и каждый путь возвращает свой вклад: xx с каждой стороны произведения и kk от второго слагаемого. Цепное правило для функций многих переменных говорит, что производная равна их сумме:

∂L∂x=x+x+k=2x+k.\frac{\partial L}{\partial x} = x + x + k = 2x + k .

Поэтому движок обратного распространения ошибки пишет grad += ..., а не grad = .... Вторая кнопка воспроизводит ошибку: каждый вклад затирает предыдущий, выживает только последний, и касательная, построенная по такому градиенту, проходит мимо кривой.

Граф L = x·x + k·x, где x доходит до L по трём путям и возвращает три вклада; рядом — кривая L(x) с касательной, построенной по накопленному градиенту; касательная проходит мимо кривой, если вклады перезаписываются, а не складываются.

Перетащите точку в x=−1.5x = -1.5 при k=3k = 3. Сумма равна нулю, и касательная горизонтальна, но ни один путь не исчез: −1.5−1.5+3=0-1.5 - 1.5 + 3 = 0. Вклады могут взаимно уничтожаться, и нулевой градиент не значит, что от xx ничего не зависит.

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

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

Зачем нужна производная: градиентный спуск

Знак f′(x)f'(x) говорит, в какую сторону ff растёт. Чтобы спускаться, нужно шагать в противоположную:

x←x−η f′(x).x \leftarrow x - \eta\, f'(x).

Размер шага η\eta называется скоростью обучения. Где склон крутой, шаг длинный; у минимума, где f′≈0f' \approx 0, — короткий, и спуск останавливается сам.

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

Из x=3x = 3 при η≈0.03\eta \approx 0.03 спуск за 20 шагов доходит до самой глубокой впадины, x≈1.885x \approx 1.885. Перетащите старт (или сдвиньте его ползунок) в x=3.3x = 3.3 — чуть дальше вершины в 3.1983.198 — и пунктирное превью покажет, как то же правило уводит точку в другую сторону, в более мелкую впадину в 4.2944.294. Производная — локальная информация: она знает, где низ здесь, но не знает, где лучшая впадина.

Теперь увеличьте η\eta. У минимума в 1.8851.885 кривизна равна f′′(1.885)≈19.5f''(1.885) \approx 19.5, и спуск сходится, только если η<2/f′′≈0.10\eta < 2/f'' \approx 0.10. Выше этого порога каждый шаг перелетает дальше, чем исправляет, и точка скачет между стенками впадины, вместо того чтобы остановиться.

Обучение нейросети — тот же самый цикл. xx превращается в миллионы весов, ff — в функцию потерь на обучающих данных, f′(x)f'(x) — в вектор градиента, а обратное распространение ошибки вычисляет его за один проход. Остальная часть лекции строит ровно это поверх крошечного движка из панелей выше.

Короткие ответы

Что такое производная одним предложением?

Производная f′(x) — это скорость, с которой f меняется на единицу изменения аргумента вблизи x, то есть наклон прямой, которая лучше всего приближает график в этой точке.

Почему касательная определяется через предел?

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

У любой ли функции есть производная?

Нет. У |x| в нуле излом: слева наклон −1, справа +1, поэтому у секущей нет единого предела. У ReLU, max(0, x), такой же излом; библиотеки для нейросетей просто выбирают там какое-то значение, обычно 0.

Чем производная отличается от градиента?

Производная — это скорость изменения функции одной переменной. Градиент собирает частные производные функции многих переменных, по одной на каждый аргумент, в вектор; он указывает направление наискорейшего роста.

Численное, символьное или автоматическое дифференцирование — что есть что?

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

Почему обратное распространение ошибки идёт в обратную сторону?

У сети одна функция потерь и миллионы параметров. Если идти назад от функции потерь, один проход по графу даёт производную этого единственного выхода по каждому входу — ценой небольшой константы, умноженной на стоимость прямого прохода. Движение вперёд потребовало бы по одному проходу на каждый параметр.

Почему при обратном распространении ошибки градиенты накапливаются через +=?

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

Литература