Цепное правило дифференцирования

TensorFlow.js предоставляет мощные инструменты для построения и обучения нейронных сетей прямо в JavaScript. Одним из ключевых компонентов автоматического дифференцирования является цепное правило, которое позволяет вычислять производные сложных функций, составленных из более простых операций.

Автоматическое дифференцирование в TensorFlow.js осуществляется через градиенты. Основной объект для работы с градиентами — функция tf.variable для параметров модели и метод tf.grad или tf.variableGrads для вычисления производных.


Принцип работы цепного правила

Цепное правило дифференцирования утверждает, что производная сложной функции, составленной из вложенных функций, вычисляется как произведение производных каждой из этих функций по цепочке:

[ = ]

В TensorFlow.js каждая операция на тензорах отслеживается в графе вычислений. Когда вызывается метод для вычисления градиента, библиотека автоматически проходит граф в обратном порядке (обратное распространение) и применяет цепное правило для каждой операции.

Пример базового применения:

const x = tf.variable(tf.scalar(2.0));

const f = x => x.square().mul(tf.scalar(3)); // f(x) = 3 * x^2

const gradFunc = tf.grad(f);

const gradValue = gradFunc(x);
gradValue.print(); // Вычисляет df/dx в точке x=2

В этом примере tf.grad создает функцию, которая возвращает производную f по x. Под капотом TensorFlow.js автоматически строит граф операций x -> x^2 -> 3*x^2 и применяет цепное правило: [ (3x^2) = 3 2x = 6x]


Работа с несколькими переменными

Для функций нескольких переменных используется tf.grads или tf.variableGrads. Пример:

const x = tf.variable(tf.scalar(1.0));
const y = tf.variable(tf.scalar(2.0));

const f = (x, y) => x.mul(y).add(y.square()); // f(x,y) = x*y + y^2

const grads = tf.grads(f);
const [dx, dy] = grads([x, y]);

dx.print(); // ∂f/∂x = y
dy.print(); // ∂f/∂y = x + 2*y

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


Автоматическое дифференцирование в обратном проходе

TensorFlow.js использует Reverse Mode Automatic Differentiation, что особенно эффективно для функций, где количество входных переменных больше, чем количество выходных (типично для нейронных сетей). В этом режиме градиенты вычисляются от конца графа к началу, что позволяет применять цепное правило последовательно для всех операций.

Пример с более сложной функцией:

const x = tf.variable(tf.scalar(2.0));

const f = x => tf.sin(x.square()).mul(tf.exp(x));

const gradFunc = tf.grad(f);
gradFunc(x).print();

Для функции f(x) = sin(x^2) * exp(x) библиотека автоматически делает следующее:

  1. Вычисляет u = x^2
  2. Вычисляет v = sin(u)
  3. Вычисляет w = exp(x)
  4. Итоговая функция f = v * w
  5. Градиент: (cos(u) * 2*x) * w + v * w — результат цепного правила

Применение в нейронных сетях

Цепное правило является фундаментом для обратного распространения ошибки (backpropagation). В TensorFlow.js оно применяется к любым слоям, будь то dense, conv или custom layers. Градиенты весов и смещений вычисляются автоматически, позволяя обновлять параметры через оптимизаторы:

const w = tf.variable(tf.randomNormal([2, 2]));
const b = tf.variable(tf.zeros([2]));

const x = tf.tensor([[1, 2]]);

const loss = () => x.matMul(w).add(b).square().mean();

const optimizer = tf.train.sgd(0.01);
optimizer.minimize(loss);

В этом коде метод optimizer.minimize автоматически:

  1. Строит граф вычислений функции потерь
  2. Вычисляет градиенты по w и b с помощью цепного правила
  3. Применяет обновление параметров по методу градиентного спуска

Выводы о цепном правиле в TensorFlow.js

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

Использование цепного правила в TensorFlow.js позволяет реализовывать сложные модели с минимальным количеством ручного кода для дифференцирования, полностью сосредоточившись на построении архитектуры и обучении.