"Машинное обучение"

Внедрение технологии FaceID в сиамской нейронной сети

Понимание более странных сетей.

Face ID - это технология, которая позволяет устройствам предоставлять себе доступ только к разрешенным идентификаторам. Он использует это, глядя на лицо человека, и если он распознается как человек, имеющий доступ, системы выдают это. В течение долгого времени он реализовывал различные технологии, но в настоящее время, после массового развития ИНС и достижения высокой производительности компьютерного зрения с помощью CNN, нейронная сеть стала более привлекательным способом сделать это.

Первый путь - простой CNN.

Самый простой способ сделать это - создать простую CNN, которая классифицирует лицо пользователя как «владельца» / «не владельца» этого устройства. Однако у этой реализации есть некоторые недостатки.

  • Для обучения нейронной сети, особенно CNN, требуется много времени и вычислительных мощностей.
  • CNN нужно тренировать для каждого человека отдельно.

Таким образом, пользователь не станет покупать устройство, если ему / ей придется ждать 3-5 часов, чтобы обучить модель, которая распознала бы его. Кроме того, требуется много изображений. Представьте, как пользователь должен сделать около 1000 селфи для распознавания лиц.

Первый путь - 2 головные нейронные сети.

Второй способ - использовать более сложную архитектуру нейронной сети - двуглавую нейронную сеть. Идея довольно проста. Сеть принимает 2 изображения, одно сохранено на устройстве владельца, а другое - с камеры. И CNN должен классифицировать их как «одинаковые» / «разные» или присвоить рейтинг.

Даже если эта архитектура является лучшим подходом, у нее есть свои ограничения.

  • Он может работать не во всех случаях, даже если он был обучен на множестве изображений разных людей.
  • Кроме того, это может быть вычислительным и трудоемким, даже если CNN будет обучаться на сервере, а не на конечном устройстве.

Так что нам нужен лучший подход.

Сиамская нейронная сеть

Сиамская нейронная сеть (или сокращенно SNN) на самом деле представляет собой простую CNN, которая требует немного другого способа обучения. Почти во всех сетях мы разбиваем наш набор данных на несколько пакетов, и загрузчик отправляет их в сеть. SNN используют метод под названием триплетное обучение. Итак, как это работает.
В основном нам нужны изображения двух типов: фотографии с изображением лица владельца и другие фотографии с лицом, не принадлежащим владельцу, обычно это случайные фотографии людей. Во время создания набора данных мы создаем из этих изображений тройки, две разные фотографии одного и того же человека и одну случайного человека. В приведенном ниже коде показан класс набора данных, реализованный в PyTorch.

# Defining the Dataset
class SNN_Dataset(data.Dataset):
    def __init__(self, root, ME_DIR, NOT_ME_DIR):
        self.root = root
        ME_PATHS = listdir(ME_DIR)
        NOT_ME_PATHS = listdir(NOT_ME_DIR)
        ME_PATHS = [join(ME_DIR, img_path) for img_path in ME_PATHS]
        NOT_ME_PATHS = [join(NOT_ME_DIR, img_path) for img_path in NOT_ME_PATHS]
        ME_PAIRS = list(itertools.permutations(ME_PATHS, 2))
        self.TRIPLETS = list(itertools.product(ME_PAIRS, NOT_ME_PATHS))
        self.TRIPLETS = [list(triplet) for triplet in self.TRIPLETS]
        for i in range(len(self.TRIPLETS)):
            self.TRIPLETS[i] = list(self.TRIPLETS[i])
            self.TRIPLETS[i][0] = list(self.TRIPLETS[i][0])
            self.TRIPLETS[i][0].append(self.TRIPLETS[i][1])
            self.TRIPLETS[i].pop(-1)
            self.TRIPLETS[i] = self.TRIPLETS[i][0]
        random.shuffle(self.TRIPLETS)
    def __getitem__(self, index):
        img_triplet = [Image.open(img).convert('RGB') for img in self.TRIPLETS[index]]
        img_triplet = [transforms.Scale((244, 244))(img) for img in img_triplet]
        img_triplet = [transforms.ToTensor()(img) for img in img_triplet]
        return img_triplet[0], img_triplet[1], img_triplet[2]
    def __len__(self):
        return self.TRIPLETS

Сеть берет каждое изображение из триплета и вычисляет линейное представление изображений. С точки зрения линейной алгебры нейронные сети на самом деле представляют собой очень большие и сложные линейные и нелинейные преобразования. Таким образом, каждый вывод ИНС является линейным представлением ввода. После линейного представления вывод переходит в формулу ниже. Если линейное представление первых изображений близко друг к другу (евклидова норма низкая) и линейное представление первого и последнего изображения далеко (евклидова норма высокая), то значение первого члена функция max перед добавлением альфа будет отрицательной. Итак, когда альфа равна 0, если первые изображения одного и того же человека, в этой формуле будет 0. Почему нам нужна альфа в формуле.

Альфа можно интерпретировать как параметр (от -1 до 1), который устанавливает чувствительность сети. Таким образом, чем выше чувствительность, тем ниже норма между изображениями одного и того же человека, и наоборот. Также, если у вас много изображений, вы можете установить альфа-канал на более высокое значение, а когда у вас меньше - на меньшее, даже отрицательное.
Когда я обучал сеть на своих изображениях, я установил альфа на 0,5 и использовал 7 изображения меня и 10 случайных изображений потребовалось 5 часов для обучения сети (я использовал комбинации для генерации набора данных) на ПК с 8 ядрами. Однако, когда я обучил сеть на изображениях одного из моих коллег, используя только 2 изображения человека и 5 случайных изображений, обучение сети заняло не более 15 минут, но также потребовалось более низкое значение альфа, даже отрицательное. Таким образом, вы можете обучить сеть с высоким значением альфа, чтобы подтолкнуть сеть к лучшему обучению, и снизить его на этапе производства.

Для обратного распространения используется значение, полученное из формулы.
И вот результаты.
Примечание: ВАСИЛИКА - означает ласку для моего имени - Василий.

Репозиторий кода: https://github.com/ScienceKot/SNN.git

Вдохновение - Андрей Бурков, стостраничная книга по машинному обучению.