Создание тензора из обычного Array и вложенных массивов

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

Импорт и инициализация ORT Web

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

import * as ort from 'onnxruntime-web';

// Инициализация сессии модели
const session = await ort.InferenceSession.create('model.onnx');

Здесь создается объект InferenceSession, через который будет выполняться инференс. Важной частью является подготовка входных данных в формате тензоров.

Создание тензора из одномерного массива

Одномерный массив JavaScript можно легко преобразовать в тензор с помощью класса ort.Tensor. Например:

const inputArray = [1.0, 2.0, 3.0, 4.0];
const tensor = new ort.Tensor('float32', Float32Array.from(inputArray), [4]);

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

  • Первый аргумент 'float32' указывает тип данных элементов тензора. ORT Web поддерживает 'float32', 'int32', 'bool' и 'string'.
  • Второй аргумент — это плоский массив значений. В случае работы с многомерными данными важно, чтобы массив был одномерным (Float32Array, Int32Array).
  • Третий аргумент — форма (shape) тензора, определяемая массивом чисел, каждое из которых соответствует размерности соответствующего измерения.

Преобразование вложенных массивов в тензор

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

const nestedArray = [
  [1, 2, 3],
  [4, 5, 6]
];

// Выравнивание массива в один плоский массив
const flatArray = nestedArray.flat();
const tensor2D = new ort.Tensor('float32', Float32Array.from(flatArray), [2, 3]);

Особенности:

  • Метод flat() позволяет преобразовать вложенный массив в одномерный массив. Для глубоко вложенных массивов можно использовать nestedArray.flat(Infinity).
  • Форма [2, 3] указывает, что тензор имеет 2 строки и 3 столбца. Количество элементов в плоском массиве должно строго соответствовать произведению размеров формы.

Автоматическая проверка согласованности формы

При создании тензора важно, чтобы вложенные массивы были регулярными, то есть каждая вложенная структура имела одинаковую длину. Несоответствие размеров приведет к ошибкам на этапе инициализации:

const invalidNestedArray = [
  [1, 2],
  [3, 4, 5]
];

// Попытка создания тензора приведет к ошибке
// const tensorInvalid = new ort.Tensor('float32', Float32Array.from(invalidNestedArray.flat()), [2, 3]);

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

Создание тензора из TypedArray напрямую

Для производительности часто используется прямое создание тензора из Float32Array, Int32Array или Uint8Array, особенно при работе с изображениями или большими массивами данных:

const width = 28;
const height = 28;
const channels = 1;

const imageData = new Float32Array(width * height * channels);
// Заполнение массива данными
for (let i = 0; i < imageData.length; i++) {
  imageData[i] = Math.random();
}

const imageTensor = new ort.Tensor('float32', imageData, [1, channels, height, width]);

Такой подход минимизирует накладные расходы на преобразование массивов и подходит для работы с потоковыми данными.

Работа с динамическими массивами

При динамическом формировании данных удобно использовать вложенные массивы и функцию flat() для преобразования:

const dynamicArray = [];
for (let i = 0; i < 5; i++) {
  const row = [];
  for (let j = 0; j < 10; j++) {
    row.push(Math.random());
  }
  dynamicArray.push(row);
}

const dynamicTensor = new ort.Tensor(
  'float32',
  Float32Array.from(dynamicArray.flat()),
  [5, 10]
);

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

Резюме принципов

  • Тензор всегда создается из плоского массива значений и формы.
  • Тип данных должен соответствовать допустимым типам ORT Web.
  • Вложенные массивы должны быть регулярными для корректного вычисления формы.
  • TypedArray обеспечивает максимальную производительность при больших данных.

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