Feature extraction без переобучения

Извлечение признаков (feature extraction) — процесс использования предварительно обученной нейронной сети для получения информативных представлений данных, которые затем могут быть использованы в новых задачах машинного обучения. В контексте TensorFlow.js это позволяет применять мощные модели прямо в браузере или на сервере без необходимости обучения с нуля и риска переобучения.

Предварительно обученные модели

TensorFlow.js предоставляет доступ к множеству предварительно обученных моделей через @tensorflow-models. Наиболее часто используемые модели для извлечения признаков:

  • MobileNet — компактная CNN для распознавания изображений, подходит для работы на веб-устройствах с ограниченными ресурсами.
  • Inception — более сложная сеть, обеспечивающая высокую точность для классификации и извлечения признаков.
  • Coco-SSD и PoseNet — специализированные модели для обнаружения объектов и анализа поз.

Ключевой аспект: эти модели обучены на больших наборах данных (например, ImageNet), что позволяет использовать их слои для генерации признаков без дополнительного обучения.

Подключение и загрузка модели

Для использования MobileNet в браузере:

import * as tf from '@tensorflow/tfjs';
import * as mobilenet from '@tensorflow-models/mobilenet';

async function loadModel() {
  const model = await mobilenet.load({ version: 2, alpha: 1.0 });
  return model;
}
  • version — выбирает архитектуру модели (1 или 2).
  • alpha — коэффициент ширины сети, влияющий на точность и скорость.

Генерация признаков

Главная цель — получить вектор признаков изображения, который можно использовать для дальнейшей классификации или кластеризации. В TensorFlow.js это делается через метод infer:

async function extractFeatures(model, imageElement) {
  // Получение вектора признаков без последнего слоя классификации
  const features = model.infer(imageElement, 'conv_preds');
  return features;
}

Параметр 'conv_preds' указывает, что нужно использовать выход перед слоем классификации, что исключает влияние конкретных классов на признаки.

Работа с батчами изображений

Для эффективной обработки нескольких изображений можно использовать tf.stack и tf.tidy:

function batchExtract(images, model) {
  return tf.tidy(() => {
    const tensors = images.map(img => tf.browser.fromPixels(img).toFloat().div(255));
    const batch = tf.stack(tensors);
    return model.infer(batch, 'conv_preds');
  });
}
  • tf.tidy автоматически очищает промежуточные тензоры, снижая нагрузку на память.
  • Нормализация изображений (div(255)) необходима для корректной работы модели.

Использование признаков для классификации

После извлечения признаков можно использовать любой простой классификатор, например, tf.Sequential с плотными слоями:

const classifier = tf.sequential();
classifier.add(tf.layers.dense({ inputShape: [1024], units: 128, activation: 'relu' }));
classifier.add(tf.layers.dense({ units: 10, activation: 'softmax' }));

classifier.compile({
  optimizer: tf.train.adam(),
  loss: 'categoricalCrossentropy',
  metrics: ['accuracy']
});
  • Входной слой получает размерность вектора признаков (1024 для MobileNet v2).
  • Модель может быть обучена на небольшом наборе данных без риска переобучения на исходную задачу.

Сохранение и повторное использование признаков

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

async function saveFeatures(features, key) {
  const data = await features.array();
  localStorage.setItem(key, JSON.stringify(data));
}

async function loadFeatures(key) {
  const data = JSON.parse(localStorage.getItem(key));
  return tf.tensor(data);
}

Это позволяет повторно использовать признаки без повторного обращения к модели.

Практические советы

  • Использовать model.infer вместо model.predict при необходимости только признаков, чтобы исключить последний классификационный слой.
  • Обрабатывать изображения в одинаковом формате и размере, соответствующем требованиям модели (например, 224x224 для MobileNet).
  • Применять tf.tidy или dispose() для предотвращения утечек памяти в браузере.
  • Минимизировать обучение новых слоев, чтобы сохранить преимущества предварительно обученной модели и избежать переобучения.

Расширенные техники

  • Пуллинг признаков: можно дополнительно применять глобальный средний или максимальный пуллинг к выходу модели для уменьшения размерности.
  • Аугментация данных: при использовании небольших наборов изображений аугментация (повороты, отражения, масштабирование) помогает улучшить обобщающую способность классификатора.
  • Сравнение признаков: вектор признаков можно использовать для поиска похожих изображений методом косинусного сходства или кластеризации через K-Means.

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