前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >实战:人脸识别的Arcface实现 | CSDN博文精选

实战:人脸识别的Arcface实现 | CSDN博文精选

作者头像
AI科技大本营
发布2019-10-28 12:09:41
8.3K0
发布2019-10-28 12:09:41
举报
文章被收录于专栏:AI科技大本营的专栏
来源 | CSDN博客

本文将简单讲述arcface从训练到部署的整个过程,主要包括前期的数据筛选和准备,模型训练以及模型部署。

此文参考的arcface的代码地址:

https://github.com/ronghuaiyang/arcface-pytorch

数据集准备

1. 首先准备需要训练的人脸数据

并按照每个人一个文件夹的形式将人脸照片保存起来,为了使人脸更符合亚洲人的特征应该尽量多的采用亚洲人来你的图片训练。

每个文件夹中最少要有两张或者是两张以上的人脸照片,也就是说训练集中每个人脸最少存在两张。图片保存形式如下图所示:

2. 将人脸数据中的人脸部分提取出来并对其

代码中假定的是人脸的数据已经剪裁并对齐,但是在实际的应用中一般拿到的都是普通的人脸的照片,需要将人脸照片进行剪裁并将不是正脸对着正前方的人脸照片仿射变换成正脸面对的照片。

opencv中提供了几种人脸检测的方法,并且在dlib中已经封装好,在速度和准确度上已经达到很好的效果,可以直接调用软件包。

具体几种人脸检测的方法以及对比可以参考网页:https://www.learnopencv.com/face-detection-opencv-dlib-and-deep-learning-c-python/

以dlib中的cnn为例采用下面代码可以将文件夹中的人脸全部对齐并重新保存在另外一个文件夹中。

代码语言:javascript
复制
import dlib, os, cv2
from tqdm import tqdm
import shutil
FaceDeteModel_Type = 'cnn'
FaceDeteModel_Path='mmod_human_face_detector.dat'
FaceShapeModel_Path = 'shape_predictor_68_face_landmarks.dat'
if FaceDeteModel_Type == 'cnn':
    detector = dlib.cnn_face_detection_model_v1(FaceDeteModel_Path)
else:
    detector = dlib.get_frontal_face_detector()
sp = dlib.shape_predictor(FaceShapeModel_Path)


def FaceDeteAlign_CNN(img):
    if isinstance(img, str):
        img = cv2.imread(img)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    if img.shape[0] * img.shape[1] > 2500000:
        img = cv2.resize(img, (0, 0), fx=0.5, fy=0.5)

    imgsize = img.shape[0] * img.shape[1]
    dets = detector(img, 0)
    if len(dets) == 0:
        print('未检测到人脸,请重拍')
        return
    else:
        proposal_dets = []
        for i, d in enumerate(dets):
            if d.confidence > 0.6:
                proposal_dets.append(d)

        if len(proposal_dets) == 0:
            print('人脸质量不佳,请重拍')
            return
        det = max(proposal_dets, key=(lambda d: d.rect.width() * d.rect.height()))
        if det.rect.width() * det.rect.height() / imgsize <= 1/60:
            print('未检测到人脸,请重拍')
            return
        faces = dlib.full_object_detections()
        rec = dlib.rectangle(det.rect.left(), det.rect.top(), det.rect.right(), det.rect.bottom())
        faces.append(sp(img, rec))
        image = dlib.get_face_chip(img, (faces[0]), size=128)
        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        return image

path = '/data/tangsh/face_data/train_celebrity/lfw'
save_path = '/data/tangsh/face_data/train_celebrity/align_flw'
img_file = os.listdir(path)
i = 0
try:
    for file in tqdm(img_file):
        img_path = os.listdir(os.path.join(path, file))
        os.system('mkdir(os.path.join(save_path, file))')
        for img_name in img_path:
            align_img = FaceDeteAlign_CNN(os.path.join(path, file, img_name))
            if align_img is not None:
                save_file = os.path.join(save_path, file)
                if not os.path.exists(save_file):
                    os.makedirs(save_file)
                print(os.path.join(save_file, img_name))
                cv2.imwrite(os.path.join(save_file, img_name), align_img)
            else:
                i = i+1
                print('thr count of none align face', i)
except Exception as error:
    print(error)

# 判断当前目录下文件夹里面的图片个数 如果图片的个数少于3删除文件夹

img_file = os.listdir(save_path)
print("len", len(img_file))
for file in tqdm(img_file):
    img_path = os.listdir(os.path.join(save_path, file))
    print("length", len(img_path))
    if len(img_path) < 3:
        shutil.rmtree(os.path.join(save_path, file))

    # for img_name in img_path:
    #     os.listdir(os.path.join(path, file))

