Facenet人脸识别模型中的三步阈值

人工智能 神经网络 机器学习
2021-10-27 07:38:09

假设我训练了两个人的图像,比如 Bob,Thomas。当我运行算法来检测与这两个人完全不同的人的脸时,比如 John,那么 John 被识别为 Bob 或 Thomas。如何避免这种情况?

我正在 GitHub(链接) 上研究使用 Facenet 模型的人脸识别模型。问题是当给定未知图像(不在训练数据集中的图像)进行识别时,它将未知人识别为数据集中的人。我在网上搜索,发现我需要增加阈值。我想我需要提高门槛但是当我将阈值增加到 0.99,0.99,99 时,它只会拒绝未知图像(不在数据集中的人的图像),有时甚至会拒绝在数据集中的人的图像。

我想通过增加阈值,我们可以确保只有当图像足够接近时,图像才会被归类为训练数据中的人物之一。

如何进行更改以使模型正常工作?有人可以更好地解释 Facenet 模型中的阈值。

1个回答

问题源于代码的性质。

代码: https ://github.com/AISangam/Facenet-Real-time-face-recognition-using-deep-learning-Tensorflow/blob/master/classifier.py

                model = SVC(kernel='linear', probability=True)
                model.fit(emb_array, label)

                class_names = [cls.name.replace('_', ' ') for cls in img_data]

如您所见,代码使用 SVC(支持向量分类器)对类进行分类。SVC(或 SVM)没有额外的unknown类。

对于threshold变量,它用于人脸检测,也就是在人脸周围绘制一个边界框,以便 FaceNet 对其进行分类。

代码:

https://github.com/AISangam/Facenet-Real-time-face-recognition-using-deep-learning-Tensorflow/blob/master/identify_face_image.py

            frame = frame[:, :, 0:3]
            bounding_boxes, _ = detect_face.detect_face(frame, minsize, pnet, rnet, onet, threshold, factor)
            nrof_faces = bounding_boxes.shape[0]

如您所见,该threshold变量仅用于检测边界框。

获取类名的代码:


predictions = model.predict_proba(emb_array)
                    print(predictions)
                    best_class_indices = np.argmax(predictions, axis=1)
                    # print(best_class_indices)
                    best_class_probabilities = predictions[np.arange(len(best_class_indices)), best_class_indices]
                    print(best_class_probabilities)
                    cv2.rectangle(frame, (bb[i][0], bb[i][1]), (bb[i][2], bb[i][3]), (0, 255, 0), 2)    #boxing face

                    #plot result idx under box
                    text_x = bb[i][0]
                    text_y = bb[i][3] + 20
                    print('Result Indices: ', best_class_indices[0])
                    print(HumanNames)

可以看到找不到unknown类。

解决方案

您可以尝试添加另一个阈值并检查predictions最大值是否低于阈值。我在张量流方面几乎没有经验,所以这只是一个概念证明,不确定它是否会起作用。

best_class_probabilities = predictions[np.arange(len(best_class_indices)), best_class_indices] #original code
if(best_class_probabilities < threshold_2):
    best_class_indices = -1
HumanNames = "unknown"

顺便说一句,由于三元组损失的性质,您不必向 SVC/SVM 添加额外的类,因为嵌入模型是锁定的且未经过训练,因此未知类嵌入与已知类将非常不同。但是,您可以尝试任何一种方法。

希望它可以帮助您度过美好的一天!