YOLOv8人脸检测实战:从数据集准备到模型训练部署全流程

📅 2026/8/27 14:44:52
YOLOv8人脸检测实战:从数据集准备到模型训练部署全流程
简介目标检测是计算机视觉的核心任务YOLO系列作为实时检测的经典框架在工程实践中应用广泛。YOLOv8采用Anchor-Free、解耦头等设计在精度与速度之间取得了良好平衡适合作为通用检测平台。在人脸检测场景中数据集质量、标注格式转换、环境配置与参数调优往往比模型结构更影响最终效果。本文从零开始梳理基于YOLOv8做人脸检测的完整链路涵盖WIDER FACE数据集清洗与转换、训练脚本参数解读、常见报错速查、性能优化及ONNX/TensorRT部署思路帮助开发者避开文档中未写明的工程陷阱快速落地人脸检测应用。 上个月我把一个“基于YOLOv8的人脸检测Python源码运行说明”的项目包分享了出去结果私信里一半以上都在问同一个问题环境装好了、命令也敲了怎么就是跑不起来或者好不容易跑通了检测效果却跟演示视频差了一大截。其实这些问题翻来覆去就那么几个原因数据集没准备好、参数不对、路径踩坑、格式转换出错。今天我就借这个项目把从数据集整理、环境配置、模型训练到最终推理的完整过程连同那些文档里不会写的坑一次性说清楚。这个项目最适合两类人一是刚接触YOLOv8、想用它做目标检测但又不想从零看论文的初学者尤其想拿人脸检测当练手二是已经在用YOLOv8做其他检测任务、想快速切换到人脸场景的开发者。如果你属于其中任何一类这篇文章基本可以当一份带避坑注释的实操手册来用。1. 为什么选YOLOv8做人脸检测1.1 人脸检测方案对比先聊几句方案选型。人脸检测这个方向太老了老到有很多“前辈方案”绕都绕不开。传统方法里最有名的是OpenCV自带的Haar Cascade几十行代码就能跑但一到遮挡、大角度侧脸、光线复杂点的场景漏检率直接放飞自我。后来有HOGSVM鲁棒性还是有限。深度学习起来之后MTCNN、RetinaFace、SCRFD这些专做人脸的模型精度都不错尤其RetinaFace在WIDER FACE榜单上很能打。但如果你把需求放宽一点——比如后面还想做行人检测、车牌检测、或者一个项目里同时检测多种目标那专做人脸的那套就有点锁死场景了。YOLOv8属于通用目标检测框架人脸只是它众多可用场景里的一种。你只需要把数据集换成脸训练流程、推理脚本、部署方案全都能复用。这也是我最后选YOLOv8的原因它不是一个“人脸检测模型”而是一个能做人脸检测的通用平台性价比高得多。Ultrlytics官方在2023年初发布YOLOv8的时候把之前v5系列里成熟的设计几乎都重构了一遍。对比v5最明显的变化是三点从Anchor-Based改成Anchor-Free省掉了锚框聚类和大量的候选框计算Backbone里的C3模块换成了C2f模块梯度流更丰富小目标特征提取能力有提升检测头拆成解耦头分类和回归分支分开收敛更稳定。这几个改动叠加下来同样的推理耗时下精度普遍比v5高了一截尤其在小脸、密集人脸这类场景里差距很明显。1.2 项目整体结构与模块划分我这个项目包解压之后目录结构是这样的face-detection-yolov8/ ├── dataset/ │ ├── images/ │ │ ├── train/ │ │ └── val/ │ └── labels/ │ ├── train/ │ └── val/ ├── runs/ │ └── detect/ ├── scripts/ │ ├── split_dataset.py │ └── convert_wider_to_yolo.py ├── face.yaml ├── train.py ├── detect.py └── README.mdtrain.py是训练入口内部封装了YOLOv8的train调用传参比命令行更灵活detect.py是推理脚本支持单张图片、图片文件夹、视频文件、摄像头实时检测四种模式face.yaml是数据集配置文件指定了训练集、验证集路径和类别名scripts下放的是辅助脚本一个是WIDER FACE数据集转YOLO格式一个是训练集/验证集划分。这个结构的取舍点是“开箱即用”和“不过度封装”之间的平衡。我见过很多项目把功能封得特别深点一个run.py全搞定出了问题根本不知道在哪一层。我也见过直接把YOLO官方仓库原样扔出来用户还得自己去翻命令行文档。这个项目选择了中间路线把最常用的两种编程方式——训练和推理——用Python脚本暴露出来参数直接写在顶部改起来方便查错也不难。1.3 为什么要把“运行说明”当一等公民项目包里那份运行说明README.md我写了将近两千字很多人觉得文档嘛随便写写就行。但实际经验告诉我源码分享类项目最大的门槛压根不是模型效果而是“用户能不能顺利把环境跑起来”。我有一次在交流群里看到一个老哥问“为什么你的代码我跑起来全是乱码”最后发现是README里忘了写Python版本要求他用Python 3.12跑一个只兼容3.8的老项目不炸才怪。所以运行说明里我固定写清楚这几块硬件要求CPU也能跑但慢GPU建议显存多少、Python版本范围、依赖安装命令、训练命令、推理命令、常见FAQ。后面第3节我会把这几部分的实际内容展开讲。2. 数据集准备人脸检测的核心工程2.1 用现成数据集还是自建数据集如果你只是想把流程跑通、体验训练自己的模型直接用公开数据集是最省力的。人脸检测领域最经典的是WIDER FACE三万两千多张图约四十万张标注人脸场景覆盖极广尺度差异大、遮挡多、姿态复杂用来当训练集非常够用。问题是它的标注格式不是YOLO格式是椭圆的bbox坐标写在txt里需要自己写转换脚本。FDDB也是一个人脸检测评测集但是它的标注格式更冷门椭圆参数存盘拿来训练反而麻烦更多是当测试集用。如果你想要一张张干净的图片自己标也可以从合规渠道收集公开肖像图然后用LabelImg标注。这里提醒一句人脸数据涉及肖像权和个人隐私收集、标注、分发都要谨慎最好用公开学术数据集或明确授权可再分发的人脸图片自己爬来的数据别乱传给自己留个坑没必要。很多人问我直接用WIDER FACE训练效果不就行了理论上可以但WIDER FACE原始标注有些框特别小几十个像素的脸一大片直接用YOLOv8训练小脸那部分loss会被大脸稀释。实践中建议先用清洗脚本过滤掉宽度或高度小于8像素的目标这是我踩过坑之后总结的不清洗的话验证集mAP看起来还行但实际应用时小脸漏检率极高。2.2 标注格式与YOLO数据格式转换YOLO格式的标注长这样每行代表一个目标class_id cx cy w hcx、cy是目标中心点的归一化坐标w、h是目标的归一化宽高全部除以图片宽高。对人脸二分类来说class_id永远是0。重点提醒一下很多人转换时容易把cx、cy算成左上角坐标或者忘了归一化训练出来的模型会莫名其妙框偏到右下角。WIDER FACE转YOLO格式的脚本核心逻辑很简单我贴一段关键代码import os def convert_wider(wider_txt, img_dir, out_label_dir): with open(wider_txt, r, encodingutf-8) as f: lines f.readlines() i 0 while i len(lines): img_path lines[i].strip() img_name os.path.basename(img_path) img_w, img_h get_image_size(os.path.join(img_dir, img_name)) num_boxes int(lines[i 1].strip()) label_lines [] for j in range(num_boxes): parts lines[i 2 j].strip().split() x, y, w, h map(float, parts[:4]) # 过滤过小的框 if w 8 or h 8: continue cx (x w / 2) / img_w cy (y h / 2) / img_h nw w / img_w nh h / img_h label_lines.append(f0 {cx:.6f} {cy:.6f} {nw:.6f} {nh:.6f}) out_name os.path.splitext(img_name)[0] .txt with open(os.path.join(out_label_dir, out_name), w) as f_out: f_out.write(\n.join(label_lines)) i 2 num_boxesWIDER FACE的bbox本身是整数但归一化后必须保留足够的精度我统一保留6位小数太少的话小脸的坐标误差会被放大导致训练时回归loss震荡。2.3 数据增强与样本均衡人脸场景最典型的问题是“小脸、遮挡、模糊、极端姿态”。YOLOv8自带Mosaic增强相当于把四张图拼在一起训练能显著提升小目标的泛化能力。但Mosaic在训练后期建议关掉Ultralytics默认最后10个epoch会自动关闭这种设计就是为了避免增强太强反而干扰收敛。如果你训练后发现自己标注的“脸”和模型理解的对不上很可能问题出在数据标注标准不统一。我建议在标注规范里写清楚只有单张完整的人脸才算一个目标侧脸角度大于90度、或者完全被遮挡的眼睛部分不算正样本。标注标准不统一是最容易忽略但影响最大的因素它会让模型学到乱七八糟的判别边界。3. 环境配置与源码运行3.1 环境要求与安装步骤先说结论Python 3.8到3.11都可以用推荐3.10。低于3.8PyTorch新版直接不支持高于3.11一些老版本依赖可能会编译报错。PyTorch建议2.0及以上Ultralytics官方对2.0的支持很成熟。GPU环境CUDA版本最低要求11.8实测CUDA 12.1也能正常跑不必非要追求最新版。新建一个虚拟环境装依赖命令如下conda create -n yolo-face python3.10 -y conda activate yolo-face pip install ultralytics pip install opencv-pythonUltralytics库会连带把torch、torchvision等核心依赖都装好所以正常情况下这两条pip命令就够用了。如果网络不好用清华源pip install ultralytics -i https://pypi.tuna.tsinghua.edu.cn/simple我见过太多人在这一步直接卡死。如果conda创建环境特别慢可以换mambamamba比conda解决依赖的速度快一个数量级装PyTorch这种重依赖时体感非常明显。3.2 运行说明的核心内容解读项目根目录的README.md开篇第一段就写了“本项目在Windows 11 Python 3.10 CUDA 12.1环境下测试通过CPU也能跑但速度会慢很多”。这句话看着简单实际上能挡住一大批环境错配的求助。下面把运行说明的几个核心模块展开讲一遍。环境验证部分我让用户先跑一段最小化验证代码from ultralytics import YOLO model YOLO(yolov8n.pt) results model.predict(https://ultralytics.com/images/bus.jpg, saveTrue)如果能正常输出检测结果说明环境任务完成了后面就可以安心训练或推理。如果这段都跑不起来先检查PyTorch是否真能调用GPUpython -c import torch; print(torch.cuda.is_available())输出True才说明GPU可用否则即使装了CUDA的PyTorch也只会默默跑CPU训练速度慢到怀疑人生而且跑着跑着就爆内存。3.3 训练命令与参数说明安装好环境之后用一条命令开始训练自己的模型python train.pytrain.py内容如下from ultralytics import YOLO if __name__ __main__: model YOLO(yolov8n.pt) model.train( dataface.yaml, epochs100, imgsz640, batch16, device0, lr00.01, patience20 )参数逐个说epochs100是训练轮数对精度要求高可以加150但对人脸检测这种相对简单的单类别任务80-100轮足够收敛加多了反而容易过拟合imgsz640是输入图片尺寸不要轻易改小改小会明显损害小脸检测精度batch16是在6GB显存比如GTX 1660 Ti上实测能跑的上限如果你显存更大可以加到32或64batch够大时训练更稳定device0表示用第一张GPU没有GPU改成cpu但要做好训练时间翻几十倍的准备lr00.01是初始学习率一般不用动但如果发现训练loss爆炸先试着降到0.001patience20是当验证集指标连续20轮不提升就提前停止防止浪费时间。这里要特别讲一下显存和batch的关系。以GTX 1660 Ti的6GB显存为例yolov8n配batch16没问题但如果换成yolov8s同样batch16就会OOM需要降到8。yolov8m就更夸张6GB显存基本只能跑batch4左右速度和精度都要妥协。所以选什么模型大小一定先看自己的显卡水平。我用1660Ti实测yolov8n一天能跑完全部训练yolov8s要接近两天yolov8m直接不推荐。3.4 face.yaml数据集配置训练之前还得确认face.yaml文件没问题path: F:/face_dataset train: images/train val: images/val names: 0: face这里最容易翻车的点有两个一是path写的是绝对路径换电脑、换目录之后必须同步修改否则YOLO会一直报错找不到数据集二是train和val路径是相对path来写的不要写成F:/face_dataset/images/train这种绝对路径否则路径拼接时会出问题。4. 模型训练与效果评估4.1 训练过程中要关注哪些指标训练日志里最重要的四个指标是box_loss边框回归损失、cls_loss分类损失、dfl_loss分布焦点损失和mAP50。前三个在训练过程中都应该持续下降如果出现某个loss在下降后突然上涨多半是学习率没衰减到位或者本身已经过拟合了可以提前stop或者调低epochs。mAP50的含义是当预测框和真实框的IoU阈值设为0.5时所有类别AP的平均值。人脸是单类别所以这个值基本代表了“模型能不能找对脸的大致位置”。mAP50-95则严格得多它把IoU从0.5到0.95每隔0.05取一个阈值共计10个阈值求平均对框位置的精确度要求高得多。如果你的应用只需要大致框出人脸主要看mAP50如果后面还要做人脸对齐、换脸、美颜这类对空间位置敏感的任务那mAP50-95才更重要这是一个很实际的选择标准。训练结束后Ultralytics会在runs/detect/train/目录下生成weights/best.pt和weights/last.pt。best.pt是验证集mAP最高的权重用这个做推理和部署别用last.pt除非你确认last和best差异极小。4.2 损失函数曲线图怎么画很多新手一上来就问“怎么画loss曲线”其实Ultralytics早就把plot_results这个工具写好了from ultralytics.utils.plotting import plot_results plot_results(runs/detect/train/results.csv)就会在runs/detect/train目录下生成results.png包含loss曲线、mAP曲线、PR曲线一张大图。如果你嫌官方画得不够好看想自己画也可以用pandas读results.csv自己画import pandas as pd import matplotlib.pyplot as plt df pd.read_csv(runs/detect/train/results.csv) plt.plot(df[epoch], df[train/box_loss], labelbox_loss) plt.plot(df[epoch], df[val/box_loss], labelval_box_loss) plt.legend() plt.show()画出来之后怎么判断好坏有一个小技巧如果train_loss持续下降但val_loss很早就不动了这是典型的过拟合信号这时候加数据增强比加epochs有效。如果train_loss和val_loss都降得很慢先怀疑学习率过大或过小再看数据集是否有问题。4.3 用训练好的模型做人脸检测推理脚本detect.py支持四种输入模式图片路径、图片文件夹、视频文件、摄像头流。核心代码如下from ultralytics import YOLO import cv2 model YOLO(runs/detect/train/weights/best.pt) results model.predict(test.jpg, conf0.5, saveTrue) cap cv2.VideoCapture(0) while cap.isOpened(): ret, frame cap.read() if not ret: break results model.predict(frame, conf0.5, verboseFalse) for r in results: boxes r.boxes.xyxy.cpu().numpy() for box in boxes: x1, y1, x2, y2 map(int, box) cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.imshow(face detection, frame) if cv2.waitKey(1) 0xFF ord(q): break cap.release() cv2.destroyAllWindows()conf是置信度阈值我平时会设0.45到0.55之间。设太低比如0.25会冒出一堆误检框设太高比如0.8又会漏掉大量侧脸和小脸。实际测试下来0.5是一个比较稳的默认值在误检和漏检之间平衡得比较好。如果你要在视频里用建议把推理帧做一下缩放最近在一台只有核显的笔记本上测试原分辨率1920x1080推理只有不到10帧缩放到960x540之后能到25帧左右基本满足实时预览需求但也要看具体显卡性能。4.4 模型导出与部署思路训练完的best.pt如果只是本地运行直接用就行。但如果你想部署到嵌入式设备或手机端就得考虑导出yolo export modelruns/detect/train/weights/best.pt formatonnx opset12ONNX格式的好处是跨平台通用可以再用ONNX Runtime、TensorRT、OpenVINO、NCNN这些推理引擎去做加速。导出时opset版本建议不低于12太老的opset会丢一些算子支持。导出之后可以用ONNX Runtime验证一下输出是否和PyTorch一致import onnxruntime as ort import numpy as np from ultralytics import YOLO model YOLO(runs/detect/train/weights/best.pt) result model.predict(test.jpg) img np.zeros((1, 3, 640, 640), dtypenp.float32) sess ort.InferenceSession(best.onnx) outputs sess.run(None, {sess.get_inputs()[0].name: img})输出的shape是(1, 84, 8400)8400是YOLOv8在不同尺度特征图上的候选框总数84是4个坐标80个COCO类别。如果是自己的模型80要替换成类别数加4。很多人导完ONNX之后发现输出解析不对多半就是这个维度理解没对上。部署到嵌入式设备时优先考虑TensorRTNVIDIA板子或OpenVINOIntel平台再往下的NCNN或MNN适合手机端但要做一遍量化精度会有轻微损失。这部分我建议不要在训练阶段就纠结先把训练跑通部署遇到具体问题再针对性看文档展开讲又是一整篇文章的量。5. 常见问题与排查技巧实录5.1 环境相关的典型报错速查这个表我整理自几个技术群里最常见的求助问题基本覆盖了90%的“跑不起来”场景报错现象可能原因解决方案ModuleNotFoundError: No module named torch虚拟环境没装PyTorch或装错环境conda activate对应环境重新pip install ultralyticsCUDA out of memory显存不足减小batch到4或8减小imgsz到480换yolov8nassert image is not None图片路径错误或中文路径问题把路径里的中文改成英文检查文件是否存在AttributeError: NoneType object has no attribute shape图片读取失败cv2.imread对中文路径支持差用cv2.imdecode代替OSError: [WinError 127]DLL加载失败重装Microsoft Visual C RedistributableRuntimeError: DataLoader worker (pid(s)) exited unexpectedlyWindows下num_workers设置过大train时把workers8调成workers2或05.2 训练不收敛或效果差怎么排查如果你的训练loss一路飘红或者明显不下降先别急着改模型结构。按照以下顺序排查大部分人问题出在前两步第一步检查数据标注。下载几张训练图片用可视化脚本把标注框画上去看看标注框和真实人脸是否对齐。我遇到过用LabelImg标注时不小心把类别标错、或者拖拽框时偏移了几个像素这种错误模型是学不出来的。第二步检查数据划分。训练集和验证集如果内容高度相似验证集指标会虚高但一到真实场景就翻车。用split_dataset.py做划分时一定要先shuffle再划分避免同一个人的所有照片都进了训练集或验证集导致数据泄漏。第三步检查学习率。如果loss在训练初期就出现nan把lr0从0.01降到0.001再试。如果是loss持续缓慢下降但mAP涨不上去适当加大epochs或者把模型从yolov8n换到yolov8s。第四步削弱过度增强。YOLOv8默认增强在数据量少的时候反而会起反效果。自己只有几千张图又不做清洗的时候可以试试把mosaic关闭mosaic0.0或者把hsv_h、hsv_s、hsv_v这几个增强参数调小一些。5.3 小脸漏检和误检的针对性优化人脸检测最头疼的就是小脸。如果你发现模型对远处的小脸几乎不检可以试试这个思路把图片切成四块每一块分别检测最后合并结果。因为小脸问题本质上不是模型能力不足而是特征图分辨率不够切图之后相当于把小目标变成了大目标。当然切图会让推理时间翻四倍适合离线处理实时场景可以简单把输入尺寸从640加大到960或1280代价是显存和耗时一起涨。误检方面最常见的误检来源是人体躯干、圆形物体、海报上的人脸。针对误检很简单一是提高conf阈值二是用NMS的IoU阈值默认0.7可以降到0.5减少重叠框三是在数据集里加入一些“非人脸但容易误检”的负样本去训练。最后一点很多新手忽略了负样本训练对抑制误检作用非常明显。5.4 根据实际经验总结的几个技巧最后分享几个只有亲手跑过整个流程才能体会到的细节。摄像头实时检测时如果画面里的脸看起来卡顿不要急着怪YOLO模型太重先把输入帧从BGR到RGB的转换检查一遍。OpenCV读出来是BGR顺序YOLOv8在预处理时会做BGR转RGB但如果你的IO已经手动转了一次再喂给YOLO就会导致颜色通道错乱检测头看起来“没反应”。这种问题最隐蔽信号是检测框偶尔出现但概率明显偏低。训练结束后别急着把best.pt当最终模型。建议用训练好的模型在训练集以外的测试图片上跑一遍专门挑那种全家福、集体照、演唱会现场图看看漏检和误检的边界在哪里。这一步能帮你想清楚conf阈值设多少比较合适也能提前暴露数据标注质量问题。实测下来几乎每次做这种“真实图压测”都能刷新一次自己对模型能力上限的认知。再一个别人不常提的小技巧数据集划分时验证集不要包含太多“太好检测”的大脸。如果验证集里全是清晰正脸mAP会显得虚高跟实际使用脱节。我通常会把验证集的构成调难一些多放一些侧脸、小脸、部分遮挡的样本这样训练过程中的early stopping和模型选择才更有意义。6. 训练自己的数据集从方案到落地6.1 收集与组织数据想要训练成果脱离WIDER FACE的“标准美颜脸”让它更贴合你自己的使用场景比如半身证件照、办公摄像头视角、美颜相机前置效果自建数据集才是正路。收集数据时注意三点图片多样性不同肤色、年龄、光线、姿态、图片分辨率混入一些640x480的低分辨率图能提升推理时的鲁棒性、正负样本配比负样本不用太多10%-20%就足够抑制误检。组织数据时把原始图片统一放到dataset/images/train、dataset/images/val、dataset/images/test三个目录里再跑一遍split_dataset.py生成对应的labels目录。文件命名建议用带前缀的编号例如face_000001.jpg不要用中文名或带空格的文件名后面做跨平台操作时能省很多事。6.2 标注工具选择与标注注意事项开源标注工具里LabelImg最老牌支持YOLO格式导出操作逻辑跟画矩形框差不多。如果你图片多LabelImg一张张点会崩溃可以考虑用AnyLabeling它带一个自动化预标注功能能用已有模型先出一版框人工再修正效率至少翻一倍。我自己实测2000张图用AnyLabeling做的半自动标注大约8小时能完成纯手工用LabelImg得超过20小时。标注时把握这几个度人脸被头发遮挡一半按可见部分标全框人脸侧到只能看到一只眼睛如果你定义的是“正脸”可以不标如果定义的是“人脸”可以标两张脸挨得很近导致框重叠两个目标都标全框不要因为重叠就删掉一个。6.3 数据划分脚本的细节split_dataset.py的核心逻辑是把图片文件名全部读出来随机打乱按85%、10%、5%划分成训练集、验证集、测试集。有几处细节值得注意import os import random import shutil random.seed(42) img_paths [] for root, dirs, files in os.walk(raw_images): for f in files: if f.endswith((.jpg, .jpeg, .png)): img_paths.append(os.path.join(root, f)) random.shuffle(img_paths) train_len int(len(img_paths) * 0.85) val_len int(len(img_paths) * 0.10) train_paths img_paths[:train_len] val_paths img_paths[train_len:train_len val_len] test_paths img_paths[train_len val_len:]固定random.seed(42)非常重要这样每次跑脚本得到的划分结果都一样可复现。不然你加了几张图重新划分以前训练的模型和现在的验证集就对不上了指标也没法横向比较。我习惯在生成数据集之后顺手写一个images_train.txt把所有训练图片路径列出来万一后面要重新训练或做错误分析能快速定位样本来源。7. 项目扩展方向从“能跑”到“好用”很多同学按照上面的步骤跑通人脸检测之后会问“然后呢”一个“能跑”的YOLOv8人脸检测demo和真正“好用”的人脸检测产品之间其实还差着好几步。最容易做也最实用的一步是把检测结果接入人脸识别管线。YOLOv8只负责“框出人脸在哪里”后面再接一个人脸特征提取模型比如FaceNet或ArcFace把检测到的人脸区域裁剪出来提取向量再和库里的人脸向量比对就能做成一个人脸考勤或人脸检索系统。这个方向最贴合实际业务也是很多行业项目的落地形态。如果你对检测性能还不满意可以尝试YOLOv8的改进方向。网络结构上给Backbone融入注意力机制SE、CBAM、ECA是最常见的改法ECA模块参数最少稍微调一下就能在几乎不增加推理耗时的前提下提升1-2个mAP点。数据增强上引入CutMix和更细粒度的Copy-Paste可以进一步提升小脸场景效果。模型结构上用轻量化Backbone如MobileNetV3替换原版能让模型更小、更适合部署到嵌入式设备。不过这些改进都是锦上添花数据质量才是真正的底线这句话我在任何场合都要强调因为它是所有目标检测项目里被忽视得最多的东西。如果是嵌入式部署我建议训练完直接导成TensorRT的engine格式在NVIDIA Jetson上推理速度比PyTorch快5到10倍。模型量化到FP16甚至INT8内存占用还能再砍半。但量化会带来精度损失人脸检测这种对框位置敏感的任务先试FP16INT8要拿样本仔细验证后再决定用不用。最后说说我自己的经验体会。刚开始做这个项目的时候我也特别迷信模型结构总想着换更强的Backbone、调更复杂的注意力机制。跑了十几轮实验之后发现提升最大的几次改动全都在数据侧清洗了标注噪声统一了标注标准加了适当的负样本补了一些极端场景的图片。模型结构带来的提升是几个点的差而数据质量带来的提升是肉眼可见的质变。如果你现在正在Debug一个“训练完效果很怪”的人脸检测模型我的第一条建议永远是把标注可视化打开逐个检查样本大概率问题一眼就能看出来。本文还有配套的精品资源点击获取