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

Итак, теперь давайте посмотрим, как эта система работает с ИИ.

Если вы хотите увидеть полный исходный код и файл модели этого проекта, перейдите и проверьте мой репозиторий Github:
https://github.com/YasinShafiei/FaceID_system

Что ИИ делает в этой системе?

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

Вещь, которая вычисляет расстояние, называется сиамскими нейронными сетями. Теперь давайте посмотрим, что такое сиамские нейронные сети и как они работают.

Сиамские нейронные сети:

Проще говоря, сиамские нейронные сети получают 2 входа и возвращают 1 выход. Например, требуется 2 изображения, сравнить их и вернуть расстояние этих 2 изображений.

Теперь давайте углубимся. Вы даете сети 2 входа одинаковой формы. Одно из них — входное изображение, а другое — проверочное. Затем изображение отправится в отдельные вложения (Содержит блоки Conv). После этого результаты встраивания попадут в слой Distance, который рассчитает расстояние 2-х сетей по следующей формуле:
| input_embedding — верификация_embedding |

входное встраивание — это входное изображение, полученное в результате встраивания, а проверочное встраивание — это проверочное изображение, полученное в результате встраивания.

Теперь результат будет отправлен на слой классификатора, который имеет 1 единицу (поскольку он вернет 1 вывод) с функцией активации Sigmoid.

Теперь вы точно знаете, как работают сиамские нейронные сети!

Следующий шаг — реализовать эти вещи в коде.

Полный исходный код этого проекта доступен в моем репозитории Github:
https://github.com/YasinShafiei/FaceID_system

Библиотеки:

Как я уже сказал, я использовал TensorFlow для создания сиамских нейронных сетей. Но есть и другие библиотеки, которые я использовал:

# import all libraries
import cv2
import os
import random
import numpy as np
import matplotlib.pyplot as plt
from keras.models import Model, load_model
from keras.layers import *
import uuid
import tensorflow as tf
from keras.metrics import Precision, Recall
import keras

Я использовал TensorFlow, чтобы использовать свою веб-камеру, чтобы увидеть результаты этого проекта, NumPy, чтобы делать прогнозы, Matplotlib, чтобы показать некоторые результаты тестовых данных, а также Precision и Recall, чтобы проверить производительность модели.

Теперь определите некоторые гиперпараметры и переменные.

BATCH_SIZE = 16
EPOCHS = 150
POSITIVE_PATH = os.path.join("data", "positive")
NEGATIVE_PATH = os.path.join("data", "negative")
ANCHOR_PATH = os.path.join("data", "anchor")

Загрузить данные:

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

Этот набор данных собран и дополнен мной. Данные имеют 3 папки. Якорные изображения, позитивные изображения и негативные изображения. Как вы знаете, в Siamese Network 2 изображения будут передаваться в сеть, и она скажет, одинаковы ли изображения или нет. Якорное изображение — это входное изображение (в данном случае лицо пользователя, которое нужно определить, одобрено оно или нет). Положительные и отрицательные — это изображения, которые будут переданы модели в качестве проверочных изображений (о них говорилось ранее). Позитивные изображения совпадают с якорями, а негативы — нет.

Сначала мы должны получить изображения.

# get images
anchor_images = tf.data.Dataset.list_files(ANCHOR_PATH + "\*jpg").take(3000)
positive_images = tf.data.Dataset.list_files(POSITIVE_PATH + "\*jpg").take(3000)
negative_images = tf.data.Dataset.list_files(NEGATIVE_PATH + "\*jpg").take(3000)

Это номер каждого класса:

Number of anchor image: 746 
Number of positive images: 3000 
Number of negative images: 3000

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

В функции preprocess_image она сначала прочитает и декодирует изображение из пути, а затем изменит размер изображения до 100x100 пикселей. После этого он будет масштабировать изображение от 1 до 0.

Теперь я просто применил предварительную обработку изображений int и создал наборы данных Train и Test:

Нейронные сети:

