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

相关推荐
草莓熊Lotso2 分钟前
Linux 2.6 内核 O(1) 调度队列深度解析:为什么它能实现常数时间调度?
linux·运维·服务器·数据结构·人工智能·哈希算法·散列表
渡我白衣2 分钟前
从森林到梯度——梯度提升树的原理、调参与实战
人工智能·深度学习·神经网络·目标检测·机器学习·计算机视觉·自然语言处理
weixin_462446233 分钟前
Python+React 专为儿童打造的汉字学习平台:从学前到小学的智能汉字教育解决方案
python·学习·react.js
Dylan的码园4 分钟前
稀疏 MoE 与原生多模态双驱:2025 大模型技术演进全景
人工智能·机器学习·ai作画·数据挖掘·boosting·oneflow
_-CHEN-_4 分钟前
Prompt Manager: 让你的 AI 提示词管理更专业
人工智能·prompt
weixin_397578025 分钟前
Transformer 架构 “Attention Is All You Need“
人工智能
檀越剑指大厂6 分钟前
AI 当主程还能远程开发?TRAE SOLO 的实用体验与cpolar内网突破
人工智能
河码匠7 分钟前
Django rest framework 自定义url
后端·python·django
哥只是传说中的小白8 分钟前
无需验证手机Sora2也能用!视频生成,创建角色APi接入教程,开发小白也能轻松接入
数据库·人工智能
cnxy1888 分钟前
Python Web开发新时代:FastAPI vs Django性能对比
前端·python·fastapi