Тензоры с нулевой размерностью и скалярные тензоры

ONNX Runtime Web предоставляет возможность работать с моделями, экспортированными в формат ONNX, прямо в браузере с использованием JavaScript. Особое внимание следует уделять работе с тензорами, поскольку они являются основной структурой данных для передачи информации между слоями модели. Одной из тонкостей является поддержка тензоров с нулевой размерностью и скалярных тензоров, которые часто вызывают вопросы у разработчиков.


Понимание тензоров с нулевой размерностью

Тензор с нулевой размерностью (0-D tensor) — это структура данных, у которой отсутствуют оси, то есть его shape равен []. Такой тензор фактически представляет собой одиночное скалярное значение.

Пример:

const ort = require('onnxruntime-web');

const scalarTensor = new ort.Tensor('float32', new Float32Array([3.14]), []);
console.log(scalarTensor.shape); // []
console.log(scalarTensor.data[0]); // 3.14

Ключевые моменты:

  • shape всегда пустой массив [].
  • data содержит единственное значение, обращение к которому происходит по индексу [0].
  • Часто используется для передачи одного числового значения в модель, например, вероятности или скалярного коэффициента.

Скалярные тензоры vs обычные массивы

Важно понимать различие между скалярным тензором и обычным массивом из одного элемента. Для ONNX Runtime Web:

  • Скалярный тензор с нулевой размерностью ([]) — это истинный скаляр, который модель воспринимает как одиночное значение без осей.
  • Массив с одним элементом ([1]) имеет одну ось с длиной 1, что интерпретируется моделью как одномерный тензор.

Пример различия:

// Скаляр
const scalar = new ort.Tensor('float32', new Float32Array([42]), []);

// Одномерный тензор
const vector = new ort.Tensor('float32', new Float32Array([42]), [1]);

console.log(scalar.shape); // []
console.log(vector.shape); // [1]

Это различие критично для корректной работы операций, таких как Add, Mul, ReduceSum и других, поскольку они по-разному обрабатывают скаляры и массивы с размерностью 1.


Создание и использование скалярного тензора

Скалярные тензоры создаются с использованием ort.Tensor с пустым массивом для shape. Важные аспекты:

  1. Тип данных — должен соответствовать типу входа модели (float32, int32 и т.д.).
  2. Доступ к значению — всегда через data[0].
  3. Совместимость с операциями — большинство бинарных и унарных операций поддерживают скаляры, позволяя автоматически распространять значение по другим тензорам (broadcasting).

Пример передачи скалярного значения в модель:

const inputTensor = new ort.Tensor('float32', new Float32Array([0.5]), []);
const session = await ort.InferenceSession.create('model.onnx');
const feeds = { 'input_name': inputTensor };
const results = await session.run(feeds);
console.log(results['output_name'].data[0]);

Broadcasting с нулевыми тензорами

ONNX Runtime Web поддерживает broadcasting, что позволяет скалярным тензорам автоматически расширяться до формы других тензоров при операциях:

const scalar = new ort.Tensor('float32', new Float32Array([2]), []);
const vector = new ort.Tensor('float32', new Float32Array([1, 2, 3]), [3]);

// Пример умножения скаляра на вектор
const session = await ort.InferenceSession.create('multiply_model.onnx');
const feeds = { 'scalar': scalar, 'vector': vector };
const results = await session.run(feeds);
console.log(results['output'].data); // [2, 4, 6]

Скаляр автоматически распространяется на весь вектор, что облегчает работу с одиночными коэффициентами.


Важные ограничения и особенности

  • Не все операции поддерживают скаляры в качестве входа. Некоторые специфические слои могут ожидать хотя бы одну размерность.
  • При экспорте моделей из PyTorch или TensorFlow важно проверять, что скаляры действительно конвертируются в тензоры с shape = [].
  • Ошибки часто возникают при прямом использовании number вместо скалярного тензора в feeds модели.

Отладка и проверка

Для проверки формы и содержимого тензора рекомендуется выводить следующие свойства:

console.log('Shape:', tensor.shape);
console.log('Data length:', tensor.data.length);
console.log('Value:', tensor.data[0]);

Это помогает убедиться, что передаваемое значение корректно интерпретируется моделью как скаляр, а не как массив с одной осью.


Работа с тензорами с нулевой размерностью в ONNX Runtime Web требует внимательного отношения к форме данных и типу тензора. Скалярные тензоры обеспечивают компактное и корректное представление одиночных значений, позволяя моделям выполнять вычисления с поддержкой broadcasting и минимизировать ошибки при передаче данных.