Время прочтения: 3 мин.

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

Первым делом, выбираем в качестве метода обнаружения лиц на изображении сверточную нейронную сеть MTCNN (Multi-Task Cascaded Convolutional Neural Network). После обнаружения лица на изображении будем использовать еще одну глубокую сверточную нейронную сеть (facenet_keras.h5) для преобразования изображения лица  в 128-мерный вектор float чисел. Ниже представлена функция, которая делает такое преобразование. Функция принимает два аргумента — модель и изображение лица размером 160х160.

def get_embedding(model, face_pixels): # facenet_keras.h5
    # преобразуем данные в тип  float
    face_pixels = face_pixels.astype('float32')
    # нормируем и центрируем
    mean, std = face_pixels.mean(), face_pixels.std()
    face_pixels = (face_pixels - mean) / std
    # трансформируем исходные данные
    samples = expand_dims(face_pixels, axis=0)
    # получаем изображение в виде 128 размерного вектора
    yhat = model.predict(samples)
    return yhat[0]

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

а) нормой (среднеквадратичным отклонением)

from numpy import linalg
linalg.norm(foto[j]-foto[i])

Чем меньше расстояние, тем более похожи вектора и более похожи изображения.

Например, для Месси это расстояние равно 5.23, для Салаха — 5.25, а для Суареса — 5.43. Между друг другом это расстояние равно от 12 до 16.

б) косинусным подобием

from numpy import dot

Для косинусного подобия есть специальные метрики в библиотеках:

from sklearn.metrics.pairwise import cosine_similarity
from scipy import spatial

Чем косинусное подобие ближе к единице, тем более похожи вектора. Мы будем пользоваться формулой NumPy, т.к. только с ней можно воспользоваться декоратором Numba, но об этом ниже.

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

Кроме того, когда фотографий много возникает проблема в скорости расчета. Это решается с помощью декоратора Numba (jit-компилятор Python).

 На практике он даёт увеличение скорости расчета в 10 раз.

@numba.jit (nopython = True)
def slechNB(foto):
    odinakov_foto = [ ]
    for i in range(len(foto)):
	for j in range(1 + i, len(foto)):                   
                if linalg.norm(foto[i] - foto[j]) < 5.5 # если используем норму
	      odinakov_foto.append(linalg.norm(foto[i]  - foto[j]))
      odinakov_foto.append(i)
                odinakov_foto.append(j)
    return odinakov_foto # возвращает список из порядковых номеров изображений
				и расстояние между ними

Итак, в данной статье мы показали, как, используя нейросети, можно преобразовать изображение в компактное пространство и рассмотрели способы сравнения этих пространств с целью обнаружения похожих (одинаковых) лиц на изображениях.