One Shot Learning, сиамские сети и Triplet Loss с Керасом

Вступление

В современную эпоху машинного обучения нейронные сети с глубокой сверткой являются очень мощным инструментом для работы с изображениями для всех видов задач. Мы видели несколько сетей, которые могут классифицировать / обнаруживать около 1000 различных типов объектов с очень хорошей производительностью. Традиционный способ построения классификатора выглядит следующим образом:

В статье 2015 года (под названием FaceNet) авторы использовали другой подход. Вместо того, чтобы использовать NN в качестве прямого классификатора, они построили «сиамскую сеть» и сравнили выходные данные, чтобы решить, были ли эти два входа схожими, назвав этот подход «One Shot Learning» и используя особую функцию потерь, называемую «Triplet Loss».

Эта статья посвящена изучению этих двух концепций и их применению к набору данных MNIST с помощью Keras.

Концепция One Shot Learning и сиамские сети

В традиционном проекте классификации вы обычно обучаете нейронную сеть так, чтобы с изображением в качестве входных данных сеть выводила вероятность (обычно softmax) для каждого класса. Поэтому, если вы хотите знать, есть ли на изображении кошка, собака или лошадь, ваша сеть выдаст 3 вероятности, по одной для каждого класса. Если вы вводите изображение собаки, сеть должна выдавать высокую вероятность для выходных данных собаки и низкую вероятность для выходных данных кошек и лошадей. Другой способ увидеть это состоит в том, что модель отвечает на вопрос «Какой класс является входным?»

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

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

Это прекрасно работает в некоторых ситуациях, но во многих случаях это может оказаться непрактичным. Что делать, если классы меняются слишком быстро, чтобы переучиваться? Типичный пример этой ситуации - распознавание лиц сотрудников у ворот безопасности компании. Классы здесь - это сотрудники, и вам нужно обучить свою систему с помощью лиц сотрудников. Переподготовка, повторное тестирование и повторное развертывание модели каждый раз, когда сотрудник прибывает или покидает компанию, на самом деле нереально. И иметь тысячи фотографий каждого сотрудника тоже нереально.

Введите статью 2015 года FaceNet: унифицированное встраивание для распознавания лиц и кластеризации (следующая за этой тесно связанной статьей). Основная идея состоит в том, чтобы иметь возможность принимать решение только на основе одного образца, чтобы иметь возможность сравнивать два изображения и определять, являются ли они одинаковыми или нет. Отсюда обучение одним выстрелом

Наша система отвечает на вопрос: «Эти две картинки похожи?» Мы не строим прямой классификатор, мы строим компаратор сходства.

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

Вложения

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

  • Два похожих изображения создают два вложения, поэтому математическое расстояние между ними невелико.
  • Два очень разных изображения создают два вложения, поэтому математическое расстояние между ними велико.
  • Вложение является L2-нормализованным, т.е. каждое вложение должно быть на единичной гиперсфере.

Для этого нам нужно обучить специализированную нейронную сеть для нашего контекста, которая производит хорошие вложения с этими свойствами. Для сравнения лиц «два похожих изображения», на которые мы ссылались выше, могут быть одним и тем же лицом на двух разных фотографиях (создавая вложения на небольшом расстоянии), а «два очень разных изображения» могут быть двумя разными лицами, что приводит к встраиванию на большом расстоянии. Что касается животных, «два похожих изображения» могут быть одним и тем же видом на разных фотографиях (вложения на короткое расстояние), а фотографии двух разных видов (вложения на большом расстоянии), вы поняли.

Как долго должно длиться ваше вложение? Четыре числа? 40? Более? Идея состоит в том, что ваше вложение должно содержать «достаточно хорошее» представление вашего класса, чтобы отличать его от других. Длина погружения - новый гиперпараметр задачи.

Например, чтобы различать эти четыре супер-простых класса пикселей 3x3, достаточно двух чисел.

