1.项目简介
本项目实现人脸识别系统。项目基本思路如下:对于输入的图片,首先通过MTCNN网络进行人脸检测,获取到人脸图片,然后使用insightface进行人脸特征提取,比较数据库中的数据,识别出人脸。项目结构如图所示:
图1 人脸识别系统结构
首先需要训练mtcnn网络,识别人脸检测。MTCNN网络的训练在《MTCNN算法理解及实现》中已经实现,这里直接使用训练好的模型即可。对于insightface,需要对insightface进行训练。
本项目使用的环境为:ubuntu16.04+RTX2070S。
2.项目实现流程
2.1数据处理
2.1.1训练数据处理
项目中使用CASIA-Webface数据,下载后的数据有如下文件:
其中,train.idx以及train.rec是用于训练的数据,其余的bin文件都是测试数据集。
首先,创建utils文件夹,里面存放的都是项目使用的公共组件,其中全局的配置在config.py文件中,代码如下:
1 import os 2 3 4 # prepare_data parameters 5 mxdata_dir = "./data" 6 tfrecord_dir = "./data/CASIA.tfrecords" 7 lfw_dir = './data/lfw' 8 lfw_save_dir = './data/lfw_face' 9 eval_dir = './data/lfw_face.db' 10 eval_datasets_self = ['./data/lfw_face.db'] 11 eval_datasets = ["./data/lfw.bin", "./data/agedb_30.bin", "./data/calfw.bin", 12 "./data/cfp_ff.bin", "./data/cfp_fp.bin", "./data/cplfw.bin", './data/lfw_face.db'] 13 14 15 # model parameters 16 model_params = {"backbone_type": "resnet_v2_m_50", 17 "out_type": "E", 18 "bn_decay": 0.9, 19 "weight_decay": 0.0005, 20 "keep_prob": 0.4, 21 "embd_size": 512} 22 23 24 # training parameters 25 s = 64.0 26 m = 0.5 27 class_num = 85742 28 lr_steps = [40000, 60000, 80000] 29 lr_values = [0.004, 0.002, 0.0012, 0.0004] 30 momentum = 0.9 31 addrt = "./data/CASIA.tfrecords" 32 model_patht = "./model/Arcface_model" 33 img_size = 112 34 batch_size = 128 35 addr = "../data/CASIA.tfrecords" 36 model_name = "Arcface" 37 train_step = 1000001 38 model_path = "../model/Arcface_model" 39 gpu_num = 2 40 model_save_gap = 30000 41 42 43 # evaluation parameters 44 eval_dropout_flag = False 45 eval_bn_flag = False 46 47 48 # face database parameters 49 custom_dir = '../data/custom' 50 arc_model_name = 'Arcface-330000' 51 arc_model_path = './model/Arcface_model/Arcface-330000' 52 53 base_dir = './model/MTCNN_model' 54 mtcnn_model_path = [os.path.join(base_dir, "Pnet_model/Pnet_model.ckpt-20000"), 55 os.path.join(base_dir, "Rnet_model/Rnet_model.ckpt-40000"), 56 os.path.join(base_dir, "Onet_model/Onet_model.ckpt-40000")] 57 embds_save_dir = "../data/face_db"
因为数据是以mxnet格式存储的,因此首先需要将数据转换成TFrecord格式,在项目根目录下创建gen_tfrecord_mxdata.py文件,代码如下:
1 import tensorflow as tf 2 import mxnet as mx 3 import os 4 import io 5 import numpy as np 6 import cv2 7 import time 8 from scipy import misc 9 import argparse 10 from utils import config 11 12 13 def arg_parse(): 14 15 parser = argparse.ArgumentParser() 16 parser.add_argument("--read_dir", default=config.mxdata_dir, type=str, help='directory to read data') 17 parser.add_argument("--save_dir", default=config.tfrecord_dir, type=str, help='path to save TFRecord file') 18 19 return parser.parse_args() 20 21 22 def main(): 23 24 with tf.python_io.TFRecordWriter(save_dir) as writer: 25 idx_path = os.path.join(read_dir, 'train.idx') 26 bin_path = os.path.join(read_dir, 'train.rec') 27 imgrec = mx.recordio.MXIndexedRecordIO(idx_path, bin_path, 'r') 28 s = imgrec.read_idx(0) 29 header, _ = mx.recordio.unpack(s) 30 imgidx = list(range(1, int(header.label[0]))) 31 labels = [] 32 for i in imgidx: 33 img_info = imgrec.read_idx(i) 34 header, img = mx.recordio.unpack(img_info) 35 label = int(header.label) 36 labels.append(label) 37 img = io.BytesIO(img) 38 img = misc.imread(img).astype(np.uint8) 39 img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR) 40 img_raw = img.tobytes() 41 42 example = tf.train.Example(features=tf.train.Features(feature={ 43 "img": tf.train.Feature(bytes_list=tf.train.BytesList(value=[img_raw])), 44 "label": tf.train.Feature(int64_list=tf.train.Int64List(value=[label])), 45 })) 46 47 writer.write(example.SerializeToString()) 48 49 if i % 10000 == 0: 50 print('%d pics processed' % i, "time: ", time.time()-begin) 51 52 53 if __name__ == "__main__": 54 55 parser = arg_parse() 56 57 save_dir = parser.save_dir 58 read_dir = parser.read_dir 59 60 begin = time.time() 61 62 main()
通过以上代码,将mxnet格式的训练数据转换成TFRecord格式的数据。
ArcFace loss的分析以及代码见insightface介绍,