Итак, сначала давайте рассмотрим, что такое сиамская нейронная сеть. SNN (сиамские нейронные сети) будет принимать 2 входа и возвращать 1 выход. Выход - это расстояние между двумя входами. Как я уже сказал, 2 входа модели будут переданы во встраивание.

Теперь давайте посмотрим, что встраивается.

Вложение (в этом проекте) имеет 4 блока Conv, которые подготовят изображения для расчета расстояний и окончательной классификации. Ввод встраивания (100, 100, 3) (потому что изображения 100, 100, 3). Каждый блок свертки имеет один слой Conv и один слой MaxPooling.

Это код для встраивания. Я объясню детали после кода:

Итак, как вы можете видеть, первый слой свертки имеет 64 единицы и размер ядра 10. Во второй свертке количество единиц увеличивается до 128, а размер ядра уменьшается до 7.

В третьем слое Conv единицы такие же, но размер ядра снижен до 4.
В финальном слое Conv только единицы увеличиваются до 256. Затем плотный слой с 4096 единицами и сигмовидной активацией. Выходная форма вложения (None, 4096).

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

Теперь остался только один шаг — определение окончательного SNN. Сначала я поставлю код, а объясню его после:

Здесь модель получит 2 входа. Одно изображение является привязкой, а другое — проверочным изображением (положительным или отрицательным). Тогда оба входа пойдут на встраивание. Результаты встраивания перейдут на слой расстояния, а плотный слой вернет выход 1.

Следующей операцией, которая должна быть сделана, является обучение!

Обучите модель:

Чтобы лучше понять эту часть, позвольте мне объяснить, как тренируется модель.

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

Для обучения я использовал оптимизатор Адама Binary Cross-Entropy loss со скоростью обучения 0,0004.

# setup loss and optimizer
loss_function = tf.losses.BinaryCrossentropy()
optimizer = tf.keras.optimizers.Adam(1e-4)

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

Вторая функция запустит этап обучения для количества эпох. Он также рассчитает отзыв и точность.

После 100 эпох обучения вот результаты:

  1. Проигрыш: 0.0
  2. Точность: 1,0
  3. Напомним: 1.0

И, наконец, сохраните модель:

siamese_network.save('face_id_model.h5')

Теперь модель сохранена и готова к использованию с хорошим результатом!!

Итак, давайте посмотрим, как модель ведет себя на тестировании!

Протестируйте модель:

Чтобы протестировать и оценить модель, сначала мне пришлось загрузить модель:

model = load_model("face_id_model.h5", custom_objects={"DistanceLayer":DistanceLayer, "BinaryCrossentropy":tf.losses.BinaryCrossentropy})

Затем я сделал прогнозы и отрендерил их, метка 0 — False, а 1 — True.

Это один из прогнозов. Модель правильно предсказала все тестовые данные:

Используйте модель:

Чтобы использовать модель, мы должны предоставить модели изображение как input_image и другое изображение как Verification_images, тогда модель будет делать прогнозы. После этого мы сравниваем, выше ли прогноз порога или нет.

Но сначала я собрал несколько изображений для проверки. Изображения для проверки будут сохранены в app_data\verification_images:

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

По сути, сбор верификаций — это добавление лица в систему идентификации лица. Как в айфонах!

Теперь давайте посмотрим, как я определил функцию для проверки лиц:

Эта функция будет делать то, что я сказал в первом абзаце этой части!

Теперь осталось только предсказание в реальном времени с помощью веб-камеры!

Итак, я написал и использовал opencv только для прогнозирования в реальном времени. НО, поскольку я хотел упростить использование, я интегрировал модель в графический интерфейс.

Если вы хотите увидеть полную записную книжку и исходный код приложения с графическим интерфейсом, ознакомьтесь с моим репозиторием на Github:
https://github.com/YasinShafiei/FaceID_system

Теперь вы увидите результаты на графике…

Как видите, модель может проверить меня, но не моего дядю. Например, идентификаторы лица на ваших iPhone.

Этот проект и статья написаны Ясином Шафии.

Репозиторий Github: https://github.com/YasinShafiei/FaceID_system
Ссылка на видео: https://youtu.be/KpcOEH2ITJM