• insightface pytorch 答疑指南


    之前写过一篇人脸识别从原理到实践 详细介绍了人脸识别相关的算法、模型和Loss等,里面也提到insightface成为当前工业事实上的基准。但是它各种牛逼,唯一不足的点就是开始时选了mxnet框架开发,奈何现在基本没什么人用了,所以在22年3月官方悄悄的把主线版本特别是PartialFC的实现换成了pytorch,而且更早之前经历过一次大的文件结构调整,加入了paddle、oneflow等很多框架的实现,但是也导致很多之前教程给的路径都找不到了,还有一些文件直接就删除了,这对于新入手造成了很大的困扰。我是非常反对这种开发中途变更,对于新出的算法新开个仓库就是了,估计为了涨star。作者过佳曾在 InsightFace大规模人脸识别 进行过讲解。

    刚开始相信大家一定和我一样有数不清的疑惑,首先是怎么安装和运行,虽然主线版本切了pytorch,但是数据集制作用的还是mxnet,而mxnet又疏于维护,存在非常多的坑,特别是对于30x0系列的新显卡,装上后各种问题。目前我用的CUDA版本为11.3,用Anaconda装的python3.8,mxnet1.7之前的默认是不需要nccl(用于显卡并行通信的库)的,1.8之后需要另外安装nccl库,版本为2.8.4

    1. conda install cudatoolkit=11.3 cudnn --channel https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/Paddle/
    2. pip install torch==1.11.0+cu113 torchvision==0.12.0+cu113 -f https://download.pytorch.org/whl/cu113/torch_stable.html
    3. pip install mxnet-cu112==1.8.0.post
    4. pip install paddlepaddle-gpu==2.2.2.post110 -f https://www.paddlepaddle.org.cn/whl/linux/mkl/avx/stable.html

    装好后就可以体验下人脸识别系统的效果啦基于insightface实现的人脸识别和人脸注册

    1. pip install Cython insightface==0.6.2
    2. pip install onnxruntime-gpu -i https://mirror.baidu.com/pypi/simple

    也可以参考insight-face-paddle ,对应的视频教程

    看到效果这么好,是不是想自己训一个模型,那怎么训练呢?

    其实人脸识别真正的入口在arcface_torch 数据集下载链接,具体每个数据集的统计指标如下

    人脸识别常用数据集对比

    下载后数据后配置RAM,也就是把数据放到内存里,这里训练主机有256G内存,切出140G用于存放数据(为什么140呢?因为glint360k占的空间是那么大),这里以MS1MV2为例

    1. sudo mkdir /train_tmp
    2. sudo mount -t tmpfs -o size=140G tmpfs /train_tmp
    3. sudo cp data/faces_emore /train_tmp/ -r

     用下面的代码就可以愉快的开始训练了,单机器8卡V100需要约8个小时,训练速度是10000张/秒,也就是每天能训8.64亿张图,非常恐怖的数字,所以如果你的数据达不到1000张每秒每卡的话可能就需要检查下配置是不是出了什么问题了.

    1. cd recognition/arcface_torch
    2. python -m torch.distributed.launch --nproc_per_node=1 --nnodes=1 --node_rank=0 --master_addr="127.0.0.1" --master_port=12581 train.py configs/ms1mv2_mbf.py

    训练过程中每个2000个iter会在测试集上评估当前的精度,如日志ms1mv2_mbf/training.log

    1. Training: 2022-04-10 23:14:04,187-rank_id: 0
    2. Training: 2022-04-10 23:14:18,205-: margin_list [1.0, 0.5, 0.0]
    3. Training: 2022-04-10 23:14:18,205-: network mbf
    4. Training: 2022-04-10 23:14:18,205-: resume False
    5. Training: 2022-04-10 23:14:18,205-: output work_dirs/ms1mv2_mbf
    6. Training: 2022-04-10 23:14:18,205-: embedding_size 512
    7. Training: 2022-04-10 23:14:18,205-: sample_rate 1.0
    8. Training: 2022-04-10 23:14:18,205-: interclass_filtering_threshold0
    9. Training: 2022-04-10 23:14:18,205-: fp16 True
    10. Training: 2022-04-10 23:14:18,205-: batch_size 128
    11. Training: 2022-04-10 23:14:18,206-: optimizer sgd
    12. Training: 2022-04-10 23:14:18,206-: lr 0.1
    13. Training: 2022-04-10 23:14:18,206-: momentum 0.9
    14. Training: 2022-04-10 23:14:18,206-: weight_decay 0.0001
    15. Training: 2022-04-10 23:14:18,206-: verbose 2000
    16. Training: 2022-04-10 23:14:18,208-: frequent 10
    17. Training: 2022-04-10 23:14:18,208-: dali False
    18. Training: 2022-04-10 23:14:18,208-: rec /train_tmp/faces_emore
    19. Training: 2022-04-10 23:14:18,208-: num_classes 85742
    20. Training: 2022-04-10 23:14:18,208-: num_image 5822653
    21. Training: 2022-04-10 23:14:18,208-: num_epoch 40
    22. Training: 2022-04-10 23:14:18,208-: warmup_epoch 0
    23. Training: 2022-04-10 23:14:18,208-: val_targets ['lfw', 'cfp_fp', 'agedb_30']
    24. Training: 2022-04-10 23:14:18,210-: total_batch_size 1024
    25. Training: 2022-04-10 23:14:18,210-: warmup_step 0
    26. Training: 2022-04-10 23:14:18,210-: total_step 227440
    27. ...
    28. Training: 2022-04-10 23:18:56,638-[lfw][2000]XNorm: 20.481429
    29. Training: 2022-04-10 23:18:56,638-[lfw][2000]Accuracy-Flip: 0.96000+-0.00853
    30. Training: 2022-04-10 23:18:56,641-[lfw][2000]Accuracy-Highest: 0.96000
    31. Training: 2022-04-10 23:19:21,795-[cfp_fp][2000]XNorm: 18.461583
    32. Training: 2022-04-10 23:19:21,795-[cfp_fp][2000]Accuracy-Flip: 0.75300+-0.02095
    33. Training: 2022-04-10 23:19:21,796-[cfp_fp][2000]Accuracy-Highest: 0.75300
    34. Training: 2022-04-10 23:19:43,475-[agedb_30][2000]XNorm: 19.645099
    35. Training: 2022-04-10 23:19:43,476-[agedb_30][2000]Accuracy-Flip: 0.81717+-0.02153
    36. Training: 2022-04-10 23:19:43,476-[agedb_30][2000]Accuracy-Highest: 0.81717
    37. ...
    38. ...
    39. Training: 2022-04-11 07:17:07,878-[lfw][226000]XNorm: 7.635595
    40. Training: 2022-04-11 07:17:07,878-[lfw][226000]Accuracy-Flip: 0.99717+-0.00289
    41. Training: 2022-04-11 07:17:07,879-[lfw][226000]Accuracy-Highest: 0.99750
    42. Training: 2022-04-11 07:17:32,307-[cfp_fp][226000]XNorm: 6.540276
    43. Training: 2022-04-11 07:17:32,308-[cfp_fp][226000]Accuracy-Flip: 0.95586+-0.01115
    44. Training: 2022-04-11 07:17:32,308-[cfp_fp][226000]Accuracy-Highest: 0.95943
    45. Training: 2022-04-11 07:17:53,429-[agedb_30][226000]XNorm: 7.491025
    46. Training: 2022-04-11 07:17:53,429-[agedb_30][226000]Accuracy-Flip: 0.97050+-0.00730
    47. Training: 2022-04-11 07:17:53,430-[agedb_30][226000]Accuracy-Highest: 0.97183

    用官方提供的数据集训的都挺不错的,可是一旦放到实际中使用,就会出现各种各样的问题,这时就需要自己搜集数据了,具体可参见人脸识别之insightface开源代码使用:训练、验证、测试(2)​​​​​​​但是其用的都是旧代码,新代码直接用mxnet的im2rec就可以了,具体可参见prepare_webface42m 请注意这里存的都是检测后并且对齐的人脸图,大小为112x112

    1. ├── 0_0_0000000
    2. │   ├── 0_0.jpg
    3. │   ├── 0_1.jpg
    4. │   ├── 0_2.jpg
    5. │   ├── 0_3.jpg
    6. │   └── 0_4.jpg
    7. ├── 0_0_0000001
    8. │   ├── 0_5.jpg
    9. │   ├── 0_6.jpg
    10. │   ├── 0_7.jpg
    11. │   ├── 0_8.jpg
    12. │   └── 0_9.jpg
    13. ├── 0_0_0000002
    14. │   ├── 0_10.jpg
    15. │   ├── 0_11.jpg
    16. │   ├── 0_12.jpg
    17. │   ├── 0_13.jpg
    18. │   ├── 0_14.jpg
    19. │   ├── 0_15.jpg
    20. │   ├── 0_16.jpg
    21. │   └── 0_17.jpg
    22. ├── 0_0_0000003
    23. │   ├── 0_18.jpg
    24. │   ├── 0_19.jpg
    25. │   └── 0_20.jpg
    26. ├── 0_0_0000004
    1. # 1) create train.lst using follow command
    2. python -m mxnet.tools.im2rec --list --recursive train WebFace42M_Root
    3. # 2) create train.rec and train.idx using train.lst using following command
    4. python -m mxnet.tools.im2rec --num-thread 16 --quality 100 train WebFace42M_Root

    验证在训练过程中就已经评估了,具体做了哪些工作可参见人脸识别之insightface开源代码使用:训练、验证、测试(3)

    最后就是部署使用了人脸识别之insightface开源代码使用:训练、验证、测试(4)

    Partial FC是近来比较大的更新,可以看下论文理解详细解读

    如果去找工作,肯定免不了被人问arcloss是怎么实现的,这块可参考

    insightface源码中arcface代码段理解 

    手撕代码insightFace中的arcface_torch

    insightface 中 Partical_FC源码学习​​​​​​​

    1. def sample(self, total_label):
    2. """
    3. Sample all positive class centers in each rank, and random select neg class centers to filling a fixed
    4. `num_sample`.
    5. total_label: tensor
    6. Label after all gather, which cross all GPUs.
    7. """
    8. ### 当前GPU负责[self.class_start, self.class_start + self.num_local)的这些正类
    9. index_positive = (self.class_start <= total_label) & (total_label < self.class_start + self.num_local)
    10. total_label[~index_positive] = -1 # 不属于当前GPU负责的正类
    11. total_label[index_positive] -= self.class_start # 当前GPU的类标号从0开始
    12. if int(self.sample_rate) != 1:
    13. positive = torch.unique(total_label[index_positive], sorted=True) # 找到当前batch出现的当前GPU负责的正类标签
    14. if self.num_sample - positive.size(0) >= 0: # 当前GPU负责的负类个数
    15. perm = torch.rand(size=[self.num_local], device=self.device) # 均匀分布,[0,1]之间随机数,选择每类的概率
    16. # [0.5470, 0.5663, 0.5749, 0.5003, 0.5056, 0.4121, 0.4119, 0.7815, 0.1450, 0.8829, 0.0609, 0.9660]
    17. perm[positive] = 2.0 # 将positive设置为2,下一步排序会被选上
    18. # [0.9709, 2.0000, 0.5654, 2.0000, 0.8771, 2.0000, 0.1031, 0.4720, 0.4122, 0.6403, 0.0315, 0.7885]
    19. index = torch.topk(perm, k=self.num_sample)[1]
    20. # 假设sample_rate=0.5, int(13*0.5)=6, 从所有类中选出6类,期中positive已确定,negative按照之前的顺序选3
    21. # [2.0000, 2.0000, 2.0000, 0.9709, 0.8771, 0.7885]
    22. # [ 3, 5, 1, 0, 4, 11]
    23. index = index.sort()[0]
    24. # tensor([ 0, 1, 3, 4, 5, 11])
    25. else:
    26. index = positive
    27. self.index = index
    28. # torch.searchsorted(sorted_sequence, values):找到values在sorted_sequence中的位置
    29. # right=False(默认),与左边值作比较;right=True,与右侧值作比较
    30. # 需要在已排序好的数组中作比较
    31. # 将当前GPU的label放入整个GPU中
    32. total_label[index_positive] = torch.searchsorted(index, total_label[index_positive])
    33. self.sub_weight = Parameter(self.weight[index])
    34. self.sub_weight_mom = self.weight_mom[index]

  • 相关阅读:
    Mybatis中Like 的三种使用方式
    5分钟搞懂MySQL - 行转列
    轻松学会结构栈
    Vuex的简介以及入门案例
    召回阶段的相关模型
    代码以功能为单位
    可视化+多人协同技术原理和案例分享
    汽车社媒营销创新玩法,品牌“自爆”不走寻常路
    vulnhub靶场之PYLINGTON: 1
    Kubernetes 词条总结
  • 原文地址:https://blog.csdn.net/minstyrain/article/details/126901471