ONNX Runtime Web (ORT Web) предоставляет мощные средства для работы с моделями машинного обучения непосредственно в браузере или в среде Node.js. После выполнения инференса одной из ключевых задач является корректная обработка возвращаемых результатов, представленных в виде тензоров.
Метод session.run(feeds) возвращает объект, где ключи
соответствуют именам выходных узлов модели, а значения — тензоры,
представленные экземплярами Tensor. Основные свойства этих
объектов:
data — одномерный массив значений
тензора, тип зависит от данных модели (Float32Array,
Int32Array и т.д.).dims — массив чисел, задающий форму
(размерности) тензора.type — тип данных элементов тензора
(float32, int32, bool и
др.).Пример структуры тензора:
{
data: Float32Array(6) [0.1, 0.9, 0.2, 0.8, 0.5, 0.5],
dims: [2, 3],
type: 'float32'
}
Тензор всегда возвращается в виде одномерного массива. Для удобной
работы часто требуется преобразовать его в многомерный массив,
соответствующий форме dims. Для этого используется
рекурсивная функция преобразования:
function reshape(data, dims) {
if (dims.length === 0) return data[0];
const size = dims[0];
const rest = dims.slice(1);
const step = data.length / size;
const result = [];
for (let i = 0; i < size; i++) {
result.push(reshape(data.slice(i * step, (i + 1) * step), rest));
}
return result;
}
// Использование:
const outputTensor = result['output_name'];
const outputArray = reshape(outputTensor.data, outputTensor.dims);
Модели ONNX могут иметь несколько выходов. В этом случае
session.run возвращает объект, где каждый ключ — имя
выходного узла. Для удобного доступа можно использовать
деструктуризацию:
const { output1, output2 } = await session.run({ input: inputTensor });
const array1 = reshape(output1.data, output1.dims);
const array2 = reshape(output2.data, output2.dims);
Такой подход позволяет сразу получить доступ к каждому выходу без дополнительных обращений к объекту.
Для крупных моделей или потоковой инференции может потребоваться
асинхронная обработка данных. Несмотря на то, что
session.run сам по себе асинхронен, дополнительная
оптимизация возможна с использованием Web Workers или
requestIdleCallback для выполнения преобразования больших
тензоров в фоне, не блокируя UI.
function processTensorAsync(tensor) {
return new Promise((resolve) => {
requestIdleCallback(() => {
resolve(reshape(tensor.data, tensor.dims));
});
});
}
const processedOutput = await processTensorAsync(result['output_name']);
После извлечения данных тензора часто требуется их нормализация или отображение. Например, для изображений данные обычно преобразуются в диапазон [0, 255]:
const normalized = outputArray.map(row => row.map(value => Math.round(value * 255)));
Для текстовых моделей или классификаторов данные могут быть
дополнительно интерпретированы с помощью функций argmax или
сортировки вероятностей:
function argmax(array) {
return array.reduce((maxIndex, value, index, arr) => value > arr[maxIndex] ? index : maxIndex, 0);
}
const predictedClass = argmax(outputArray[0]);
Тип данных тензора напрямую влияет на способы обработки:
float32 — подходит для математических вычислений,
нормализации, визуализации.int32 — чаще используется для индексов классов или
категорий.bool — преобразуется в логические значения для масок
или условий.string — встречается в NLP-моделях, требует
конкатенации и декодирования в текст.Важно проверять свойство type перед обработкой, чтобы
избежать некорректного преобразования.
При работе с большими моделями рекомендуется повторно использовать
тензоры и массивы, вместо создания новых копий. Например, можно работать
с TypedArray напрямую для суммирования, усреднения или
других операций:
const data = outputTensor.data;
let sum = 0;
for (let i = 0; i < data.length; i++) {
sum += data[i];
}
const mean = sum / data.length;
Это позволяет минимизировать расходы памяти и ускоряет постобработку.
Для графиков, гистограмм или изображений данные из ONNX Runtime Web
удобно передавать в популярные JavaScript-библиотеки
(Chart.js, D3.js, Three.js,
Canvas). Перед этим массивы тензоров нужно адаптировать под
формат, который ожидает библиотека: двумерные массивы, плоские массивы
RGB или последовательности чисел.