尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

YOLOv8人脸检测实战:从环境配置到RK3588部署

发布时间:2026/9/24 21:50:21

资讯中心
01
ARTICLE

YOLOv8人脸检测实战:从环境配置到RK3588部署

YOLOv8人脸检测实战:从环境配置到RK3588部署
简介面向毕业设计、期末大作业与课程设计场景的YOLOv8人脸检测实战项目基于YOLOv8实现人脸检测完整流程代码包含详细注释适合刚接触目标检测的初学者直接上手也便于二次扩展。项目经严格调试下载解压后按说明部署即可运行并附带数据库脚本与前后端代码具备界面展示与操作管理能力具有较好的工程实用价值。压缩包共19个文件以14个Python源码文件为主覆盖模型构建、训练、损失计算、EMA、NMS推理、数据加载、导出等功能模块同时提供2个shell训练脚本、1个训练权重文件.pt及1份说明文档整体仅11.79MB轻量便于传播与学习。目前已有426人学习下载适合需要快速完成人脸检测项目、验证算法效果或作为毕设/课设交付成果的开发者参考。1. 一张监控截图暴露的问题为什么通用检测模型换到人脸场景就失灵人脸检测听起来是目标检测里最基础的课题但真正接过实际项目的人都懂把 COCO 上跑得不错的 YOLOv8 模型直接拿来做闸机、考勤或课堂点名前几帧可能还行等画面里出现侧脸、低头、逆光检测框就开始乱跳。这不是 YOLOv8 不行而是通用模型的类别语义和训练分布跟人脸场景的真实诉求之间有明显错位。这篇实战笔记要解决的就是这个错位。从拿到一份标记为“下载即用”的 YOLOv8 人脸检测项目开始我会按真实落地顺序走一遍环境预检、权重选型、推理验证、用自己的数据微调、导出部署最后把训练日志里那些看似正常的曲线翻出来逐段排查。适合两类人一是正在做人脸检测相关毕设或课题、需要一份能跑通并讲清楚原理的基线工程二是已经在用 YOLOv8 做检测、但被人脸场景里的小目标、遮挡和误检反复折腾的开发者。2. 把下载即用的人脸检测项目跑起来目录结构、权重文件与环境预检2.1 拿到项目包先别急着 pip install先读这 3 个文件从网上下载的 YOLOv8 人脸检测项目其目录结构通常长这样├── data/ # 数据集与标注文件 │ ├── images/ # 训练/验证图片 │ ├── labels/ # YOLO 格式的 txt 标注 │ └── data.yaml # 数据集配置文件 ├── runs/ # 训练输出目录 │ ├── detect/ │ └── train/ # 权重文件与训练曲线 ├── models/ # 模型结构定义或权重转存 │ └── yolov8n-face.pt ├── ultralytics/ # 第三方库常见做法是直接安装部分项目把改过的源码包打进目录 ├── train.py # 训练入口脚本 ├── detect.py # 推理入口脚本 └── requirements.txt第一步不是装依赖而是打开data.yaml、train.py和requirements.txt三个文件做预检。data.yaml里最关键的是nc字段它必须等于 1人脸检测通常只有一个类path字段必须是绝对路径或能被相对路径正确解析的目录名。很多“下载即用”的项目跑不起来就是因为path还指向作者的本地磁盘路径。requirements.txt里有几个版本容易踩坑torch、torchvision和ultralytics三者需要配对。我的经验是如果机器上有 N 卡直接用pip install ultralytics会自动拉起匹配的 torch 版本如果是纯 CPU 机器就不要一上来就装最新版 ultralytics因为新版对 CPU 推理的某些算子树优化反而回退过。2.2 用 ultralytics 官方库跑通最小推理命令绝大多数 YOLOv8 人脸检测项目都属于“在官方 ultralytics 基础上换数据集、换类别数”的二次封装所以最快确认环境是否正常的办法是跳过项目自带的边缘脚本直接用官方 API 做一次最小推理from ultralytics import YOLO # 加载项目自带的权重文件路径按实际位置调整 model YOLO(models/yolov8n-face.pt) # 对单张图片做推理conf 参数控制置信度阈值 results model.predict( sourcedata/images/test.jpg, conf0.25, saveTrue, projectruns/detect, namesmoke_test, exist_okTrue, ) # 打印检测结果数量验证模型是否真正输出了人脸框 for r in results: print(len(r.boxes), 个检测框)这段代码的验证逻辑很简单如果权重文件能正常加载并且图片里检测出人脸框说明整条推理链路是通的。conf0.25是 YOLOv8 的默认置信度阈值但做人脸检测时建议第二轮把这个值提到 0.4 以上。因为人脸误检比如把圆形表盘、球体误判成人脸在低置信度区间非常密集0.25 在单人脸场景会带来大量假阳性。exist_okTrue是容易被忽略的参数如果不加第二次运行同名name目录时ultralytics 会创建一个带序号的新目录加了则直接复用。这在写循环验证脚本时能省掉很多脏输出。2.3 模型权重怎么选yolov8n 到 yolov8x 的取舍与 .pt/.onnx 边界人脸检测对模型体量的敏感度比通用检测更高。用官方 YOLOv8 做对比yolov8n和yolov8s的人脸检测速度差不大但 mAP 差距可能到一个数量级。我一般定这样的选择策略权重版本显存占用batch16推理速度RTX 3060适合的人脸场景yolov8n约 6 GB约 1.8 ms/张移动端、边缘盒子的快速验证yolov8s约 10 GB约 3.2 ms/张考勤机、闸机等中等算力设备yolov8m约 16 GB约 5.6 ms/张对单人脸精度要求较高的后端服务yolov8l/x约 22 GB 以上约 10 ms/张离线批量处理不适合实时需要注意的点是.pt文件里保存的不只是权重还包括模型结构定义、训练超参数和优化器状态所以一份 “yolov8n-face.pt” 完全可能是作者在自己数据上微调过的模型跟官方原始权重在行为上差异很大。拿到手之后应该先跑一张含多张人脸、不同大小的测试图观察小尺寸人脸的召回情况再决定要不要换更大的权重。.pt转.onnx的边界在于onnx 只保留前向推理图适合部署但不适合继续训练。所以项目里同时出现.pt和.onnx是合理工程结构前者留给继续 fine-tune后者留给实际部署。2.4 用摄像头或视频文件做人脸检测与标注“实时摄制视频的人脸检测与标注”是热搜词里出现频率很高的真实需求。用 YOLOv8 做实时视频检测官方 API 一行就能切到视频源yolo detect predict modelmodels/yolov8n-face.pt source0 showTrue conf0.4source0表示调用默认摄像头showTrue会弹出一个预览窗口。实际项目中直接用命令行会吃亏因为没法做后处理逻辑。我一般会改用 Python 脚本在逐帧循环里把检测框和置信度拼到画面左上角同时把结果写到 CSV 里方便后面做帧级统计。import cv2 from ultralytics import YOLO model YOLO(models/yolov8n-face.pt) cap cv2.VideoCapture(0) frame_idx 0 while cap.isOpened(): ret, frame cap.read() if not ret: break results model.predict(frame, conf0.4, verboseFalse) # 遍历每个检测框画框并打印坐标信息 if results and results[0].boxes is not None: for box in results[0].boxes: x1, y1, x2, y2 map(int, box.xyxy[0].tolist()) conf float(box.conf[0]) cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.putText( frame, fface {conf:.2f}, (x1, y1 - 8), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2, ) print(fframe{frame_idx}, bbox({x1},{y1},{x2},{y2}), conf{conf:.3f}) cv2.imshow(face-detection, frame) frame_idx 1 if cv2.waitKey(1) 0xFF ord(q): break cap.release() cv2.destroyAllWindows()这段脚本的工程价值在于verboseFalse这个参数。默认情况下 ultralytics 每帧都会往终端打印推理耗时和检测结果跑实时视频时终端会被刷成一片严重影响排查错误日志。另外map(int, box.xyxy[0].tolist())这种写法是把 tensor 转成 Python 整数不转的话后面cv2.rectangle会传出类型异常。3. 用自己的数据微调从 labelme 标注到 YOLO 格式的转换路径3.1 采集与标注哪些人脸场景值得做哪些是白费功夫先泼一盆冷水如果是单人人脸、正脸、光照均匀的场景没有必要自己标数据训练。预训练的 YOLOv8 在 WIDER FACE 这类公开人脸数据集上已经有足够好的表现。真正值得自己动手标数据的场景有三类大量侧脸和低头姿态、密集小尺寸人脸比如教室内后排学生、以及与真实部署环境接近的图像噪声分布比如老旧监控摄像头的偏色和压缩痕迹。标注工具的选择常见做法是用 labelme。它支持矩形框和极简的 JSON 输出对单人脸的标注效率高。一张 1080p 图像里标 20 张人脸熟练后大约需要 40 秒但需要注意的是人脸检测的数据集质量瓶颈不只在标注精度还在图片数量分布。至少要保证最难的场景比如小脸、遮挡脸占到总量的 30%否则模型学到的只是“容易的样本”的分布。3.2 把 labelme 的 JSON 转成 YOLO 训练格式转换脚本与参数说明labelme 导出的 JSON 结构里包含图像尺寸和每个矩形的顶点坐标但 YOLO 训练需要的是归一化中心点格式class x_center y_center width height并且宽度高度都是相对于图像宽高的比例。写一个通用的转换脚本import json import os from glob import glob def convert_labelme_to_yolo(json_path, out_dir): # 读取 labelme 的 JSON 文件 with open(json_path, r, encodingutf-8) as f: data json.load(f) img_w data[imageWidth] img_h data[imageHeight] txt_name os.path.splitext(os.path.basename(json_path))[0] .txt out_path os.path.join(out_dir, txt_name) lines [] for shape in data[shapes]: if shape[label] ! face: # 只处理 face 标签忽略其他 continue points shape[points] xmin min(p[0] for p in points) ymin min(p[1] for p in points) xmax max(p[0] for p in points) ymax max(p[1] for p in points) # 坐标归一化并计算中心点 w (xmax - xmin) / img_w h (ymax - ymin) / img_h x_center (xmin xmax) / 2.0 / img_w y_center (ymin ymax) / 2.0 / img_h # 过滤掉异常标注宽高为 0 或超出图像边界 if w 0 or h 0 or w 1 or h 1: continue lines.append(f0 {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}) with open(out_path, w, encodingutf-8) as f: f.write(\n.join(lines)) json_files glob(data/labelme_jsons/*.json) for jf in json_files: convert_labelme_to_yolo(jf, data/labels) print(fconverted: {jf}) print(f共转换 {len(json_files)} 个文件)这个脚本里有三个容易写错的点。第一是坐标原点labelme 的坐标原点是图像左上角如果从别的标注工具迁移过来先确认坐标系是否一致。第二是长宽计算有些转换脚本错误地使用了xmax - xmin 1这种像素级偏移在归一化后影响很小但强迫症建议统一为不加 1。第三是异常过滤标注时手抖把矩形拖到图像外或误操作产生零宽度的框这些脏数据如果不过滤训练时可能出现 loss 为 NaN 的情况。3.3 数据集划分与配置文件train.txt、val.txt、data.yaml 怎么写标注转成 txt 之后还要做数据划分和写配置文件。ultralytics 框架推荐的数据集目录结构是data/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ └── data.yaml图片和对应的 txt 文件必须保持同名同目录层级。划分比例我一般用 8:1:1但如果数据总量少于 300 张验证集按 10% 可能只有 30 张图此时建议改为 7:1.5:1.5 并开启数据增强。划分脚本可以简单用随机数实现import os import random import shutil random.seed(42) # 固定随机种子保证可复现 img_dir data/all_images label_dir data/all_labels train_split, val_split, test_split 0.8, 0.1, 0.1 images [f for f in os.listdir(img_dir) if f.endswith(.jpg)] random.shuffle(images) n_train int(len(images) * train_split) n_val int(len(images) * val_split) split_map { train: images[:n_train], val: images[n_train:n_train n_val], test: images[n_train n_val:], } for split, imgs in split_map.items(): os.makedirs(fdata/images/{split}, exist_okTrue) os.makedirs(fdata/labels/{split}, exist_okTrue) for img in imgs: src_img os.path.join(img_dir, img) src_lbl os.path.join(label_dir, img.replace(.jpg, .txt)) if not os.path.exists(src_lbl): print(fwarning: {img} 没有对应标签文件跳过) continue shutil.copy(src_img, fdata/images/{split}/{img}) shutil.copy(src_lbl, fdata/labels/{split}/{img.replace(.jpg, .txt)}) print(划分完成)这个脚本里random.seed(42)很关键。如果去掉每次重跑脚本都会生成不同的划分结果后续做对比实验时会出现“A 模型在训练集 A 上表现好、B 模型在训练集 B 上表现好”的假象根本没法定位是模型结构差异还是数据分布差异。data.yaml的内容相对固定# 数据集配置path 建议写相对路径或绝对路径 path: ./data train: images/train val: images/val test: images/test nc: 1 names: [face]names里的类别名称会直接显示在预测框的 label 上。如果项目里原本有多个类名比如从某个人脸加关键点的数据集改过来的一定要改成只含face否则会在推理时报维度错误。3.4 训练命令与 freeze 参数显存不够时先冻结 backbone训练入口我通常不用官方的一行命令而是写一个训练脚本方便记录超参数yolo train \ modelyolov8n.pt \ datadata/data.yaml \ epochs100 \ imgsz640 \ batch16 \ lr00.01 \ freeze10 \ device0freeze10的含义是冻结模型前 10 层的参数这在前 30 轮训练中能显著降低显存占用对显存较小或 batch 起不来的情况很有帮助。但在人脸检测这个小类别集场景里我的经验是 freeze 只适合做“冷启动”的前 20~30 轮之后必须解冻全部层让骨干网络也适配人脸数据的分布。如果从头到尾都 freezemAP 会卡在一个不上不下的值模型学到的只是检测头对新数据集的适配而骨干网络仍然停留在 COCO 的语义空间。imgsz640是人脸检测的妥协解。更大的输入尺寸比如 960能显著提升小脸召回但显存占用按平方增长而且对后续部署到边缘设备的模型转换会带来额外复杂度。我一般先用 640 跑基线如果小脸漏检严重再单独用 960 训练一个版本对比。4. 从 .pt 到部署落地ONNX 导出与 RK3588 边缘设备的实践要点4.1 导出 ONNX 的命令与 opset 版本选择训练完成后把.pt导出为.onnx是一个绕不开的环节。ultralytics 提供一行命令yolo export modelruns/detect/train/weights/best.pt formatonnx opset12 simplifyTrueopset是最容易被忽视的参数。ONNX 的算子版本和推理引擎的支持范围强相关opset 12 是一个兼容性非常好的折中版本几乎所有推理框架都支持opset 17 或更高虽然能利用更新的算子优化但部分边缘端 NPU 的模型转换工具可能还不支持某些新算子。我的习惯是如果目标是瑞芯微 RK3588优先用 opset 12如果只做服务器端 CPU 推理opset 12 也完全够用没必要追新。simplifyTrue会调用 onnx-simplifier 对计算图做常量折叠和算子融合导出的模型更小推理速度也略快。但注意简化过程有可能改变某些输出节点的名称如果后续在部署代码里按名字取输出张量导出后要检查一下输出名是否变了。4.2 CPU 机器推理用 ONNX Runtime 还是 OpenVINO很多人手里的机器没有 N 卡只能靠 CPU 跑推理。这就是热搜词里“ubuntu20.04搭建yolov8环境cpu版本”对应的场景。CPU 推理有两个选择onnxruntime 和 openvino。在两代较新的 Intel CPU 上OpenVINO 对 YOLOv8 的加速效果明显特别是批处理场景能到 3~5 倍提速AMD CPU 或 ARM 机器上则直接用 onnxruntime 更省心。一个简单的推理脚本import cv2 import numpy as np import onnxruntime as ort # 创建 ONNX Runtime 会话开启 CPU 优化 sess ort.InferenceSession( models/yolov8n-face.onnx, providers[CPUExecutionProvider], ) img cv2.imread(data/images/test.jpg) img_resized cv2.resize(img, (640, 640)) # YOLOv8 的输入是 CHW 格式BGR 转 RGB 并归一化到 0-1 blob cv2.cvtColor(img_resized, cv2.COLOR_BGR2RGB).astype(np.float32) / 255.0 blob np.transpose(blob, (2, 0, 1))[None, ...] outputs sess.run(None, {sess.get_inputs()[0].name: blob}) # outputs[0] 的 shape 是 [1, 84, 8400]前 4 行是关键点/宽高第 5 行是置信度 preds outputs[0][0] boxes preds[:4, :].T # 4 x 8400 - 8400 x 4 scores preds[4:5, :].T # 置信度 # 简单过滤置信度 0.4 的候选框 keep scores[:, 0] 0.4 candidate_boxes boxes[keep] candidate_scores scores[keep] print(f置信度超过 0.4 的框: {len(candidate_boxes)} 个)这段代码省略了 NMS只展示了 ONNX 模型的裸输出是什么形状。很多从 pytorch 转到 onnxruntime 的人卡在这一步因为 pytorch 模型输出的是已经做过 NMS 的检测框列表而 ONNX 模型输出的是 8400 个锚框的原始预测必须手动做置信度过滤和 NMS。这是部署环节最典型的黑匣子。4.3 部署到 RK3588 时模型转换这件事该交给谁“RK3588 部署 YOLOv8”是人脸检测项目里被搜索得最多的硬件话题。RK3588 的 NPU 算力约 6 TOPS跑一个优化后的 YOLOv8s 人脸检测大约能到 20~30 FPS关键是模型量化与转换的链路。常见的落地路径是yolov8n.pt→onnx→rknn。瑞芯微官方提供了 rknn-toolkit2 工具包转换命令大致是from rknn.api import RKNN rknn RKNN() # 配置量化方式int8 对精度有损fp16 更稳 rknn.config(mean_values[[0, 0, 0]], std_values[[255, 255, 255]], target_platformrk3588) rknn.load_onnx(modelmodels/yolov8n-face.onnx) rknn.build(do_quantizationTrue, datasetdataset.txt) rknn.export_rknn(models/yolov8n-face.rknn)dataset.txt里存放的是用于量化的校准图片路径每行一张图。我的经验是这个校准集至少要有 50 张贴近真实部署场景的图而不是从训练集里随便抽。量化校准图与部署场景偏差过大会导致 int8 模型在人脸上出现严重的精度下降表现在推理结果上就是漏检率突然变高、置信度整体偏低。在 RK3588 上跑 RKNN 模型也是独立的话题涉及 rknn-toolkit-lite2 的运行时 API以及 NPU 和 CPU 之间的数据拷贝优化。如果只是先验证可行性直接用官方提供的 rknn_yolov8_demo 改类别数和权重路径即可。5. 人脸检测实战中的高频翻车现场现象、原因与排查逻辑5.1 现象检测框一直在跳同一张脸时大时小用视频流做实时人脸检测时画面里的人没动检测框的尺寸和中心点却在连续帧里抖动摇摆。这在小脸场景尤其突出本来 20 像素宽的脸某一帧输出 18 像素下一帧输出 25 像素框的视觉观感非常不稳定。原因有两层。第一层是模型本身对低分辨率人脸的定位精度不够任何一帧的抖动都会被放大第二层是置信度波动当某帧的置信度刚好低于阈值被滤掉时就会出现“消失又出现”的闪烁感。解决思路不是去改模型而是做帧间平滑。常见做法是维护一个最近 5 帧的检测框队列用加权平均输出最终坐标。也可以放宽置信度阈值到 0.3 保证召回同时用卡尔曼滤波做轨迹预测。人脸检测落到视频场景后处理往往比模型本身更决定体验。5.2 现象模型把人脸当目标检测没问题但加入人脸关键点就崩很多“YOLOv8 人脸检测项目”不只检测人脸框还包含眼睛、鼻子、嘴巴等关键点输出。如果你只下载了这样的项目但不需要关键点跑训练时会发现 loss 高居不下检测框的 mAP 也低于只做单一任务的表现。原因是 YOLOv8 的检测头和关键点头共享骨干网络但关键点回归任务的梯度会反向影响特征提取层的分布。人脸关键点和人脸框是相关但不同粒度的任务框检测需要的是位置信息关键点需要的是局部纹理信息共享骨干会产生任务冲突。解决方法是二选一要么直接裁剪掉关键点分支只保留检测头重新训练要么接受多任务框架但给关键点 loss 设置更小的权重系数。如果你只需要人脸框建议直接选用纯人脸检测项目而不是关键点检测的复合项目。5.3 现象模型在训练集上 mAP 很高换到真实视频里几乎测不到脸训练完成后打印 mAP0.5 高达 0.95但拿到真实摄像头场景里画面里明明有正脸检测框就是出不来。这不叫模型差叫训练集与部署域不一致。去对比一下训练集图片和真实视频帧的差异很多公开人脸数据集里的图片是网络爬取的清晰正脸分辨率高、光照均匀、没有运动模糊而摄像头画面是压缩后的 MJPEG 视频流有偏色、有噪点、人脸可能占画面比例很小。模型在训练域里见过的人脸“长得太干净”遇到轻度模糊就判为负样本。解决方法是把真实摄像头采集的帧加入训练集。最少抽 200 帧切成图片用已有模型做预标注然后人工修正追加到训练数据里重新微调。这一步的效果通常比调整任何超参数都明显。5.4 现象训练时 loss 曲线下降很好看但验证集 loss 反向上升在训练日志里看到 box loss 和 cls loss 一路下行但每轮结束时的验证集 mAP 反而下降这属于典型的过拟合信号。YOLOv8 自带的正则化手段不足以应对小数据集人脸的多样性。此时优先检查两点。第一训练集和验证集之间是否有信息泄漏比如同一个人在不同图片里反复出现模型学到的是“记住这张脸”而不是“学好人脸的一般模式”。第二数据增强是否过弱人脸框标注本身是紧致的、形状固定的如果增强策略里缺乏随机裁剪和颜色扰动模型容易把训练集里的背景纹理也学进特征。补救办法是把增强参数调起来ultralytics 里可以设置hsv_h0.015、degrees5、translate0.1、scale0.5让人脸框的位置和色彩出现更多变化。同时可以考虑加早停patience20表示连续 20 轮验证集没有更好就自动停止能省下不少算力。6. 调优的最后一公里用损失函数曲线图判断训练是否真的收敛6.1 把训练日志转成损失曲线训练脚本跑完后runs/detect/train/目录下会生成results.csv里面记录了每一轮的 train/box_loss、train/cls_loss、metrics/mAP50 等指标。最简单的曲线绘制方式是直接用 pandas 读 CSV 后画图import pandas as pd import matplotlib.pyplot as plt # 读取训练日志 df pd.read_csv(runs/detect/train/results.csv) # 清掉列名里的前后空格 df.columns df.columns.str.strip() # 画出 box loss 和 cls loss 两条曲线 plt.figure(figsize(10, 5)) plt.plot(df[epoch], df[train/box_loss], labeltrain box loss) plt.plot(df[epoch], df[train/cls_loss], labeltrain cls loss) plt.plot(df[epoch], df[val/box_loss], labelval box loss, linestyle--) plt.xlabel(epoch) plt.ylabel(loss) plt.title(YOLOv8 Face Detection Loss Curves) plt.legend() plt.grid(True) plt.savefig(loss_curve.png, dpi150)看曲线的时候重点关注三个节点。第一是训练 loss 和验证 loss 的分叉点如果两者在前 20 轮就开始分道扬镳说明模型容量过大或数据太少第二是 loss 的下降斜率是否在后期趋平如果还有明显下降趋势说明 epochs 设少了第三是验证 loss 是否出现过山车式的回升如果有检查是过拟合还是学习率在后期设置不当。6.2 用一段真实视频做“交付级”验证而不是只看指标指标是给人看的效果是给机器跑的。最后一步验证我会刻意挑一段没有出现在训练数据里的视频包含三种场景正脸、低头/侧脸、部分遮挡脸分别统计检测成功率。做法很简单用检测脚本跑完整段视频把每一帧的检测结果按时间戳写入日志然后统计三类场景的框数。正脸场景如果漏检超过 2%可以先降置信度阈值再试低头/侧脸场景漏检严重问题大概率在训练数据里这类样本太少。这个验证习惯帮我避过多次“指标很高、交付翻车”的尴尬。做项目不是把准确率刷到一个好看的数字交差而是让模型拿到现场环境下依然稳定工作。这也正是我当时给自己定的验收标准训练曲线再漂亮不如一段两分钟的真实视频来得有说服力。人脸的形态变化远大于大多数人的直觉同一个人的正脸和侧脸在特征空间里可能比不同人的正脸相距更远。这是我做这个方向踩得最深的一个坑也是现在每次训练前都会先看一眼数据分布的原因。希望帮到你。本文还有配套的精品资源点击获取
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。