简介这份资源包面向希望上手深度学习目标检测、尤其是人脸表情识别的开发者与学习者提供从数据到部署的完整实践路径。包内共2000个文件以1989个txt标注与说明文件为主辅以8个md说明、1个yaml配置、1份docx与1份pdf使用文档压缩包约367.62MB覆盖数据集、源码与教程三类内容。数据集包含多来源、多类别的人脸表情图像及标注可用于训练与泛化评估源码基于主流深度学习框架含训练、验证与推理脚本并针对面部小目标检测做了适配优化教程则从环境配置、数据预处理讲到模型训练、评估与部署还涉及超参数调整、数据增强和迁移学习等调优技巧。资源另附可视化工具与OpenCV相关处理思路便于将模型用于图片或视频流的实时表情识别。目前已有2391人学习适合具备Python与深度学习基础、想快速跑通表情识别项目的读者参考。1. 表情识别项目落地从 YOLOv8 检测到表情分类的完整链路表情识别这个方向很多人第一反应是「拿个分类网络跑 FER2013 就完事了」但真正落到工程里纯分类方案在多人合影、侧脸、遮挡场景下几乎不可用——你连人脸框都拿不到分类器输入什么所以工业界更常见的做法是两阶段先用 YOLOv8 做人脸检测裁出人脸区域再送进表情分类头。这份「YOLOv8-表情识别数据集源码教程.rar」走的就是这条路线包里包含标注好的人脸表情数据集、YOLOv8 训练与推理源码、以及从环境配置到模型导出的教程文档。它适合两类人一是想跑通「检测分类」完整 pipeline 的算法工程师二是手里有表情识别需求、需要一份能直接改的数据集和代码基线的从业者。Ubuntu 20.04、Windows 都能跑CPU 版本也能出结果只是慢。下面我按自己拆包复现的顺序把这份资源里真正值得抄的部分拆开讲。2. 环境配置与数据准备YOLOv8 在 Ubuntu 20.04 和 Windows 上的差异2.1 环境选型为什么 CPU 版本也值得先跑一遍很多人一上来就折腾 CUDA结果驱动版本、cuDNN、PyTorch 三者对不上卡在torch.cuda.is_available()返回 False 上耗掉一整天。我的建议是先用 CPU 版本把整条链路跑通确认数据集格式、训练脚本、推理脚本都没问题再切 GPU。这份资源的教程里也是这个思路CPU 版本在 Ubuntu 20.04 和 Windows 上都能装区别只在 PyTorch 的安装命令。Ubuntu 20.04 下我一般这么建环境# 创建独立虚拟环境避免污染系统 Python python3 -m venv yolov8_env source yolov8_env/bin/activate # 安装 CPU 版 PyTorch注意 torchvision 版本要匹配 pip install torch2.0.1 torchvision0.15.2 --index-url https://download.pytorch.org/whl/cpu # 安装 ultralyticsYOLOv8 的官方库 pip install ultralytics8.0.200 # 验证安装 yolo checksWindows 下把source换成yolov8_env\Scripts\activate其余一致。yolo checks会打印出 Python 版本、PyTorch 版本、是否检测到 GPU这一步能提前暴露 90% 的环境问题。参数说明torch2.0.1和torchvision0.15.2是配套的不要单独升级其中一个。ultralytics版本我锁在 8.0.200因为再新的版本 API 有变动资源里的训练脚本可能不兼容。如果你要用 GPU把--index-url换成对应 CUDA 版本的源比如 cu118。2.2 数据集结构YOLO 格式和分类格式要分开看这份资源的数据集是两套一套是人脸检测的 YOLO 格式标注每张图对应一个.txt每行class x_center y_center width height坐标归一化到 0-1另一套是裁好的人脸表情分类图按文件夹分angry、happy、sad、surprise等类别。很多人拿到包直接开训结果检测模型把「人脸」和「表情」混在一起标mAP 上不去。正确的目录结构应该是这样datasets/ ├── detection/ │ ├── images/ │ │ ├── train/ │ │ └── val/ │ └── labels/ │ ├── train/ │ └── val/ └── classification/ ├── train/ │ ├── angry/ │ ├── happy/ │ └── ... └── val/ ├── angry/ └── ...检测数据集只需要一个类别face不要给表情单独建类别。表情交给第二阶段的分类模型。如果你拿到的标注里表情和人脸混标了用下面这个脚本清洗import os import glob # 只保留 class_id 为 0 的人脸框丢弃表情类别标注 def clean_labels(label_dir, keep_class0): for txt_path in glob.glob(os.path.join(label_dir, *.txt)): with open(txt_path, r) as f: lines f.readlines() kept [] for line in lines: parts line.strip().split() if len(parts) 5 and int(parts[0]) keep_class: kept.append(line) with open(txt_path, w) as f: f.writelines(kept) # 如果清洗后文件为空说明这张图没有有效人脸框建议移出训练集 if not kept: print(f空标注文件建议检查: {txt_path}) clean_labels(datasets/detection/labels/train) clean_labels(datasets/detection/labels/val)逻辑说明YOLO 格式每行第一个数字是类别 idkeep_class0表示只保留人脸类。清洗后空文件要人工确认可能是原图就没有人脸也可能是标注丢了。这一步不做训练时会出现大量背景误检。2.3 data.yaml 配置路径写错是最常见的翻车点YOLOv8 训练靠data.yaml找数据这个文件写错路径报错信息往往很模糊。资源里的data.yaml模板长这样path: /home/user/datasets/detection # 数据集根目录绝对路径最稳 train: images/train val: images/val nc: 1 names: [face]注意path用绝对路径train和val是相对path的路径。Windows 下路径分隔符用/或\\不要用单个\否则 YAML 解析会出错。nc: 1表示只有一个类别names列表长度必须和nc一致否则训练启动就报索引越界。3. 模型训练与调参YOLOv8 人脸检测 表情分类的两阶段实现3.1 第一阶段人脸检测模型训练检测模型用 YOLOv8n 就够人脸检测不是复杂任务n 版本在 CPU 上也能跑。训练命令# 从预训练权重开始训练 100 轮图像尺寸 640 yolo detect train \ modelyolov8n.pt \ datadatasets/detection/data.yaml \ epochs100 \ imgsz640 \ batch16 \ lr00.01 \ patience20 \ projectruns/face_detect \ nameexp1参数说明modelyolov8n.pt会自动下载预训练权重第一次跑需要联网。imgsz640是输入分辨率人脸通常占画面比例小可以试imgsz960提升小脸召回但显存和耗时翻倍。patience20表示 20 轮验证指标不提升就早停防止过拟合。lr00.01是初始学习率YOLOv8 默认用余弦退火一般不用改。训练完看runs/face_detect/exp1/results.csv重点看metrics/mAP50-95和val/box_loss。如果 mAP 卡在 0.5 以下先检查标注质量再考虑加数据增强。资源教程里提到用labelme标注后转 YOLO 格式转换脚本在tools/labelme2yolo.py转换后务必用yolo detect val验证一遍。3.2 第二阶段表情分类模型训练检测模型输出人脸框后裁图送分类模型。分类模型可以直接用 YOLOv8 的classify模式也可以换成 ResNet、MobileNet。资源里给的是 YOLOv8-cls好处是同一套 ultralytics API不用额外装库。# 表情分类训练数据按文件夹分好类别 yolo classify train \ modelyolov8n-cls.pt \ datadatasets/classification \ epochs80 \ imgsz224 \ batch32 \ projectruns/expression_cls \ nameexp1参数说明imgsz224是分类输入尺寸人脸裁图后 224 足够。batch32在 CPU 上可能内存吃紧降到 16。分类数据集每个类别至少 200 张少于这个数建议先做数据增强或迁移学习。训练完看confusion_matrix.png如果happy和surprise混淆严重说明这两类视觉特征接近需要加更多样本或调整类别定义。3.3 两阶段串联推理脚本怎么写训练完两个模型串联推理的逻辑是检测模型出框 → 按框裁图 → 分类模型出表情标签 → 画回原图。from ultralytics import YOLO import cv2 # 加载两个模型 det_model YOLO(runs/face_detect/exp1/weights/best.pt) cls_model YOLO(runs/expression_cls/exp1/weights/best.pt) img cv2.imread(test.jpg) det_results det_model(img, conf0.5) # conf 过滤低置信度框 for box in det_results[0].boxes: x1, y1, x2, y2 map(int, box.xyxy[0]) face_crop img[y1:y2, x1:x2] if face_crop.size 0: continue cls_result cls_model(face_crop) label cls_result[0].names[cls_result[0].probs.top1] conf cls_result[0].probs.top1conf.item() # 画框和标签 cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.putText(img, f{label} {conf:.2f}, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2) cv2.imwrite(result.jpg, img)逻辑说明conf0.5是检测置信度阈值低于这个值的框丢弃避免把背景当人脸。face_crop.size 0是防御性检查框坐标越界时裁图会为空。分类结果取top1和top1conf如果置信度低于 0.6建议标成「不确定」而不是硬给一个表情标签。4. 避坑与排查表情识别项目里最容易翻车的五个点4.1 现象训练 loss 正常下降但 mAP 一直是 0原因data.yaml里names和标注文件里的类别 id 对不上或者标注文件路径写错YOLO 读到了空标签。解决用yolo detect val单独跑验证看输出里Instances数量是否为 0。如果是 0逐张检查.txt文件是否存在、内容是否为空。4.2 现象CPU 训练一轮要几个小时根本跑不完原因imgsz设太大或者batch太大导致内存交换。解决CPU 训练把imgsz降到 416batch降到 8epochs先设 30 轮看趋势。如果还是慢用yolov8n.pt而不是yolov8s.ptn 版本参数量最小。4.3 现象推理时人脸框位置偏移框到了背景原因训练集里人脸框标注不紧或者数据增强里mosaic把多张图拼在一起导致框错位。解决检查标注是否贴合人脸边缘训练时加mosaic0.0关闭马赛克增强看 mAP 是否回升。如果回升明显说明标注质量有问题需要重新标。4.4 现象表情分类总是偏向某一类比如全预测成 happy原因类别样本不均衡happy 样本远多于其他类。解决用yolo classify train时加augmentTrue或者在数据集层面做重采样。更直接的办法是算每个类别的样本数对少的类别做离线增强旋转、亮度调整补到均衡。4.5 现象模型导出 ONNX 后推理结果和 PyTorch 不一致原因导出时imgsz和推理时输入尺寸不一致或者预处理归一化参数不同。解决导出命令里显式指定imgsz640推理时也用 640。ONNX 推理的预处理要和训练时一致YOLOv8 默认是1/255归一化、RGB 通道不要额外做均值方差归一化。5. 进阶技巧用 RK3588 和 GTX 1660Ti 做部署验证的实操差异资源里的教程主要覆盖训练和 PC 端推理但实际项目往往要落到边缘设备。我拿手头的 GTX 1660Ti 和 RK3588 各跑了一遍差异很明显这里把关键参数和验证方法记下来。GTX 1660Ti 是 6GB 显存跑 YOLOv8n 检测 分类串联imgsz640时显存占用约 2.3GB单帧推理 12ms 左右。导出 TensorRT 引擎能压到 6ms但要注意 TensorRT 版本和 CUDA 驱动匹配。导出命令# 导出 TensorRT 引擎FP16 精度 yolo export modelruns/face_detect/exp1/weights/best.pt formatengine halfTrue imgsz640halfTrue开启 FP16精度损失很小速度提升约 40%。如果导出报错先确认tensorrt和pycuda装好版本对应 CUDA 11.8。RK3588 是 ARM 平台不能直接用 PyTorch需要转 RKNN。流程是 PyTorch → ONNX → RKNN。ONNX 导出时opset12不要用太新的 opsetRKNN 工具链对高版本支持不好。转 RKNN 的脚本在资源tools/目录下核心参数# RKNN 转换关键配置 rknn.config( mean_values[[0, 0, 0]], # YOLOv8 不做均值减法 std_values[[255, 255, 255]], # 除以 255 归一化 target_platformrk3588, quantized_dtypeasymmetric_quantized-8 # 8bit 量化 )量化后精度会掉 2-3 个点 mAP如果掉太多用混合量化把检测头部分保留 FP16。RK3588 上单帧推理约 35ms比 1660Ti 慢但功耗只有几瓦适合边缘部署。验证方法拿同一张测试图分别在 PyTorch、ONNX、RKNN 三个后端跑对比检测框坐标和分类标签。如果 RKNN 结果偏差大先检查量化校准集是否覆盖了各种光照和角度校准集至少 200 张从训练集里随机抽。从那以后我每次导出模型都强制走一遍「PyTorch → ONNX → 目标平台」的三方对比坐标偏差超过 5 个像素就回去查预处理。这个习惯帮我省掉了至少三次返工。希望帮到你。本文还有配套的精品资源点击获取
