Вывод dL/dz: откуда берётся dz = a − y

Формула dz=a−y — предсказание минус правильный ответ — выглядит слишком простой для того, что она делает: это весь сигнал ошибки, с которого начинается обратный ход логистической регрессии. Она не взята с потолка и не подогнана под ответ — она получается честным применением цепного правила из школьного анализа. Эта статья проходит вывод шаг за шагом, с алгеброй на виду, и проверяет каждое число в Python.

Что нужно вывести и зачем

Логистическая регрессия предсказывает число a=σ(z), где z=wTx+b — взвешенная сумма входов, а σ — сигмоида, сжимающая любое число в диапазон от 0 до 1. Правильный ответ — y, либо 0, либо 1. Штраф (loss) за ошибку одного предсказания (a) — кросс-энтропия (L) (почти ноль при уверенном правильном ответе, огромное число при уверенной ошибке; откуда именно берётся такая форма формулы — в «Функции стоимости»):

L=−[ylog⁡a+(1−y)log⁡(1−a)]

Чтобы обучать модель градиентным спуском, нужно знать, как L реагирует на изменение z — то есть производную dLdz. Она нужна именно по z, а не сразу по весам (w), потому что z — это точка, где сходятся все веса (w) и признаки (x), а дальше от dz до градиентов по каждому весу (w) — один короткий шаг (dw=x⋅dz, разобрано в статье «Градиентный спуск для логистической регрессии»).

Прямая цепочка вычислений — z→a→L: сначала z через сигмоиду (σ) превращается в a, потом a через кросс-энтропию превращается в L. Между z и L нет прямой связи — только через посредника a. Именно для такой цепочки и существует цепное правило: производная конца цепочки по началу равна произведению производных на каждом звене.

dLdz=dLda⋅dadz

Разберём каждый из двух множителей по отдельности, а потом перемножим.

Если можешь пересказать: нужна dL/dz; цепочка z→a→L не прямая, идёт через a, значит по цепному правилу dL/dz=dL/da⋅da/dz, — двигаемся дальше.

Шаг 1: производная ошибки по a

Кросс-энтропия склеивает два случая одной формулой, потому что y всегда либо 0, либо 1 — одно из двух слагаемых всегда обнуляется. Разберём каждый случай отдельно.

При y=1 второе слагаемое (1−y)log⁡(1−a)=0⋅log⁡(1−a) пропадает целиком, и остаётся:

L=−log⁡a

Производная логарифма — школьное правило: ddalog⁡a=1a. С минусом впереди:

dLda=−1a

При y=0 пропадает первое слагаемое, остаётся:

L=−log⁡(1−a)

Здесь берём производную сложной функции: внутри — (1−a), снаружи — логарифм. Производная внутренней части (1−a) по a равна −1 (потому что перед a стоит минус). Правило цепочки для этого случая: производная log⁡(1−a) по a — это 11−a, умноженное на производную внутренней части −1, то есть −11−a. А снаружи ещё один минус (из L=−log⁡(1−a)), который переворачивает знак обратно:

dLda=−(−11−a)=11−a

Прежде чем читать дальше: при a, близком к 1 (модель почти уверена, что ответ — единица), а истинный y=0 — то есть модель уверенно ошиблась, — будет ли dLda=11−a большим числом или маленьким? Прикинь по формуле, а потом проверь: при a=0.99, 11−0.99=10.01=100 — очень большое число. Это забегание вперёд: сигнал ошибки уже здесь, на уровне производной по a, устроен так, чтобы кричать громко при уверенной ошибке. Увидим это ещё раз в конце статьи.

Если можешь пересказать: при y=1 производная ошибки по a равна −1/a, при y=0 равна 1/(1−a) — оба случая получены прямым дифференцированием логарифма, — листай дальше.

Шаг 2: производная сигмоиды (σ) по z

У сигмоиды (σ) необычно красивая производная — она выражается через саму сигмоиду (σ), без всяких экспонент снаружи:

dadz=a(1−a)

Откуда это берётся. Сигмоида по определению — σ(z)=(1+e−z)−1, то есть выражение в степени −1. Дифференцируем как степенную функцию (правило: производная u−1 равна −u−2⋅u′, где u=1+e−z, а u′=−e−z, потому что производная e−z по z даёт множитель −1):