В своей статье FaceNET авторы выбрали 64 числа для обозначения характеристик человеческого лица. Попытка использовать 128 немного улучшила производительность, но ненамного, поэтому они сочли 64 хорошим компромиссом.

Система BERT, созданная Google, не работала с изображениями, но использовала 768 чисел для представления семантического значения слова или фразы.

В этой статье мы выбрали вложения размером 10.

Архитектура проекта для тройной потери

Есть два основных способа узнать параметры нашей сети. Во-первых, мы могли бы просто рассматривать правую часть системы как двоичный классификатор с Y = 1, если входные изображения принадлежат к одному классу, и Y = 0, если нет.

Во-вторых, мы могли бы использовать подход, использованный в статье FaceNet. Поскольку мы хотим сравнить два изображения и иметь вложения на небольшом расстоянии для похожих изображений и вложения на большом расстоянии для разных изображений, идея состоит в том, чтобы рассмотреть

  • Начальная картинка, называемая якорем
  • Картинка из того же класса, что и якорь, называемая Позитивным.
  • Картинка из другого класса привязки, называемая Негативом.

С помощью этих троек из трех изображений (назовем эти вложения A, P и N соответственно) мы хотим

расстояние (A, P) ‹расстояние (A, N)

Давай перепишем по-другому

distance (A, P) - расстояние (A, N) ‹0

Чтобы наша сеть не научилась простому решению, которое удовлетворяет уравнению путем вывода нулей для всего, давайте установим запас между AP и AN с параметром запаса:

distance (A, P) - distance (A, N) + margin ‹0

Наша функция Loss будет основана на этой сущности и будет иметь следующую форму:

L = max (d (A, P) −d (A, N) + маржа, 0)

Подготовка данных для обучения

В этой статье мы будем использовать набор данных MNIST. Все изображения будут отсортированы по классам, это будет полезно для подготовки наших триплетных партий позже.

Триплетная партия

Теперь нам нужно подготовить тройные партии к обучению. Каждый образец нашей партии будет содержать 3 картинки: Якорь, Положительное и Отрицательное. Как выбрать нашу тройню? Первый подход - выбрать триплет совершенно случайным образом следующим образом:

Нам нужна наша сеть сходства, чтобы научиться четко различать наши классы. Исходя из определения убытка, различают три категории троек:

  • простые тройки: тройки с нулевым проигрышем, потому что d (A, P) + margin ‹d (A, N)
  • жесткие тройки: тройки, в которых отрицательное значение ближе к привязке, чем положительное, т. е. d (A, N) ‹d (A, P).
  • полутвердые тройки: тройки, в которых отрицательное значение не ближе к привязке, чем положительное, но все же имеют положительную потерю:
    d (A, P) ‹d (A , N) ‹d (A, P) + маржа

Каждая из этих ситуаций зависит от того, где сравнивается негатив с якорем и позитивом. Будет справедливо сказать, что если наша функция потерь дает 0 для этих простых троек, то наша модель многому из них не научится. С другой стороны, жесткие тройки будут генерировать большие потери и будут иметь большое влияние на параметры нашей сети. Это придаст слишком большой вес неверно размеченным данным. Поэтому мы должны выбрать стратегию, сочетающую легкие, сложные и, возможно, полутвердые тройки. В своей оригинальной статье FaceNet решил нарисовать первую, относительно большую случайную выборку триплетов (убедившись, что распределение классов каким-то образом соблюдено) и выбрал N / 2 жестких и N / 2 случайных выборок для своей партии размера N. Для этой статьи мы сделаем партии из 32 триплетов, состоящих из 16 жестких и 16 случайных, взятых из большой партии из 200 случайных триплетов.

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

Построение нашей модели Кераса

Нейронная сеть

Итак, какая архитектура для нашей нейронной сети? Поскольку в данном случае мы больше фокусируемся на функции потерь, архитектура NN здесь не очень актуальна. Действительно, мы могли взять любую архитектуру, от простой до мощной, такой как ResNet. Для простоты возьмем простой: три стопки сверточных слоев / слоев пула + один полностью связанный. Мы должны убедиться, что последний слой не имеет функции активации, чтобы иметь полный диапазон значений внедрения.

