Paddle实现人脸对比(二)

我之前发过一篇基于孪生网络的人脸对比的文章,这篇文章也到了百度的推荐位置:

但是,效果并不是很好。经过大量的搜索,我发现了一种新的方法,可以非常好的实现人脸对比。

原理分析

我们先训练一个普通的人脸分类模型,这个人脸分类模型可以认为是这样的:

因此,在训练完分类模型后,只需要去掉底下的分类层(在模型中一般是全连接层),只看特征提取层的输出的相似程度即可。

如何比较两个输出的相似度呢?其实,这两个输出都是向量,因此我们可以采用两向量之间的夹角判断相似度。这个方法甚至在高中的信息技术课本里就有提到:

课本中是使用这种方法进行自然语言处理的,我们也可以使用这种方法进行人脸对比。其实就是根据两向量的乘积等于两向量的长度乘上两向量之间夹角的余弦值。

在paddle中,提供了专门的函数计算这个相似度:

python 复制代码
import paddle.nn.functional as F
cosine_similarity = F.cosine_similarity(vec1, vec2) 

注意,这里的vec1、vec2都应该是paddle的张量类型,可以使用paddle.to_tensor()函数转换为张量类型。

数据集加载

我们可以按照正常的图片分类的方式加载图片,我采用这个开源的数据集:

人脸数据_数据集-飞桨AI Studio星河社区 (baidu.com)

代码如下:

python 复制代码
import numpy as np
from PIL import Image
import paddle
from random import shuffle
import pickle


class FaceData(paddle.io.Dataset):

    def __init__(self, mode):
        super().__init__()
        # 训练集/测试集
        file = 'facecap/facecap/train_list.txt' if mode == 'train' else 'facecap/facecap/test_list.txt'
        self.imgs = []
        self.labels = []
        with open(file) as f:
            # 读取数据集文件信息数据并洗牌
            lines = f.readlines()
            shuffle(lines)
            print('read down')
            # 加载数据集
            for line in lines:
                line = line.strip()
                img, label = line.split(' ')
                pil_img = Image.open(f'facecap\\facecap\\{img}').convert('RGB').resize((96, 96))
                self.imgs.append(np.array(pil_img).transpose((2, 0, 1)))
                self.labels.append(label)
        self.imgs = np.array(self.imgs, dtype=np.float32)
        self.labels = np.array(self.labels, dtype=np.int32)
        print('load down')

    def __getitem__(self, idx):
        return self.imgs[idx], self.labels[idx]

    def __len__(self):
        return len(self.labels)


if __name__ == '__main__':
    train_dataset = FaceData(mode='train')
    test_dataset = FaceData(mode='test')

    pickle.dump(train_dataset, open('./database/train.data', 'wb'), protocol=4)
    pickle.dump(test_dataset, open('./database/test.data', 'wb'), protocol=4)

脚本采用pickle存储加载后的数据集,方便使用。

训练脚本

训练脚本非常简单,我们采用resnet模型,如下:

python 复制代码
import paddle
from dataset import FaceData
import pickle

paddle.set_device('gpu')

train_dataset = pickle.load(open('./database/train.data', 'rb'))
test_dataset = pickle.load(open('./database/test.data', 'rb'))

net = paddle.vision.resnet18(num_classes=500)
model = paddle.Model(net)

model.load('./output/model')

model.prepare(
    paddle.optimizer.Adam(parameters=model.parameters()),
    paddle.nn.CrossEntropyLoss(),
    paddle.metric.Accuracy()
)

model.fit(train_dataset, epochs=20, batch_size=64, verbose=1, save_dir='./cache/model')

model.evaluate(test_dataset, batch_size=64, verbose=1)

model.save('./output/model')

推理脚本

推理脚本需要注意去除最后的全连接层,代码如下:

python 复制代码
import paddle
from dataset import FaceData
import numpy as np
import paddle.nn.functional as F

state_dict = paddle.load('./output/model.pdparams')

old_net = paddle.vision.resnet18(num_classes=500)
old_net.load_dict(state_dict)

new_layers = list(old_net.children())[:-1]  # 移除全连接层
net = paddle.nn.Sequential(*new_layers)

model = paddle.Model(net)


def predict(img1, img2):
    """
    推理两张图片的相似度
    :param img1: 第一张图片的PIL数据
    :param img2: 第二张图片的PIL数据
    :return: 相似度,属于区间[0, 1]。越大越相似
    """
    d1 = np.array(img1, dtype=np.float32).transpose((2, 0, 1))
    d2 = np.array(img2, dtype=np.float32).transpose((2, 0, 1))

    p1 = model.predict_batch(np.expand_dims(d1, axis=0))[0]
    p2 = model.predict_batch(np.expand_dims(d2, axis=0))[0]
    t1 = paddle.to_tensor(p1)
    t2 = paddle.to_tensor(p2)
    return float(F.cosine_similarity(t1, t2)[0][0][0])

测试

采用网上的图片进行一次测试,结果也非常的好,相同的人脸相似度为0.9,不同的人脸为0.8。实际应用中,可以将当前人脸与数据库中的所有人脸进行对比,确定当前人脸

参考

使用PaddlePaddle实现人脸对比和人脸识别_paddle 人脸识别-CSDN博客

教育科学出版社 高中教材 信息技术 选择性必修4

相关推荐
紫小米1 小时前
后端日志管理
python·fastapi
agicall.com1 小时前
座机通话双方语音分离技术解决方案详解
人工智能·语音识别·信创电话助手·座机语音转文字·固话座机录音转文字
AI机器学习算法1 小时前
《动手学深度学习PyTorch版》笔记
人工智能·学习·机器学习
Goboy2 小时前
「我的第一次移动端 AI 办公」TRAE SOLO 三端联动, 通勤路上就把活干了,这设计,老罗看了都想当场退役
人工智能·ai编程·trae
qq_452396232 小时前
第二十篇:《UI自动化测试的未来:AI驱动的智能测试与低代码平台》
人工智能·低代码·ui
视觉&物联智能2 小时前
【杂谈】-人工智能风险文化对组织决策的深远影响
人工智能·安全·ai·agi
白雪茫茫2 小时前
监督学习、半监督学习、无监督学习算法详解
python·学习·算法·ai
β添砖java2 小时前
深度学习(12)Kaggle房价竞赛
人工智能·深度学习
冬奇Lab2 小时前
RAG 系列(十):混合检索——让召回更全面
人工智能·llm
冬奇Lab3 小时前
一天一个开源项目(第95篇):Claude for Financial Services - Anthropic 官方金融行业 AI 代理套件
人工智能·开源·资讯