dσdz=−(1+e−z)−2⋅(−e−z)=e−z(1+e−z)2

Дробь выглядит громоздко, но раскладывается на два знакомых множителя:

e−z(1+e−z)2=11+e−z⏟σ(z)⋅e−z1+e−z⏟1−σ(z)

Первый множитель — это прямо определение σ(z). Второй проверяется в одну строку алгебры: e−z1+e−z=(1+e−z)−11+e−z=1−11+e−z=1−σ(z). Значит:

dσdz=σ(z)(1−σ(z))=a(1−a)

Интуиция без формул: сигмоида (σ) растёт быстрее всего в середине графика (около z=0, где a=0.5) и почти не меняется на краях (где a близко к 0 или к 1, график почти плоский). Произведение a(1−a) в точности отражает это: при a=0.5 оно максимально (0.5⋅0.5=0.25), а при a близком к 0 или к 1 — почти ноль. Крутизна наклона сигмоиды (σ) и её собственное значение связаны напрямую — в этом и состоит удобство этой функции.

Проверим числом: при z=1.38 имеем a=0.799, формула даёт 0.799⋅0.201≈0.1606. Численная производная (посчитать σ при z=1.380001 и z=1.379999, взять разницу и поделить на шаг) тоже даёт 0.1606 — совпало.

Если можешь пересказать: производная сигмоиды (σ) — a(1−a), получена дифференцированием (1+e−z)−1 и разложением дроби на σ(z) и 1−σ(z); максимальна в середине, почти нулевая на краях, — листай дальше.

Шаг 3: перемножаем по цепному правилу

Теперь у нас есть оба множителя, остаётся перемножить их по формуле dLdz=dLda⋅dadz — отдельно для каждого случая y.

Случай y=1:

dLdz=(−1a)⋅a(1−a)=−(1−a)=a−1

Дробь 1a и множитель a из производной сигмоиды сокращаются один в один (это и есть «взаимное гашение», о котором говорится в конце статьи) — остаётся только −(1−a), что после раскрытия скобки равно a−1.

Случай y=0:

dLdz=11−a⋅a(1−a)=a

Здесь сокращается (1−a) в числителе и знаменателе, остаётся просто a.

Оба случая, записанные одной формулой: при y=1 ответ a−1, что равно a−y; при y=0 ответ a, что тоже равно a−y. Совпадение не случайное — это ровно то, ради чего формула проверяется на оба случая:

dz=a−y

Символьная проверка через Python (библиотека sympy умеет дифференцировать и упрощать алгебраические выражения автоматически) подтверждает вывод без единого приближения: если взять общую формулу кросс-энтропии L=−(ylog⁡a+(1−y)log⁡(1−a)) с a=σ(z) и честно продифференцировать по z через цепное правило, разность результата и (a−y) символьно упрощается ровно до нуля — то есть формулы тождественно совпадают, не только в частных случаях y=0 и y=1, а для любого y между ними тоже (хотя y на практике принимает только 0 или 1, формула работает как единая).

Финальная проверка на числах: z=1.38, a=0.799, y=1. Формула: dz=0.799−1=−0.201. Численная производная L по z (та же техника маленького шага, что и выше) тоже даёт −0.201. Совпало.

Если можешь пересказать: при y=1 дробь 1/a гасится множителем a из производной сигмоиды и остаётся a−1; при y=0 гасится (1−a) и остаётся a; оба случая — это a−y, — листай дальше.

Мини-проверка: пересчитай сам

Мини-задача: пусть a=0.01, y=1 — модель почти уверена в неправильном ответе. Чему равен dz по формуле dz=a−y? И чему равна производная сигмоиды a(1−a) в этой точке?

Ответ

dz=0.01−1=−0.99. А a(1−a)=0.01⋅0.99=0.0099 — маленькое число, потому что a далеко от середины сигмоиды (σ). Обрати внимание: несмотря на то что a(1−a) маленькое, итоговый dz=−0.99 остаётся большим — потому что при выводе через кросс-энтропию этот маленький множитель полностью сократился с 1/a. Это и есть смысл «взаимного гашения»: сигмоида (σ) сама по себе почти не меняется на краях, но комбинация с кросс-энтропией восстанавливает полный сигнал ошибки (dz).

