В работе с моделями машинного обучения на изображениях одной из ключевых операций является преобразование значений пикселей в диапазон, удобный для сети. В ONNX Runtime Web для JavaScript нормализация и денормализация выполняются на этапе подготовки входных данных и обработки выходных значений модели.
Модели глубокого обучения чувствительны к масштабу входных данных.
Изображения обычно представлены в формате Uint8Array или
ImageData с пикселями в диапазоне 0–255.
Перед подачей в сеть необходимо привести эти значения к диапазону, на
котором обучалась модель, например:
[0, 1] — простое масштабирование на 255.[-1, 1] — используется в моделях, обученных с
центрированными значениями.Нормализация ускоряет сходимость и уменьшает вероятность ошибок из-за переполнения или недостаточной точности.
Для работы с ONNX Runtime Web используется тип
ort.Tensor. Пример создания тензора из изображения с
нормализацией:
import * as ort from 'onnxruntime-web';
// Предположим, imageData — объект ImageData с width, height и data
const { width, height, data } = imageData;
// Преобразуем Uint8Array в Float32Array и нормализуем
const floatData = new Float32Array(width * height * 3);
for (let i = 0; i < width * height; i++) {
floatData[i * 3] = data[i * 4] / 255; // R
floatData[i * 3 + 1] = data[i * 4 + 1] / 255; // G
floatData[i * 3 + 2] = data[i * 4 + 2] / 255; // B
}
// Создание тензора в формате [1, 3, height, width]
const inputTensor = new ort.Tensor('float32', floatData, [1, 3, height, width]);
Ключевые моменты:
i * 4 используется, так как
ImageData.data содержит альфа-канал (RGBA).[batch, channel, height, width], как ожидают большинство
ONNX-моделей для CV.[0,1].Некоторые модели требуют центрации относительно среднего значения и масштабирования на стандартное отклонение:
const mean = [0.485, 0.456, 0.406];
const std = [0.229, 0.224, 0.225];
for (let i = 0; i < width * height; i++) {
floatData[i * 3] = (data[i * 4] / 255 - mean[0]) / std[0];
floatData[i * 3 + 1] = (data[i * 4 + 1] / 255 - mean[1]) / std[1];
floatData[i * 3 + 2] = (data[i * 4 + 2] / 255 - mean[2]) / std[2];
}
Такое преобразование улучшает точность моделей, обученных на ImageNet, где значения каждого канала централизованы.
После обработки моделью результат часто возвращается в том же
диапазоне, что и вход (например, [0,1] или центрированный).
Для визуализации или сохранения изображения необходимо обратное
преобразование:
const outputData = modelOutput.data; // Float32Array из тензора [1, 3, height, width]
const denormalized = new Uint8ClampedArray(width * height * 4);
for (let i = 0; i < width * height; i++) {
denormalized[i * 4] = Math.min(255, Math.max(0, outputData[i * 3] * 255));
denormalized[i * 4 + 1] = Math.min(255, Math.max(0, outputData[i * 3 + 1] * 255));
denormalized[i * 4 + 2] = Math.min(255, Math.max(0, outputData[i * 3 + 2] * 255));
denormalized[i * 4 + 3] = 255; // альфа-канал
}
Особенности:
Math.min и Math.max
предотвращает выход за границы [0,255].Canvas или сохранения в
PNG необходим полный альфа-канал.ONNX Runtime Web поддерживает несколько вариантов исполнения
(webgl, wasm). При больших изображениях
нормализация и денормализация могут стать узким местом. Оптимизации:
Float32Array сразу при чтении
пикселей.Worker или
OffscreenCanvas для ускорения подготовки данных.ONNX Runtime Web позволяет использовать:
ImageData — стандарт для Canvas.HTMLImageElement — с предварительным копированием в
Canvas.TypedArray — Float32Array или
Uint8Array для прямой передачи.Для каждого типа требуется корректная нормализация. Наиболее
универсальный подход — всегда конвертировать в Float32Array
и формировать тензор [1, 3, height, width].
Нормализация и денормализация пикселей — базовые операции, определяющие корректность работы моделей компьютерного зрения в ONNX Runtime Web. Правильное масштабирование, центрирование и формирование тензоров позволяют получить точные прогнозы и корректно визуализировать результаты.