其中用到的模型参数可以在上面提供的人脸检测网页中下载

3. 接下来是将训练集中图片路径和label保存在一个指定的文件中

代码中train.py中有一段代码如下:

代码语言:javascript
复制
opt = Config()
if opt.display:
    visualizer = Visualizer()
device = torch.device("cuda")

train_dataset = Dataset(opt.train_root, opt.train_list, phase='test', input_shape=opt.input_shape)
# Dataset中输入的数据为opt.train_root 数据存放的路径, opt.train_list 每行为训练数据的图片名字 图片的label

其中Dataset函数的一个参数是数据集的路径,第二个参数是数据集中图片对应的路径以及label保存,文件内容如下:

每行包括两个元素,第一个是数据集下每个图片的路径,第二个参数是图片对应的label。

具体生成该文件可以参照以下代码:

代码语言:javascript
复制
import os

f = open('img_train.txt','w')
path = '/data2/fengms/arcface-pytorch-master/data/Datasets/webface/align'
img_file = os.listdir(path)
print("len", len(img_file))
label = 0
for file in img_file:
    img_path = os.listdir(os.path.join(path, file))
    for img  in img_path:
        new_context = os.path.join(file, img) + " " + str(label) +  '\n'
        print(new_context)
        f.write(new_context)
    label = label + 1

f.close()

到目前为止训练集的数据已经准备好。同理如果需要验证集以及flw数据集按照同样的方法设置。

训练代码

训练代码之前需要在data目录下创建Datasets目录,分别放入训练数据集文件夹webface以及验证数据集flw。每个文件夹下分别放入数据集文件夹 以及训练和测试图片的路径 以及label保存的txt文件。特别注意flw文件夹中放入的txt文件为 lfw_test_pair.txt,该文件夹在作者提供的代码中有保存。

接下来就是修改config.py文件中的配置

代码语言:javascript
复制
backbone = 'resnet50' #选用的网络结构
classify = 'softmax'
num_classes = 10001 #等于人脸中类别的个数,大于或者小于报错
metric = 'arc_margin'
easy_margin = False
use_se = False
loss = 'focal_loss'

display = False
finetune = False

train_root = '/data2/fengms/arcface-pytorch-master/data/Datasets/webface/align'
train_list = '/data2/fengms/arcface-pytorch-master/data/Datasets/webface/img_info.txt'
val_list = '/data/Datasets/webface/val_data_13938.txt'

test_root = '/data1/Datasets/anti-spoofing/test/data_align_256'
test_list = 'test.txt'

lfw_root = '/data2/fengms/arcface-pytorch-master/data/Datasets/lfw/align_flw'
lfw_test_list = '/data2/fengms/arcface-pytorch-master/data/Datasets/lfw/lfw_test_pair.txt'

checkpoints_path = 'checkpoints'
load_model_path = 'models/resnet18.pth'
test_model_path = 'checkpoints/resnet18_110.pth'
save_interval = 10

需要注意的是选用的网络结构改变的时候需要修改网络结果中self.fc5中的参数值,因为不同网络在同样输入大小的时候全卷积层输出的特征图的大小是不一致的,因此将特征图平铺之后形成的向量大小是不一致的。

例如我选用的训练网络结构为resnet50,resnet.py中代码修改如下:

代码语言:javascript
复制
    self.layer1 = self._make_layer(block, 64, layers[0], stride=2)
    self.layer2 = self._make_layer(block, 128, layers[1], stride=2)
    self.layer3 = self._make_layer(block, 256, layers[2], stride=2)
    self.layer4 = self._make_layer(block, 512, layers[3], stride=2)
    # self.avgpool = nn.AvgPool2d(8, stride=1)
    # self.fc = nn.Linear(512 * block.expansion, num_classes)
    self.fc5 = nn.Linear(512 * 16 * 16, 512) # 选用不同的网络时需要修改。

当输入图片的大小为128的时候经过全卷积操作layer4输出的特征图的大小是16*16

当数据集准备好以及参数配置好后,需要创建checkpoints文件夹用于保存模型。之后安装一些必要的包torch torchvision等等 。

安装完环境后就能正常运行了python train.py

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-10-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 AI科技大本营 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
人脸识别
腾讯云神图·人脸识别(Face Recognition)基于腾讯优图强大的面部分析技术,提供包括人脸检测与分析、比对、搜索、验证、五官定位、活体检测等多种功能,为开发者和企业提供高性能高可用的人脸识别服务。 可应用于在线娱乐、在线身份认证等多种应用场景,充分满足各行业客户的人脸属性识别及用户身份确认等需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档