PyTorch Metric Learning: что нового

PyTorch Metric Learning претерпел множество изменений за последние несколько месяцев. Вот основные моменты.

Расстояния, редукторы и регуляризаторы

Функции потерь теперь легко настраиваются с введением расстояний, редукторов и регуляризаторов.

Расстояния

Рассмотрим TripletMarginLoss в его форме по умолчанию.

Эта функция потерь пытается минимизировать:

где «d» представляет расстояние L2. Но что, если мы хотим использовать другую метрику расстояния, такую ​​как ненормализованный L1 или отношение сигнал / шум? С модулем расстояний вы можете легко опробовать эти идеи:

Вы также можете использовать меры сходства, а не расстояния, даже если сходство обратно пропорционально расстояниям:

С помощью меры сходства TripletMarginLoss внутренне меняет местами термины с положительной и отрицательной привязкой:

где «s» обозначает сходство.

Редукторы

Потери обычно вычисляются для каждого элемента, пары или тройки, а затем уменьшаются до одного значения с помощью некоторой операции, такой как усреднение. Многие функции потерь PyTorch принимают параметр сокращения, который обычно имеет значение «среднее», «сумма» или «нет».

В PyTorch Metric Learning параметр reducer служит той же цели, но вместо этого принимает объект, который выполняет сокращение. Вот пример передачи ThresholdReducer в функцию потерь:

Этот ThresholdReducer отбрасывает убытки, выходящие за пределы диапазона (10, 30), а затем возвращает среднее значение оставшихся убытков.

Регуляризаторы

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

А классификационные потери имеют необязательный параметр регуляризатора веса:

Гибкий MoCo для самостоятельного обучения

Momentum Contrastive Learning (MoCo) - это современный алгоритм самоконтроля.

Вкратце он состоит из следующих этапов:

  1. Инициализируйте две свертки Q и K с одинаковым весом.
  2. На каждой итерации обучения устанавливайте веса K равными (m) * K + (1-m) * Q, где m - импульс.
  3. Получите пакет изображений X и случайным образом расширенную версию X`.
  4. Передайте X в Q и X` в K и сохраните вывод K в большой очереди.
  5. Примените потерю InfoNCE (также известную как NTXent), используя [Q_out, K_out] как положительные пары и [Q_out, queue] как отрицательные пары.
  6. Обратное распространение и обновление Q.

Эта простая процедура прекрасно работает для создания хороших экстракторов признаков. Вам может быть интересно, можно ли использовать другую функцию потерь, метрику расстояния или метод сокращения. А как насчет добычи жестких негативов из очереди?

С этой библиотекой очень легко опробовать эти идеи с помощью CrossBatchMemory. Сначала инициализируйте его с помощью любых потерь на основе кортежей и, при желании, укажите майнер:

Создайте «метки», чтобы указать, какие элементы являются положительными парами, и укажите, какую часть пакета добавить в очередь:

Вычислите потерю и выполните шаг оптимизатора. CrossBatchMemory берет на себя весь майнинг, вычисление потерь и учет очереди:

Чтобы подтвердить, что CrossBatchMemory работает с MoCo, я написал блокнот, демонстрирующий, что он обеспечивает точность, эквивалентную официальной реализации на CIFAR10 (с использованием InfoNCE и без майнинга). Вы можете запустить блокнот на Google Colab.

ТочностьКалькулятор

Если вам нужно вычислить точность на основе k-ближайших соседей и кластеризации k-средних, AccuracyCalculator - удобный инструмент для этого. По умолчанию он вычисляет 5 стандартных показателей точности, когда вы передаете вложения запроса и ссылки:

Добавить собственные метрики точности очень просто:

Теперь, когда вы вызываете get_accuracy, возвращаемый словарь будет включать some_amazing_metric. Ознакомьтесь с документацией, чтобы узнать, как это работает.

Распределенные оболочки

Чтобы убытки и майнеры работали в нескольких процессах, используйте распределенные обертки:

Зачем нужны эти обертки? Под капотом метрические потери и майнеры обычно должны иметь доступ ко всем кортежам в пакете. Но если ваша программа выполняется в отдельных процессах, проигрыш / майнер в каждом процессе не может видеть глобальный пакет и, следовательно, будет видеть только часть всех кортежей. Использование распределенных оболочек решает эту проблему. (Спасибо Джону Джорджи, который придумал, как реализовать это в своем проекте конструктивных неконтролируемых текстовых представлений DeCLUTR.)

Примеры в документации Google Colab +

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

В заключение, вот подробное представление о содержимом этой библиотеки.

Надеюсь, что вы найдете ее полезной!