tf.variableGrads — это мощный инструмент для вычисления
градиентов в TensorFlow.js, который позволяет оптимизировать
произвольные функции, зависящие от переменных (объектов
tf.Variable). Он играет ключевую роль в построении и
обучении нейронных сетей, где требуется точное управление градиентами и
обновление весов моделей.
tf.variableGrads принимает функцию f,
которая возвращает скалярное значение (или объект, суммируемый до
скаляра) и вычисляет производные по всем переменным, используемым внутри
этой функции. В отличие от tf.grads, который работает с
тензорами, tf.variableGrads автоматически ищет только
переменные (tf.Variable) и возвращает градиенты по ним.
Пример базового синтаксиса:
const x = tf.variable(tf.tensor1d([1, 2, 3]));
const y = tf.variable(tf.tensor1d([0.5, 0.5, 0.5]));
const f = () => x.square().sum().add(y.square().sum());
const {value, grads} = tf.variableGrads(f);
console.log('Значение функции:', value.dataSync());
console.log('Градиенты по x:', grads[x.name].dataSync());
console.log('Градиенты по y:', grads[y.name].dataSync());
value — результат функции f.grads — объект, где ключи — имена переменных, а
значения — тензоры градиентов.tf.variableGrads удобно использовать, когда функция
зависит сразу от нескольких переменных:
const a = tf.variable(tf.tensor1d([1, 2]));
const b = tf.variable(tf.tensor1d([3, 4]));
const loss = () => a.square().sum().add(b.mul(a).sum());
const {value, grads} = tf.variableGrads(loss);
Здесь grads[a.name] и grads[b.name] будут
содержать градиенты функции по a и b
соответственно. Такой подход избавляет от необходимости вручную вызывать
grad для каждой переменной отдельно.
После вычисления градиентов можно обновлять переменные с использованием оптимизаторов:
const learningRate = 0.1;
const optimizer = tf.train.sgd(learningRate);
const step = () => {
const {value, grads} = tf.variableGrads(loss);
optimizer.applyGradients(grads);
return value;
};
for (let i = 0; i < 5; i++) {
const lossValue = step();
console.log(`Шаг ${i + 1}, значение функции:`, lossValue.dataSync());
}
applyGradients принимает объект grads, где
ключи — переменные, а значения — тензоры градиентов.tf.variableGrads создает новые тензоры градиентов,
которые необходимо правильно утилизировать, чтобы избежать утечек
памяти:
tf.tidy оборачивает вычисления в
замкнутую область видимости:tf.tidy(() => {
const {value, grads} = tf.variableGrads(loss);
optimizer.applyGradients(grads);
});
tf.Variable), которые хранятся
постоянно.tf.variableGrads корректно работает с функциями,
содержащими условные операторы или циклы:
const z = tf.variable(tf.tensor1d([1, -1, 2]));
const complexLoss = () => tf.tidy(() => {
const positive = z.relu().sum();
const negative = z.neg().relu().sum();
return positive.add(negative);
});
const {value, grads} = tf.variableGrads(complexLoss);
Градиенты вычисляются корректно по всем переменным, даже если внутри функции есть ветвления.
tf.variableGrads особенно полезен для кастомных слоев и
функций потерь:
tf.train.* оптимизаторами для
итеративного обновления переменных.Пример пользовательского слоя:
const weights = tf.variable(tf.randomNormal([2, 2]));
const bias = tf.variable(tf.zeros([2]));
const forward = (input) => input.matMul(weights).add(bias).relu();
const customLoss = (input, target) => {
const predictions = forward(input);
return predictions.sub(target).square().mean();
};
const input = tf.tensor2d([[1, 2]]);
const target = tf.tensor2d([[0.5, 1]]);
const {value, grads} = tf.variableGrads(() => customLoss(input, target));
optimizer.applyGradients(grads);
tf.variableGrads лучше всего подходит для небольших
функций или кастомных потерь, где градиенты по всем переменным нужны
одновременно.model.fit эффективнее, так как оптимизация встроена.tf.tidy предотвращает накопление
ненужных тензоров.tf.variableGradstf.Variable.tf.variableGrads обеспечивает гибкий инструмент для
прямого взаимодействия с градиентами переменных, открывая возможности
для точного контроля обучения и экспериментов с нейронными сетями в
браузере и Node.js.