Юнит-тестирование в контексте TensorFlow.js предполагает проверку корректности работы отдельных компонентов кода, связанных с тензорными операциями, вычислительными графами и моделями. Основная цель — убедиться, что функции корректно обрабатывают входные данные, возвращают ожидаемые результаты и устойчивы к различным граничным условиям.
Для тестирования тензорных операций чаще всего используются фреймворки типа Jest или Mocha. Они позволяют изолировать функции и проверять их поведение без необходимости запуска полного приложения. Важно настроить среду так, чтобы:
tf.nextFrame().Пример подключения TensorFlow.js в тестах:
const tf = require('@tensorflow/tfjs-node');
Использование tfjs-node вместо браузерного варианта
ускоряет вычисления за счёт нативного бэкенда.
Тензорные операции требуют аккуратного подхода при сравнении
результатов. Прямое сравнение массивов JavaScript может быть ненадёжным
из-за особенностей представления чисел с плавающей запятой. Для этого
применяются методы tf.equal,
tf.all или специальные функции сравнения с
допуском:
function tensorsClose(a, b, epsilon = 1e-5) {
return tf.tidy(() => {
const diff = tf.abs(tf.sub(a, b));
return diff.max().arraySync() < epsilon;
});
}
Функция tensorsClose позволяет проверять, что два
тензора близки друг к другу с заданной точностью, предотвращая ложные
отрицательные результаты при сравнении чисел с плавающей точкой.
Каждую тензорную операцию рекомендуется тестировать отдельно. Основные категории проверок:
Корректность вычислений Проверка, что операция
возвращает ожидаемый результат для конкретных входных данных. Пример для
операции tf.add:
test('tf.add правильно складывает два тензора', () => {
const a = tf.tensor([1, 2, 3]);
const b = tf.tensor([4, 5, 6]);
const expected = tf.tensor([5, 7, 9]);
expect(tensorsClose(tf.add(a, b), expected)).toBe(true);
});Обработка неправильных форматов Проверка, что функция выбрасывает ошибки при несоответствии формы тензоров:
test('tf.add выбрасывает ошибку при несовпадении форм', () => {
const a = tf.tensor([1, 2, 3]);
const b = tf.tensor([[1, 2, 3]]);
expect(() => tf.add(a, b)).toThrow();
});Проверка границ и особых случаев Тестирование операций на пустых тензорах, NaN, Infinity и экстремальных значениях:
test('tf.mul корректно обрабатывает нулевые элементы', () => {
const a = tf.tensor([0, 1, 2]);
const b = tf.tensor([10, 10, 10]);
const expected = tf.tensor([0, 10, 20]);
expect(tensorsClose(tf.mul(a, b), expected)).toBe(true);
});TensorFlow.js использует граф вычислений с управлением памятью через
систему tf.tidy. Юнит-тесты должны включать вызовы
tf.tidy, чтобы предотвращать утечки памяти при массовом
создании тензоров:
test('tf.sub не вызывает утечку памяти', () => {
tf.tidy(() => {
const a = tf.tensor([5, 6]);
const b = tf.tensor([2, 3]);
const result = tf.sub(a, b);
expect(result.shape).toEqual([2]);
});
});
Некоторые методы, особенно связанные с загрузкой моделей или
использованием WebGL, являются асинхронными. Тестирование таких функций
требует использования async/await:
test('асинхронная загрузка модели возвращает корректный объект', async () => {
const model = await tf.loadLayersModel('file://path/to/model.json');
expect(model.inputs.length).toBeGreaterThan(0);
});
При создании собственных слоёв или функций активации следует разрабатывать отдельные тесты для:
tf.grads или
tf.valueAndGradients.Пример тестирования пользовательской функции активации:
function customRelu(x) {
return tf.tidy(() => tf.maximum(0, x));
}
test('customRelu корректно работает', () => {
const x = tf.tensor([-1, 0, 2]);
const expected = tf.tensor([0, 0, 2]);
expect(tensorsClose(customRelu(x), expected)).toBe(true);
});
Юнит-тестирование тензорных операций важно интегрировать с непрерывной интеграцией. Это гарантирует, что изменения в коде библиотеки или модели не нарушают корректность вычислений и позволяют автоматически проверять производительность операций.
cpu,
webgl, wasm) обеспечивает переносимость.tf.tidy для всех промежуточных
вычислений.async/await.Эти практики создают надежную базу для разработки и поддержки приложений на TensorFlow.js, где точность и предсказуемость тензорных операций критически важны.