百度site app网站添加到网站首页源文件中的代码是哪些?网站新类型
news/
2025/9/22 21:20:42/
文章来源:
百度site app网站添加到网站首页源文件中的代码是哪些?,网站新类型,做ps彩图什么网站好,工艺宣传网站建设人脸对比
人脸对比#xff0c;顾名思义#xff0c;就是对比两个人脸的相似度。本文将用Paddle实现这一功能。
PS#xff1a;作者肝了整整3天才稍微搞明白实现方法
数据集准备
这里使用百度AI Studio的开源数据集#xff1a;
人脸数据_数据集-飞桨AI Studio星河社区 (b…人脸对比
人脸对比顾名思义就是对比两个人脸的相似度。本文将用Paddle实现这一功能。
PS作者肝了整整3天才稍微搞明白实现方法
数据集准备
这里使用百度AI Studio的开源数据集
人脸数据_数据集-飞桨AI Studio星河社区 (baidu.com)
这个数据集提供了500个人的人脸各100张比较适合我们的项目。
根据这个数据集很容易写出数据集类文件名为face_dataset.py
import numpy as np
from PIL import Image
import paddle
from random import shuffleclass FaceData(paddle.io.Dataset):def __init__(self, mode, num):super().__init__()# 训练集/测试集file facecap/train_list.txt if mode train else facecap/test_list.txtself.imgs1 []self.imgs2 []self.labels []# 控制相同人脸个数与不同人脸个数各占一半_1_count 0with open(file) as f:# 读取数据集文件信息数据并洗牌lines f.readlines()shuffle(lines)lines lines[:num]print(read down)# 加载数据集for line1 in lines:line1 line1.strip()img1, label1 line1.split( )pil_img1 Image.open(ffacecap\\{img1}).convert(RGB).resize((96, 96))for line2 in lines:line2 line2.strip()img2, label2 line2.split( )if label1 label2:_1_count 1pil_img2 Image.open(ffacecap\\{img2}).convert(RGB).resize((96, 96))self.imgs1.append(np.array(pil_img1).transpose((2, 0, 1)) / 255.0)self.imgs2.append(np.array(pil_img2).transpose((2, 0, 1)) / 255.0)self.labels.append(1)elif _1_count 0:_1_count - 1pil_img2 Image.open(ffacecap\\{img2}).convert(RGB).resize((96, 96))self.imgs1.append(np.array(pil_img1).transpose((2, 0, 1)) / 255.0)self.imgs2.append(np.array(pil_img2).transpose((2, 0, 1)) / 255.0)self.labels.append(0)self.imgs1 np.array(self.imgs1, dtypenp.float32)self.imgs2 np.array(self.imgs2, dtypenp.float32)self.labels np.array(self.labels, dtypenp.float32)print(load down)def __getitem__(self, idx):return self.imgs1[idx], self.imgs2[idx], self.labels[idx]def __len__(self):return len(self.labels)需要注意的是PIL的图片维度与paddle CNN的维度不一样需要使用transpose改变
当然使用这个数据集类读取数据是非常漫长的因此我们创建了一个face_create_dataset.py创建数据集对象并保存到本地
from face_dataset import FaceData
import pickletrain_dataset FaceData(modetrain, num2000)
test_dataset FaceData(modetest, num200)pickle.dump(train_dataset, open(./database/train.data, wb), protocol4)
pickle.dump(test_dataset, open(./database/test.data, wb), protocol4) 这里我们使用pickle保存对象注意这里要指定protocol4以保证可以存储超过4G的大文件
最后这个脚本会在本地的database文件夹下生成两个data文件使用时只需要加载即可
孪生网络
既然要输入两张图片就自然需要使用两张卷积网络分别处理两张图片。但是人脸对比与输入顺序无关这就要求两个网络对于同一张图片的输出是相同的也就是这两个网络是相同的。即共享权重的网络。因此我们可以定义网络如下
class FaceNet(paddle.nn.Layer):def __init__(self):super().__init__()# 共享权重的cnn网络self.cnn paddle.nn.Sequential(paddle.nn.Conv2D(3, 16, 3, padding1),paddle.nn.ReLU(),paddle.nn.MaxPool2D(2, 2),paddle.nn.Conv2D(16, 32, 3, padding1),paddle.nn.ReLU(),paddle.nn.MaxPool2D(2, 2),paddle.nn.Conv2D(32, 64, 3, padding1),paddle.nn.ReLU(),paddle.nn.MaxPool2D(2, 2),paddle.nn.Conv2D(64, 128, 3, padding1),paddle.nn.ReLU(),paddle.nn.MaxPool2D(2, 2),paddle.nn.Flatten(),paddle.nn.Linear(4608, 5))def forward(self, face1, face2):# 前向传播使用cnn网络分别输出两个结果并返回n1r self.cnn(face1)n2r self.cnn(face2)return n1r, n2r
这个网络还需要有特殊的损失函数。这个损失函数将会使相同的人脸距离相近不同的人脸距离更远。我们采用勾股定理计算距离这样的距离也叫欧氏距离。
因此对于一个在n维空间上的两个点(x1, x2, x3, ..., xn), (y1, y2, y3, ..., yn)就有 因此如果人脸相同损失函数将会输出的损失值是 这样的话如果距离过远损失值就会偏大 从而使输出更接近0
如果人脸不同输出的损失值是 这样的话只有当距离比设定阈值远时损失才为0.
另外损失最好使用乘方而不是绝对值这样的话就可以增加远离时的梯度。
我们定义其损失函数如下
# 损失函数定义
class FaceLoss(paddle.nn.Layer):def __init__(self, margin(512 ** 0.5)):super(FaceLoss, self).__init__()self.margin margindef forward(self, output1, output2, label):# 计算欧式距离勾股定理euclidean_distance paddle.norm(output1 - output2, axis1)# 损失值# 在数据集中1为相同0为不同。但是输出要求相似的图片距离更近loss_contrastive label * paddle.square(euclidean_distance) \(1 - label) * paddle.square(paddle.maximum(self.margin - euclidean_distance, paddle.to_tensor(0.0)))# 损失函数应对同一批次取一个损失值return paddle.mean(loss_contrastive)
在paddle中可以使用paddle.norm计算距离。axis1表示只对第1维度计算距离因为第0维度是数据批次。
在数据集中我们定义1为相同0为不同。根据我们之前的分析很容易算出损失值的公式。
接下来就可以把这两个整合在一个py文件中起名face_layers.py
import paddleclass FaceNet(paddle.nn.Layer):def __init__(self):super().__init__()# 共享权重的cnn网络self.cnn paddle.nn.Sequential(paddle.nn.Conv2D(3, 16, 3, padding1),paddle.nn.ReLU(),paddle.nn.MaxPool2D(2, 2),paddle.nn.Conv2D(16, 32, 3, padding1),paddle.nn.ReLU(),paddle.nn.MaxPool2D(2, 2),paddle.nn.Conv2D(32, 64, 3, padding1),paddle.nn.ReLU(),paddle.nn.MaxPool2D(2, 2),paddle.nn.Conv2D(64, 128, 3, padding1),paddle.nn.ReLU(),paddle.nn.MaxPool2D(2, 2),paddle.nn.Flatten(),paddle.nn.Linear(4608, 5))def forward(self, face1, face2):# 前向传播使用cnn网络分别输出两个结果并返回n1r self.cnn(face1)n2r self.cnn(face2)return n1r, n2r# 损失函数定义
class FaceLoss(paddle.nn.Layer):def __init__(self, margin(512 ** 0.5)):super(FaceLoss, self).__init__()self.margin margindef forward(self, output1, output2, label):# 计算欧式距离勾股定理euclidean_distance paddle.norm(output1 - output2, axis1)# 损失值# 在数据集中1为相同0为不同。但是输出要求相似的图片距离更近loss_contrastive label * paddle.square(euclidean_distance) \(1 - label) * paddle.square(paddle.maximum(self.margin - euclidean_distance, paddle.to_tensor(0.0)))# 损失函数应对同一批次取一个损失值return paddle.mean(loss_contrastive)
训练
接下来我们需要编写训练脚本face.py
import paddle
from face_dataset import FaceData
from face_layers import FaceNet, FaceLoss
import pickle# 加载数据集
train_dataset pickle.load(open(./database/train.data, rb))
test_dataset pickle.load(open(./database/test.data, rb))# 输出数据集信息
print(f加载数据完毕训练集数据个数{len(train_dataset)}测试集数据个数{len(test_dataset)})count 0
for context1, context2, label in train_dataset:if label 1:count 1print(f训练集相同人脸个数{count})count 0
for context1, context2, label in test_dataset:if label 1:count 1print(f测试集相同人脸个数{count})# 指定设备
paddle.device.set_device(gpu)# 创建模型
model paddle.Model(FaceNet())# 打印模型信息
print(model.summary(((1, 3, 96, 96), (1, 3, 96, 96))))# 模型训练的配置准备准备损失函数优化器和评价指标
model.prepare(paddle.optimizer.Adam(parametersmodel.parameters(), learning_rate0.00001),FaceLoss())# 模型训练
model.fit(train_dataset, epochs50, batch_size64, verbose1)
# 模型评估
model.evaluate(test_dataset, batch_size64, verbose1)# 保存模型
model.save(./output/face-compare)这里需要注意我们需要使用FaceLoss作为损失函数
训练完毕后训练数据将被存储在本地的output文件夹下使用时加载即可
接下来我们可以编写face_use.py使用这个模型
import paddle
from face_dataset import FaceData
from face_layers import FaceNet
from PIL import Image
import numpy as np# 加载模型
model paddle.Model(FaceNet())
model.load(./output/face-compare)print(加载模型完毕)# 打开图片
pil_img1 Image.open(ffacecap\\003\\30.jpg).convert(RGB).resize((96, 96))
pil_img2 Image.open(ffacecap\\003\\27.jpg).convert(RGB).resize((96, 96))# 转np数组
np_img1 np.array(pil_img1, dtypenp.float32).transpose((2, 0, 1)) / 255.0
np_img2 np.array(pil_img2, dtypenp.float32).transpose((2, 0, 1)) / 255.0# 预测
pred model.predict_batch((np.array([np_img1], dtypenp.float32), np.array([np_img2], dtypenp.float32)))# 计算距离
euclidean_distance paddle.norm(paddle.to_tensor([pred[0]]) - paddle.to_tensor([pred[1]]))
print(euclidean_distance.numpy())这里只以两张相同人的人脸的图片做测试最后输出
加载模型完毕
[0.1978856]
改用两张不同人的人脸做测试最后输出
加载模型完毕
[1.1059165]
可以看到这个模型的效果还不错。但是经过我的多次测试发现这个模型还有一定的提升空间。这需要更大的数据集、更深的模型和更多的训练次数
总结
我们使用孪生网络技术成功实现了人脸对比模型并有一定的准确性可以应用于人脸比对等场景。但是由于数据集、模型和训练次数有限还难以实现更准确的人脸对比
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/910409.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!