Загрузка изображений в тензоры

Работа с изображениями является одной из ключевых задач при использовании TensorFlow.js. Для большинства моделей глубокого обучения входными данными являются тензоры, представляющие изображение в числовом виде. Понимание процесса преобразования изображений в тензоры позволяет эффективно интегрировать визуальные данные в модели машинного обучения на JavaScript.

Форматы изображений и их представление

Изображения могут быть представлены в различных форматах: PNG, JPEG, GIF и других. Для обработки в TensorFlow.js изображения необходимо представить в виде тензоров rank-3 (для цветных изображений) или rank-2 (для градаций серого). Цветные изображения имеют форму [высота, ширина, каналы], где каналы обычно равны 3 (RGB) или 4 (RGBA). Градации серого требуют одного канала.

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

  • Тип данных: tf.tensor поддерживает типы float32, int32 и bool. Для изображений чаще всего используется float32 с нормализацией значений от 0 до 1.
  • Порядок каналов: TensorFlow.js ожидает формат [H, W, C] (высота, ширина, каналы), в отличие от некоторых библиотек, где используется [C, H, W].

Загрузка изображений из HTML-элементов

Основной способ работы с изображениями в браузере — через элементы <img>, <canvas> или <video>. TensorFlow.js предоставляет функцию tf.browser.fromPixels(), которая конвертирует изображение в тензор.

Пример:

const imgElement = document.getElementById('myImage');
const tensor = tf.browser.fromPixels(imgElement);
console.log(tensor.shape); // [высота, ширина, 3]

Особенности использования:

  • fromPixels() поддерживает объекты ImageData, HTMLImageElement, HTMLCanvasElement, HTMLVideoElement.
  • Созданный тензор имеет тип int32 по умолчанию. Для большинства моделей требуется преобразование к float32 и нормализация:
const normalized = tensor.toFloat().div(tf.scalar(255));
  • Можно изменять размер изображения через tf.image.resizeBilinear():
const resized = tf.image.resizeBilinear(normalized, [224, 224]);

Загрузка изображений из файлов

Для загрузки изображений с локальной файловой системы используется API FileReader. После чтения содержимого создаётся элемент Image:

const input = document.getElementById('fileInput');
input.addEventListener('change', (event) => {
  const file = event.target.files[0];
  const reader = new FileReader();
  
  reader.onl oad = () => {
    const img = new Image();
    img.src = reader.result;
    img.onl oad = () => {
      const tensor = tf.browser.fromPixels(img).toFloat().div(tf.scalar(255));
      console.log(tensor.shape);
    };
  };

  reader.readAsDataURL(file);
});

Преимущества такого подхода:

  • Позволяет работать с любыми локальными изображениями без сервера.
  • Совместим с веб-интерфейсами и drag-and-drop.

Использование пакета tfjs-node для серверной загрузки

Для Node.js существует модуль @tensorflow/tfjs-node, который позволяет работать с изображениями напрямую из файловой системы без HTML-элементов. Основные функции:

  • tf.node.decodeImage() — преобразует буфер изображения в тензор.
  • Поддерживаются форматы PNG, JPEG, BMP.

Пример:

const fs = require('fs');
const tf = require('@tensorflow/tfjs-node');

const imageBuffer = fs.readFileSync('image.jpg');
const tensor = tf.node.decodeImage(imageBuffer, 3).toFloat().div(tf.scalar(255));
console.log(tensor.shape); // [высота, ширина, 3]

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

  • Второй аргумент 3 указывает количество каналов (RGB).
  • Можно использовать tf.image.resizeBilinear() для масштабирования.
  • Поддержка tf.tensor позволяет интегрировать тензор в любые модели TensorFlow.js.

Преобразование тензоров для моделей

Модели глубокого обучения часто требуют конкретной формы тензора. Общие шаги подготовки изображения:

  1. Изменение размера:
const resized = tf.image.resizeBilinear(tensor, [224, 224]);
  1. Нормализация значений:
const normalized = resized.div(tf.scalar(255));
  1. Добавление батча:
const batched = normalized.expandDims(0); // [1, 224, 224, 3]

Эти действия обеспечивают корректный ввод для большинства предобученных моделей, включая MobileNet, ResNet и EfficientNet.

Пакет tf.data для работы с потоками изображений

Для обучения моделей на множестве изображений используется API tf.data. Основные возможности:

  • Создание потока из массива URL или файлов.
  • Автоматическая пакетная обработка и перемешивание данных.
  • Поддержка аугментации изображений.

Пример:

const imagePaths = ['img1.jpg', 'img2.jpg', 'img3.jpg'];
const ds = tf.data.generator(function* () {
  for (const path of imagePaths) {
    const imgBuffer = fs.readFileSync(path);
    const tensor = tf.node.decodeImage(imgBuffer, 3).toFloat().div(tf.scalar(255));
    yield tensor;
  }
}).batch(2);

ds.forEachAsync(batch => {
  console.log(batch.shape);
});

Советы по оптимизации

  • Для больших изображений лучше использовать tf.image.resizeBilinear() перед передачей в модель, чтобы уменьшить потребление памяти.
  • Использовать tf.tidy() для автоматического освобождения ненужных тензоров:
tf.tidy(() => {
  const tensor = tf.browser.fromPixels(img).toFloat().div(tf.scalar(255));
  const resized = tf.image.resizeBilinear(tensor, [224, 224]);
  // работа с resized
});
  • Для пакетной обработки данных применять tf.data или Promise.all() при загрузке множества изображений.

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