Твоя очередь: возьми своё число a от 0.001 до 0.02 (тоже уверенная ошибка, y=1) и посчитай dz=a−y по той же формуле — оно почти не изменится, оставаясь близким к −1, сколько бы ты ни взял a в этом диапазоне.

Почему это не просто красивая алгебра: будильник ошибки

Представь будильник, который должен звенеть громче, чем сильнее ты не прав. У кросс-энтропии он работает исправно: даже когда модель уверенно ошиблась, сигнал ошибки dz=a−y остаётся громким — как мы только что увидели, −0.99 при a=0.01, почти максимально возможное значение.

Проверим это на альтернативе. Что если взять не кросс-энтропию, а квадрат разницы L=(a−y)2/2 — самый естественный на вид кандидат в функции ошибки (L)? Цепное правило работает точно так же, только dL/da теперь другое (dda(a−y)22=a−y, обычное дифференцирование степени), а множитель сигмоиды a(1−a) остаётся тем же самым, потому что он не зависит от выбора loss:

dLdz=(a−y)⋅a(1−a)

Здесь никакого сокращения не происходит — множитель a(1−a) остаётся стоять рядом, а не гасится, как в случае кросс-энтропии.

Прежде чем читать дальше: для квадрата разницы, когда модель уверенно ошиблась (например, a близко к 0, а y=1), будильник звенит громче или тише, чем у кросс-энтропии? Попробуй угадать по формуле выше, а потом проверь на числах.

Возьмём те же числа: a=0.01, y=1. Множитель ошибки: a−y=0.01−1=−0.99. Множитель сигмоиды: a(1−a)=0.01⋅0.99=0.0099. Перемножаем: dL/dz=−0.99⋅0.0099≈−0.0098 — почти ноль, хотя ошибка максимальная. Будильник почти сломан именно тогда, когда должен звенеть громче всего.

Сравним на числах из основного примера: z=1.38, a=0.799, y=1. Для квадрата разницы: dL/dz=−0.201⋅0.1606≈−0.0323 (проверено численной производной, совпадает). Для кросс-энтропии на тех же числах: dz=a−y=−0.201 — примерно в шесть раз больше по модулю (0.201/0.0323≈6.2).

Сила сигнала ошибки |dz| от предсказания a при y=1: кросс-энтропия убывает линейно от 1 до 0 и остаётся громкой около a=0 (≈0.99); квадрат разницы поднимается лишь до пика ≈0.15 и падает почти до нуля у обоих краёв, включая уверенную ошибку

Лишний множитель a(1−a) у квадрата разницы никуда не гасится — при уверенных предсказаниях (a близко к 0 или 1) он почти обнуляет будильник именно тогда, когда ошибка ещё велика. У кросс-энтропии этот множитель сокращается ровно потому, что dL/da у неё содержит 1/a или 1/(1−a) — дробь, специально устроенную так, чтобы отменить производную сигмоиды (σ). Это не совпадение: кросс-энтропию для сигмоиды (σ) выбирали именно из этого требования — чтобы сигнал ошибки (dz) не гас на уверенных, но неправильных предсказаниях.

Если можешь пересказать: у квадрата разницы множитель a(1−a) никуда не гасится, и на уверенных ошибках сигнал (dz) почти пропадает; у кросс-энтропии он сокращается и остаётся линейным a−y — поэтому она и выбрана в паре с сигмоидой (σ), — тема усвоена.

Что дальше

Формула dz=a−y — не трюк и не совпадение, а прямое следствие цепного правила: производная ошибки по a содержит дробь 1/a или 1/(1−a), производная сигмоиды (σ) по z содержит множитель a(1−a), и при перемножении дроби гасят друг друга, оставляя чистое вычитание. Символьная проверка подтверждает это без приближений.

С этим выводом на руках весь шаг обратного хода логистической регрессии больше не нужно принимать на веру — можно проследить его от первой производной до последнего числа. Как этот dz используется дальше — чтобы получить градиенты по каждому весу и обновить их, — разобрано в статье «Градиентный спуск для логистической регрессии».