Paddle实现人脸对比(二)

news2025/5/25 3:15:00

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

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

原理分析

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

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

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

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

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

import paddle.nn.functional as F
cosine_similarity = F.cosine_similarity(vec1, vec2) 

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

数据集加载

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

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

代码如下:

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模型,如下:

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')

推理脚本

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

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 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1593369.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【汇编】存储器

存储器 计算机存储器可分为内部存储器(又称内存或主存)和外部存储器,其中内存是CPU能直接寻址的储存空间,由半导体器件制成 存储单元的地址和内容 计算机存储信息的基本单位是一个二进制位,一位可存储一个二进制数&…

spring boot 集成 flyway依赖 做数据库迁移,让部署没烦恼

flyway 是一个敏捷工具&#xff0c;用于数据库的移植。采用 Java 开发&#xff0c;支持所有兼容 JDBC 的数据库。 主要用于在你的应用版本不断升级的同时&#xff0c;升级你的数据库结构和里面的数据。 还是直接上代码 第一步&#xff1a; <!-- Flyway 数据库迁移 依赖 他…

FJSP:鲸鱼优化算法WOA求解柔性作业车间调度问题(FJSP),提供MATLAB代码

一、柔性作业车间调度问题 柔性作业车间调度问题&#xff08;Flexible Job Shop Scheduling Problem&#xff0c;FJSP&#xff09;&#xff0c;是一种经典的组合优化问题。在FJSP问题中&#xff0c;有多个作业需要在多个机器上进行加工&#xff0c;每个作业由一系列工序组成&a…

【Kafka】Kafka 架构深入

Kafka 工作流程及文件存储机制 Kafka 中消息是以 topic 进行分类的&#xff0c;生产者生产消息&#xff0c;消费者消费消息&#xff0c;都是面向 topic 的。 topic 是逻辑上的概念&#xff0c;而 partition 是物理上的概念&#xff0c;每个 partition 对应于一个 log 文件&am…

大模型(Large Models):探索人工智能领域的新边界

&#x1f31f;文章目录 &#x1f31f;大模型的定义与特点&#x1f31f;模型架构&#x1f31f;大模型的训练策略&#x1f31f;大模型的优化方法&#x1f31f;大模型的应用案例 随着人工智能技术的飞速发展&#xff0c;大模型&#xff08;Large Models&#xff09;成为了引领深度…

CSS盒模型(详讲)

目录 概述&#xff1a; 内容区&#xff08;content&#xff09;&#xff1a; 内边距&#xff08;paddingj&#xff09;&#xff1a; 前言&#xff1a; 设置内边距&#xff1a; 边框&#xff08;border&#xff09;&#xff1a; 前言&#xff1a; 示例&#xff1a; 外边…

ACID模型是什么

ACID模型是什么 ACID模型是数据库管理系统中保证事务处理安全性的一组特性。ACID是原子性&#xff08;Atomicity&#xff09;、一致性&#xff08;Consistency&#xff09;、隔离性&#xff08;Isolation&#xff09;和持久性&#xff08;Durability&#xff09;四个英文单词的…

WebApi+Python PyQ5实现大文件下载,Ui增加进度条和下载速率+已验证uos和Windows环境

Web Api接品代码&#xff1a; using Microsoft.AspNetCore.Mvc; using System.Collections.Concurrent; using System.Net;namespace LargeFileHandling.Controllers {[ApiController][Route("[controller]")]public class TestProgramFileManagerController : Cont…

【鸿蒙开发】第二十章 Camera相机服务

1 简介 开发者通过调用Camera Kit(相机服务)提供的接口可以开发相机应用&#xff0c;应用通过访问和操作相机硬件&#xff0c;实现基础操作&#xff0c;如预览、拍照和录像&#xff1b;还可以通过接口组合完成更多操作&#xff0c;如控制闪光灯和曝光时间、对焦或调焦等。 2 …

js canvas实现裁剪图片并下载

简历上给自己挖的坑&#xff0c;面试被拷打&#xff0c;早就该填了T.T 参考&#xff1a;【js canvas实现图片裁剪】 https://www.bilibili.com/video/BV1QK411d7n1/?share_sourcecopy_web&vd_sourcebf743b20b76eab11028ba2fb05f056b4 效果 思路 组成&#xff1a; 上传文…

