
InsightFace in OneFlow基于 OneFlow 框架的人脸识别训练、验证与模型转换实战指南【免费下载链接】insightfaceState-of-the-art 2D and 3D Face Analysis Project项目地址: https://gitcode.com/GitHub_Trending/in/insightface本文以recognition/arcface_oneflow子项目为主体系统介绍如何基于 OneFlow 深度学习框架复现 InsightFace 人脸识别工作流从 OneFlow 环境安装、MS1M 数据集从 MXNet recordio 到 OFRecord 的转换到 ResNet100 / MobileFaceNet 骨干网络下的 ArcFace / CosFace 训练、LFW / CFP-FP / AgeDB-30 验证以及最终将模型导出为 ONNX 的完整链路。读完本文你将掌握这套基于 OneFlow 的人脸识别训练管线并能在自己的数据集上直接复现与扩展。背景InsightFace 与 OneFlow 的实现InsightFace 开源项目InsightFace 是基于 MXNet 实现的开源 2D 3D 深度人脸分析工具箱。在其原始实现中它集成了常用人脸识别数据集CASIA-Webface、MS1M、VGG2 等以 MXNet 可直接运行的二进制形式提供如 recordio 格式。多种骨干网络ResNet、MobileFaceNet、InceptionResNet_v2 等深度网络用于提取人脸特征。多种损失函数SphereFace Loss、Softmax Loss、ArcFace 等 Margin-based 损失实现。本仓库中的recognition/arcface_oneflow正是这一系列移植工作的核心目录它把 InsightFace 的人脸识别训练、验证链路完整迁移到了 OneFlow 上。InsightFace 在 OneFlow 中的实现基于 InsightFace 已有的工作成果OneFlow 移植了其基础人脸识别模型目前已经支持训练与验证数据集支持 MS1M、Glint360k 作为训练数据集LFW、CFP-FP 与 AgeDB-30 作为验证数据集并提供了对应的训练与验证脚本。骨干网络支持 ResNet100 与 MobileFaceNet 作为人脸识别模型的 Backbone。损失函数实现 Softmax Loss 以及 Margin Softmax Loss包括 Nsoftmax、ArcFace、CosFace 和 Combined Loss。分布式优化实现模型并行Model Parallelism与 Partial FC 优化。模型转换实现 MXNet 模型转换与 ONNX 导出。计划中还将逐步完善更多数据集转换、更丰富 Backbone、更全面的损失函数实现以及分布式配置的增量教程。准备工作在开始运行前需要确认两件事安装 OneFlow。准备训练与验证用的 OFRecord 数据集。安装 OneFlow按照 OneFlow 官方的安装指引安装最新的 master wheel 包即可python3 -m pip install oneflow -f https://oneflow-staging.oss-cn-beijing.aliyuncs.com/branch/master/cu102/6aa719d70119b65837b25cc5f186eb19ef2b7891/index.html --user注意上述安装命令对应的是 CUDA 10.2 的 master 分支 wheel。实际部署时请根据自身 CUDA 环境选择匹配的版本。准备数据集从 recordio 到 OFRecordInsightFace 原仓库中提供了一系列已完成人脸对齐等预处理的人脸识别数据集。OneFlow 需要的是 OFRecord 格式的数据。考虑到转换步骤繁琐可以直接下载已经转换好的 OFRecord 数据集MS1M-ArcFace (face_emore)MS1MV3下面以 MS1M-ArcFace 为例说明如何将原始数据集转换为 OFRecord 格式。1. 下载数据集下载好的 MS1M-ArcFace 数据集目录结构如下faces_emore/ train.idx train.rec property lfw.bin cfp_fp.bin agedb_30.bin前三个文件train.idx、train.rec、property是训练数据集 MS1M 的 MXNet recordio 格式文件后三个.bin文件分别是 LFW、CFP-FP、AgeDB-30 三个验证数据集。2. 将 MS1M 从 recordio 格式转换为 OFRecord 格式训练数据集的转换有两种方式2.1 直接使用 Python 脚本生成 n 个已 shuffle 的数据 part或2.2 Python 脚本 Spark Shuffle Spark Partition先生成单个 part再根据需要用 Spark 做 shuffle 与 partition。两者只需执行其一。2.1 直接使用 Python 脚本运行python tools/mx_recordio_2_ofrecord_shuffled_npart.py --data_dir datasets/faces_emore --output_filepath faces_emore/ofrecord/train --num_part 16成功后将得到num_part个 OFRecord 分片本示例为 16 个目录结构如下tree ofrecord/test/ ofrecord/test/ |-- _SUCCESS |-- part-00000 |-- part-00001 |-- part-00002 |-- part-00003 |-- part-00004 |-- part-00005 |-- part-00006 |-- part-00007 |-- part-00008 |-- part-00009 |-- part-00010 |-- part-00011 |-- part-00012 |-- part-00013 |-- part-00014 -- part-00015 0 directories, 17 files2.2 Python 脚本 Spark Shuffle Spark Partition先运行脚本生成一个包含全部数据的 OFRecordpart-0python tools/mx_recordio_2_ofrecord.py --data_dir datasets/faces_emore --output_filepath faces_emore/ofrecord/train然后使用 Spark 进行 Shuffle 与 Partition下载工具 jar 包通过 OneFlow 的 spark-oneflow-connector 项目下载spark-oneflow-connector-assembly-0.1.0.jar。运行 Spark 命令假设已安装并配置好 Spark// Start Spark ./spark-2.4.3-bin-hadoop2.7/bin/spark-shell --jars ~/spark-oneflow-connector-assembly-0.1.0.jar --driver-memory64G --conf spark.local.dir/tmp/ // shuffle and partition in 16 parts import org.oneflow.spark.functions._ spark.read.chunk(data_path).shuffle().repartition(16).write.chunk(new_data_path) sc.formatFilenameAsOneflowStyle(new_data_path)即可得到 16 个 part 的 OFRecord目录结构与 2.1 一致_SUCCESSpart-00000~part-00015共 17 个文件。说明文档中的转换脚本路径tools/mx_recordio_2_ofrecord_shuffled_npart.py与tools/mx_recordio_2_ofrecord.py在当前的 OneFlow 仓库本仓库为 InsightFace 的镜像目录结构见 tools/中对应为mx_recordio_2_ofrecord_shuffled_npart.py与mx_recordio_2_ofrecord.py调用参数保持一致。训练与验证为了降低用户的使用与迁移成本OneFlow 的训练脚本已调整为 Torch 风格用户可以直接通过configs/*.py配置文件修改参数无需改动训练代码。训练入口为 train.py其核心流程是解析配置文件 → 初始化日志与分布式环境 → 构建 Trainer包含骨干网络、FC 分类层、优化器、学习率调度、验证回调与 checkpoint 回调→ 根据--graph参数选择 Graph 模式或 DDP eager 模式执行训练。配置文件configs/*.py配置文件采用easydict的edict()组织所有训练超参数均以属性形式暴露。以 configs/base.py 为例关键参数如下参数含义示例值ms1mv3loss损失函数类型arcface/cosfacearcfacenetwork骨干网络r18/r34/r50/r100/r200/mbfr50resume是否从 checkpoint 恢复训练Falseoutput输出目录名ms1mv3_arcface_r50embedding_size特征嵌入维度512fp16是否启用混合精度训练False/Truemodel_parallel是否启用模型并行False/Truesample_ratePartial FC 的类别采样率1.0/0.1partial_fc是否启用 Partial FC 优化False/1graph是否使用 Graph 模式Truesynthetic是否使用合成数据纯性能测试Falsemomentum/weight_decaySGD 优化器参数0.9/5e-4batch_size单卡 batch size128lr初始学习率注释注明按 batch size 512 设定0.1ofrecord_pathOFRecord 数据集路径/dev/shm/ms1m-retinaface-t1/ofrecordofrecord_part_numOFRecord 分片数8/200num_classes类别数对应数据集身份数93431MS1M-RetinaFace-T1num_image训练图片总数5179510num_epoch总训练轮数25/30warmup_epochwarmup 轮数-1 表示关闭-1decay_epoch学习率衰减节点MultiStepLR 里程碑[11, 17, 22]val_targets验证数据集列表[lfw, cfp_fp, agedb_30]base.py中按config.dataset的不同取值emore、ms1m-retinaface-t1、glint360k、webface分别给出数据集路径、类别数、图片总数、epoch 与学习率衰减计划使用时只需切换config.dataset即可切换整套数据配置。更精简的示例见 configs/ms1mv3_mbf.pyMobileFaceNet Partial FC FP16 组合与 configs/glint360k_r50.pyGlint360k CosFace Partial FC 组合。骨干网络与损失函数的源码实现骨干网络recognition/arcface_oneflow/backbones/__init__.py的get_model通过名称r18/r34/r50/r100/r200返回 ir_resnet.py 中对应的iresnet18~iresnet200。IResNet 采用 IBasicBlockBN→Conv3x3→BN→PReLU→Conv3x3→BN 的残差结构输出 512 维特征nn.BatchNorm1d归一化后返回。损失函数recognition/arcface_oneflow/utils/losses.py实现了CosFace与ArcFace两个 Margin Loss 模块CosFace 直接在余弦相似度上减去 marginm再乘 scalesArcFace 则先对余弦值取反余弦加上 margin 后再取余弦并乘 scale。训练时二者均与交叉熵CrossEntropyLoss_sbp组合使用。训练eager 模式DDP./train_ddp.shtrain_ddp.sh通过python3 -m oneflow.distributed.launch启动分布式训练默认 8 卡DEVICE_NUM_PER_NODE8配置MASTER_ADDR127.0.0.1、MASTER_PORT17788执行train.py configs/ms1mv3_r50.py。在 eager 模式下Trainer.train_eager()会用flow.nn.parallel.DistributedDataParallel包装模型前向计算 logits → CombinedMarginLoss×64 → 交叉熵 → 反向传播 → 优化器 step并在每步调用验证回调与 logging 回调。训练Graph 模式./train_graph_distributed.sh与 eager 脚本的唯一区别是在train.py后追加了--graph参数。在 Graph 模式下train.py会通过flow.nn.Graph构建静态图训练管线见 graph.py 中的TrainGraphbuild()中执行数据加载 → 模型前向 → CombinedMarginLoss×64 → 交叉熵 → backward并可自动启用 AMPfp16时开启enable_amp与动态 GradScaler以及算子融合allow_fuse_add_to_output、allow_fuse_model_update_ops。模型并行时FC 层通过FC7按world_size切分权重并以sbp.split(0)放置见 function.py。验证val.py为了方便查看已保存预训练模型的精度项目提供了仅执行验证的脚本 val.py./val.shval.sh内部执行python val.py configs/ms1mv3_r50 --model_path eager_test/epoch_0val.py会加载指定 checkpoint剔除num_batches_tracked与fc.weight权重将backbone.前缀剥离后加载到骨干网络中再通过EvalGraph在 LFW、CFP-FP、AgeDB-30 上完成验证。这得益于训练过程中 function.py 注册的CallBackVerification每 600 步触发一次验证与CallBackModelCheckpoint每轮保存 checkpoint回调。OneFlow2ONNX模型导出训练并验证完成后可将 OneFlow 模型导出为 ONNX便于在 ONNX Runtime 等推理引擎中部署pip install oneflow-onnx0.5.1 ./convert.shconvert.sh内部执行python3 oneflow2onnx.py configs/ms1mv3_r50 --model_path /workdir/epoch_0oneflow2onnx.py 的转换流程是按配置构建骨干网络get_model将网络包装为flow.nn.Graph并用flow.randn(1, 3, 112, 112)编译一次以确定静态图加载 checkpoint 并剥离backbone.前缀与 FC 层权重最后调用oneflow_onnx的convert_to_onnx_and_check完成转换与校验。输入图片尺寸默认 112×112--image_size输出目录默认onnx_model--out_path。结语recognition/arcface_oneflow为开发者提供了一条从数据准备、分布式训练、精度验证到 ONNX 导出的完整 OneFlow 人脸识别链路其 Torch 风格的配置与训练脚本大幅降低了迁移成本同时 Graph 模式、模型并行与 Partial FC 又为大规模身份识别如 Glint360k 的 36 万类别提供了性能保障。你可以基于 configs/ 下的配置模板替换为自己的 OFRecord 数据集与骨干网络组合快速复现并扩展这套训练管线。【免费下载链接】insightfaceState-of-the-art 2D and 3D Face Analysis Project项目地址: https://gitcode.com/GitHub_Trending/in/insightface创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考