Функция потерь

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

L = max (d (A, P) −d (A, N) + маржа, 0)

Модель обучения

Теперь наша модель Full Keras с привязкой, положительным и отрицательным изображениями в качестве входных данных.

Оценка и метрики

В традиционном классификаторе наша производительность будет основана на лучшем прогнозном балле из всех классов, что приведет к матрице путаницы с метриками Точность, отзыв или F1.

В нашей ситуации наша модель производит вложения, которые мы можем использовать для вычисления расстояний, поэтому мы не можем применить ту же систему для оценки производительности нашей модели. Если две картинки из одного класса, расстояние должно быть низким, если картинки из разных классов, расстояние должно быть большим. Итак, нам нужен порог: если найденное расстояние ниже порога, тогда это то же самое решение, если расстояние выше порога, то это другое решение. Мы должны тщательно выбирать этот порог. Слишком низкий означает, что у нас будет высокая точность, но также будет слишком много ложноотрицательных результатов. Слишком много, и у нас будет слишком много ложных срабатываний. Это проблема кривой ROC. Итак, одним из показателей для оценки может быть площадь под кривой (AUC). В этой статье мы выберем порог так, чтобы частота ложных срабатываний была ниже 10e-3, а затем оценим чувствительность (отзыв).

Наш процесс оценки возьмет тестовый набор данных и оценит расстояние всех изображений друг от друга, а затем вычислит AUC с помощью функции sklearn.

Межклассовое расстояние

Еще одна интересная метрика, на которую следует обратить внимание во время обучения, - насколько «далеки» друг от друга вложения каждого класса. Чтобы быть тщательным, мы должны оценить весь набор данных, но здесь это просто для того, чтобы убедиться, что сеть плавно сходится для всех классов.

Тренировочный процесс

Теперь давайте обучим нашу модель. Каждый цикл создает новый пакет и обрабатывает его.

Вот наша кривая ROC после тренировки:

А теперь посмотрим, как далеко друг от друга находятся классы. В среднем они изменились с 0,5 до 1,4. Это ясно указывает на то, что соответствующие вложения лучше производятся нашей сетью.

Давайте поиграем с нашей сетью, попробовав сравнить несколько тестовых изображений с эталонным изображением из каждого класса. Мы ясно видим, что наша сеть теперь надежно сравнивает сходства:

  • расстояние между тестовым изображением и другим изображением того же класса невелико (10e-2)
  • расстояние между тестовым изображением и другим классом велико (10e-0)

Резюме

  • Одноразовое обучение - это еще один подход к классификации. Его можно использовать, если количество «классов» меняется слишком часто и / или данных для каждого класса недостаточно.
  • Его можно использовать с множеством различных архитектур нейронных сетей.
  • Метод тройной потери - это один из способов обучения сети. Требуется стратегия выбора троек товаров для питания сети во время обучения.

Надеюсь, это помогло вам понять методологию «однократного обучения» с использованием Deep Learning, мне это показалось очень интересным.

Полный код доступен здесь на моем гитхабе.

Этот код был создан на базе ноутбуков Azure и запущен на виртуальной машине для обработки и анализа данных Azure (с графическим процессором Nvidia K80).

Ссылки и благодарности

Курс Эндрю Нг по сверточной нейронной сети с глубоким обучением на Coursera

2015 FaceNet: единое вложение для распознавания лиц и кластеризации Флориана Шроффа, Дмитрия Калениченко и Джеймса Филбина.

Еще одно подробное объяснение потери триплетов и майнинга триплетов от Olivier Moindreau с TensorFlow

Тесс Феррандес за ее лучшую реализацию проигрыша, чем у меня

Абделькадер Дахоу и Хабиб Салас за отзыв