8. Spring Boot 配置文件

源码地址&#xff1a;SpringBoot_demo 本篇文章内容源码位于上述地址的com/chenshu/springboot_demo/config包下 1. 配置文件是什么 上节说到&#xff0c;Spring Boot的项目分为三个部分&#xff1a;源代码目录、资源目录、单元测试目录。 而配置文件的位置就位于资源目录res…

【竞技宝jjb.lol】LOL:T1成功击败HLE晋级MSI!

北京时间2024年4月13日,英雄联盟LCK2024春季季后赛继续进行,昨天迎来败者组决赛HLE对阵T1。本场比赛HLE率先拿下一局之后,T1连续两局在后期决策上碾压HLE拿到赛点,第四局zeus祭出上单VN在中期杀穿HLE后排,最终T1以3-1的比分击败HLE晋级春季决赛,同时也拿到了MSI的参赛资格。以下…

CSS3 常用样式

个人主页&#xff1a;学习前端的小z 个人专栏&#xff1a;HTML5和CSS3悦读 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结&#xff0c;欢迎大家在评论区交流讨论&#xff01; 文章目录 ✍CSS3 常用样式&#x1f48e;1 CSS3 新增选择器&#x1f339;1.1 属性选择器…

Python匿名函数4不要

当你需要完成一件小工作时&#xff0c;在本地环境中使用这个函数&#xff0c;可以让工作如此得心应手&#xff0c;它就是Lambda 函数。 Lambda 函数是 Python 中的匿名函数。有些人将它们简称为lambdas&#xff0c;它们的语法如下&#xff1a; lambda arguments: expressionl…

拥有了这24个Python接单平台,你就拥有了“钞能力”

学Python能兼职挣米吗&#xff1f;怎么挣&#xff1f; 一、Python兼职种类&#xff1a; 接私活刚学会python那会&#xff0c;就有认识的朋友介绍做一个网站的私活&#xff0c;当时接单赚了4K&#xff0c;后又自己接过开发网站后台接口、做数据处理等事情&#xff0c;都赚了一…

Python实现外观模式、桥接模式、组合模式和享元模式

今天介绍四种结构型设计模式&#xff1a;外观模式、桥接模式、组合模式和享元模式 外观模式 外观模式&#xff08;Facade Pattern&#xff09;&#xff0c;它为子系统提供一个统一的接口&#xff0c;使得子系统更加容易使用。 在Python中&#xff0c;我们可以通过定义一个外…

记录-若依前端集成markdown文档,自动生成文档目录

使用版本: vue 2.6.12 html-loader 1.3.2 markdown-loader 6.0.0 github-markdown-css ^5.5.1 highlight.js 9.18.5 webpack 4.47.x 一.引入loder插件&#xff0c;html-loader和markdown-loader //安装 pnpm install html-loader --save ; pnpm install markdown-loader --sa…

Zynq学习笔记--AXI 总线概述

目录 1. AXI总线概述 1.1 主要特点 1.2 通道功能 1.3 信号概览 2. AXI Interconnect 2.1 信号说明 2.2 内部结构 3. PS-PL AXI Interface 3.1 AXI FPD/LFP/ACP 3.2 Address Editor 3.3 地址空间 3.4 AXI-DDR 4. 通过ILA观察AXI信号 4.1 AXI 读通道 1. AXI总线概述…

头歌-机器学习 第15次实验 朴素贝叶斯分类器

第1关:条件概率 任务描述 本关任务:根据本节课所学知识完成本关所设置的选择题。 相关知识 为了完成本关任务,你需要掌握条件概率。 条件概率 朴素贝叶斯分类算法是基于贝叶斯定理与特征条件独立假设的分类方法,因此想要了解朴素贝叶斯分类算法背后的算法原理,就不得…

STM32-看门狗

1、看门狗是什么&#xff1a;就是一个向下定时器&#xff0c;定时时间一到&#xff0c;就会触发一个向下的复位的中断&#xff0c;使单片机开始工作 2、作用&#xff1a;MCU微控制器构成的微型计算机系统中&#xff0c;由于微控制器的工作常常会受到来自外界电磁场的干 扰,造成…