Маленькие правила вместо одной огромной формулы
Для c=a+b локальные производные по обоим операндам равны1. Для c=ab они равны b и a. Для c=tanh(a) derivative равна1−c². Для ReLU используется1 приa>0,0 приa<0; в0 выбран0 как соглашение, а не классическая производная.
В L=z*z каждый из двух входов mul имеет local derivative z=7. Это два ребра к одному узлу; суммарный эффект14. Если превратить operands в set и передать вклад только один раз, gradient будет вдвое меньше.
Черта обозначает derivative выбранного output L по узлу, не его forward value. Incoming gradient масштабирует local derivative, затем contribution добавляется к уже накопленному результату.
Эксперимент. Выберите шаг mul и сопоставьте operand, local derivative, incoming gradient и contribution. У add local derivative1 не означает, что gradient его родителя обязательно1: учитывается вся цепочка после этого узла.
Легко ошибиться. Удобный визуализатор не может подставлять одинаковую derivative1 для всех типов операций. Любой новый примитив требует своего локального правила и проверки численной разностью.