资讯动态

Yolov5人脸表情异常行为检测源码:从环境配置到训练部署全流程

发布时间:2026/10/3 14:15:49 来源:尧图企业网站定制
简介本资源是一套基于Yolov5与Python实现的人脸识别、人脸细粒度表情识别及异常行为检测的完整源码项目面向计算机视觉方向的初学者、毕业设计学生及课程大作业开发者可帮助快速搭建具备人脸检测、表情分类与行为分析能力的应用系统。压缩包共107个文件约24.81MB以37个py源码文件为核心辅以18个yaml配置、21个txt说明、10张jpg与4张png示例图另含pt权重、ui界面文件、mat数据及Dockerfile覆盖训练、推理与部署环节。目前已有269人学习下载。项目代码注释详尽新手也能理解功能完善、界面美观、操作简单经过严格调试可稳定运行可直接作为毕设、期末大作业或课程设计的高分参考具有较高的实际应用价值。1. 从一份能跑通的 Yolov5 人脸表情异常行为源码说起如果你正在找一份能直接跑起来、代码注释齐全、还带界面的人脸识别加表情识别加异常行为检测的 Python 项目这份基于 Yolov5 的源码包大概率能省掉你从零搭框架的两周时间。它不是那种只丢几个 .py 文件让你自己猜怎么跑的半成品而是把 Dockerfile、示例图片、模型推理脚本、界面逻辑都打包好了下载解压后按步骤装依赖就能看到摄像头或图片流里的检测结果。适合三类人赶毕设或期末大作业的学生、想快速验证 Yolov5 多任务推理的算法新手、需要一个人脸加行为分析 demo 给客户看的产品原型开发者。我拆过不少类似项目这份的完整度算中上坑也有下面按是什么、怎么跑、哪里翻车、怎么改的顺序讲透。2. Yolov5 做多任务推理人脸、表情、行为怎么串起来2.1 为什么选 Yolov5 而不是 MTCNN 或 RetinaFace人脸识别这个领域传统方案是 MTCNN 做检测、FaceNet 做特征比对、再加一个分类网络做表情。这套组合精度不差但部署时你要维护三个模型、三套预处理逻辑对新手极不友好。Yolov5 的优势在于它是一个统一的目标检测框架你可以把人脸当成一个类别去训练也可以把表情类别直接作为检测类别输出。常见做法是先用 Yolov5 检测出人脸框再在框内做细粒度表情分类异常行为则通过人脸框的位置变化加时序逻辑判断。这样一套 Yolov5 权重加一个轻量分类头就能覆盖三个功能推理链路短调试时只需要盯一个模型的输出。选 Yolov5 而不是 Yolov8 或 RT-DETR主要原因是这份源码的生态适配。Yolov5 的detect.py、train.py、export.py脚本成熟网上关于yolov5训练自己的数据集的教程最多你遇到问题搜得到答案。Yolov8 虽然更新但很多毕设模板和教程还没跟上改起来反而费劲。这份源码用的是 Yolov5 的标准结构models/、utils/、data/目录都在你按官方文档改配置就能跑。2.2 源码目录结构与核心文件职责拿到压缩包后先别急着python detect.py。花五分钟看清楚目录能避免后面 80% 的找不到文件报错。典型结构如下project/ ├── Dockerfile # 容器化部署脚本 ├── detect.py # 推理入口支持图片/视频/摄像头 ├── train.py # 训练脚本换数据集时用 ├── requirements.txt # Python 依赖清单 ├── models/ │ ├── common.py # 网络基础模块 │ └── yolo.py # Yolov5 模型定义 ├── utils/ │ ├── datasets.py # 数据加载与增强 │ ├── general.py # 非极大值抑制等通用函数 │ └── plots.py # 画框、写标签 ├── data/ │ ├── images/ # 示例图片含 0.jpg、1.jpg、2440.jpg 等 │ └── hyps/ # 超参数 yaml ├── weights/ │ └── best.pt # 训练好的权重 └── ui/ # 界面相关代码如有detect.py是入口它读取weights/best.pt对data/images/下的图片或摄像头流做推理。Dockerfile里通常写好了基础镜像和依赖安装命令如果你不想配环境直接docker build能省事。data/images/里的0.jpg、1.jpg、2440.jpg、2441.jpg、example2.jpg是作者留的测试图用来验证模型能不能正常出框。1620298460804.gif可能是演示动图不影响运行。2.3 环境配置conda 建环境与依赖安装新手最容易卡在环境上。我一般用 conda 建独立环境避免和系统 Python 打架。步骤如下# 创建 Python 3.8 环境Yolov5 对 3.8/3.9 兼容最好 conda create -n yolo_face python3.8 -y conda activate yolo_face # 安装 PyTorch根据你的 CUDA 版本选没有 GPU 就用 CPU 版 # CUDA 11.3 示例 pip install torch1.12.1cu113 torchvision0.13.1cu113 -f https://download.pytorch.org/whl/torch_stable.html # 安装项目依赖 pip install -r requirements.txtrequirements.txt里通常包含opencv-python、numpy、pillow、pyyaml、tqdm、matplotlib等。如果安装opencv-python时报错先pip install --upgrade pip再试。没有 GPU 的话把 torch 换成 CPU 版pip install torch1.12.1cpu torchvision0.13.1cpu -f https://download.pytorch.org/whl/torch_stable.html。装完后用python -c import torch; print(torch.cuda.is_available())验证返回True说明 GPU 可用。2.4 跑通第一张图detect.py 参数详解环境好了先拿示例图试。命令如下python detect.py --weights weights/best.pt --source data/images/0.jpg --img-size 640 --conf-thres 0.25 --device 0参数逐个说--weights指向训练好的权重没有的话先确认weights/目录下有没有best.pt或last.pt--source可以是单张图、文件夹、视频文件或0摄像头--img-size 640是推理分辨率Yolov5 默认 640改大精度升速度降--conf-thres 0.25是置信度阈值低于这个值的框会被丢掉人脸检测一般 0.25 到 0.5 之间--device 0指定第一块 GPUCPU 跑就写--device cpu。跑完结果默认存在runs/detect/exp/下打开图片能看到人脸框和类别标签。如果报AssertionError: No such file or directory九成是路径写错了。--source的相对路径是相对于你执行命令的目录不是脚本所在目录。保险做法是cd到项目根目录再执行或者用绝对路径。3. 表情识别与异常行为检测从检测框到语义输出3.1 细粒度表情识别的接入方式Yolov5 本身输出的是人脸这个类别的框表情识别需要额外一步。常见两种接法一种是把表情类别直接合并进 Yolov5 的检测类别比如person_face_happy、person_face_angry训练时标注就带上表情标签另一种是 Yolov5 出人脸框后裁剪框内区域送进一个独立的分类网络如 ResNet18 或 MobileNetV3做七分类。这份源码大概率用的是第二种因为细粒度通常意味着分类头单独训练。如果你要自己接分类头核心代码逻辑如下import cv2 import torch from models.common import DetectMultiBackend from utils.general import non_max_suppression # 加载 Yolov5 模型 model DetectMultiBackend(weights/best.pt, devicecuda:0) model.eval() # 加载表情分类模型假设已训练好 emotion_model torch.load(weights/emotion_resnet18.pt, map_locationcuda:0) emotion_model.eval() emotion_labels [angry, disgust, fear, happy, sad, surprise, neutral] img cv2.imread(data/images/1.jpg) img_rgb cv2.cvtColor(img, cv2.COLOR_BGR2RGB) tensor torch.from_numpy(img_rgb).permute(2, 0, 1).float().unsqueeze(0) / 255.0 tensor tensor.cuda() # Yolov5 推理 pred model(tensor) pred non_max_suppression(pred, conf_thres0.25, iou_thres0.45) for det in pred: if det is not None and len(det): for *xyxy, conf, cls in det: x1, y1, x2, y2 map(int, xyxy) face img_rgb[y1:y2, x1:x2] face_tensor torch.from_numpy(face).permute(2, 0, 1).float().unsqueeze(0) / 255.0 face_tensor torch.nn.functional.interpolate(face_tensor, size(224, 224)) face_tensor face_tensor.cuda() with torch.no_grad(): emotion_out emotion_model(face_tensor) emotion_idx emotion_out.argmax(dim1).item() label emotion_labels[emotion_idx] cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.putText(img, label, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2) cv2.imwrite(runs/emotion_result.jpg, img)这段代码先跑 Yolov5 拿到人脸框再把框内区域缩放到 224x224 送进表情分类模型。non_max_suppression的conf_thres和iou_thres是后处理参数iou_thres控制重叠框合并人脸密集场景可以调到 0.5 以上。表情分类模型的输入尺寸要和训练时一致不一致的话interpolate那步必须加。3.2 异常行为检测的时序逻辑异常行为检测比表情更依赖场景定义。常见做法是如果检测到人脸框在连续帧中快速移动、或者人脸消失又出现、或者多人聚集且表情为愤怒/恐惧的比例超过阈值就触发异常告警。这份源码里可能用了一个简单的状态机或滑动窗口。核心思路是维护一个帧队列对每帧的检测结果做统计。from collections import deque # 维护最近 30 帧的检测结果 history deque(maxlen30) def check_abnormal(detections, frame_idx): # detections: 当前帧的人脸框列表和表情标签 history.append(detections) if len(history) 30: return False # 统计最近 30 帧中愤怒恐惧的比例 negative_count 0 total_count 0 for frame_dets in history: for det in frame_dets: total_count 1 if det[emotion] in [angry, fear]: negative_count 1 if total_count 0: return False ratio negative_count / total_count # 负面表情占比超过 60% 判定为异常 return ratio 0.6deque(maxlen30)是固定长度队列自动丢弃旧帧。ratio 0.6这个阈值需要根据你的场景调监控场景可以低一点课堂场景可以高一点。异常行为不一定只看表情还可以结合人脸框面积变化率突然变大说明有人靠近摄像头、框中心点位移速度等。这些逻辑都在 Python 层做不涉及模型改动改起来灵活。3.3 用 Dockerfile 一键部署如果你不想在本地配环境或者要部署到服务器Dockerfile是现成的。典型内容如下FROM pytorch/pytorch:1.12.1-cuda11.3-cudnn8-runtime WORKDIR /app COPY requirements.txt . RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple COPY . . CMD [python, detect.py, --weights, weights/best.pt, --source, 0]构建和运行docker build -t yolo_face . docker run --gpus all -it --rm -v $(pwd)/data:/app/data yolo_face--gpus all让容器能用宿主机的 GPU需要先装 nvidia-docker。-v把本地data目录挂进容器这样推理结果能存到宿主机。如果构建时 pip 下载慢把requirements.txt里的包换成国内源或者提前把 wheel 文件下好放本地。4. 避坑与排查那些让我重装三次环境的问题4.1 报错 No module named utils 或 No module named models现象在detect.py所在目录执行python detect.py提示找不到utils或models模块。原因Python 的模块搜索路径默认是执行命令的目录如果你在别的目录用绝对路径执行脚本项目根目录不在sys.path里。解决cd到项目根目录再执行或者在脚本开头加import sys; sys.path.append(/path/to/project)。我一般直接在项目根目录开终端省事。4.2 CUDA out of memory现象推理时显存爆了报RuntimeError: CUDA out of memory。原因--img-size设太大或者同时跑了多个进程占着显存。解决先把--img-size降到 416 或 320 试再不行就--device cpu跑。如果必须用 GPU用nvidia-smi看哪个进程占着显存kill掉不用的。另外--batch-size在推理时默认是 1一般不是它的问题。4.3 检测框位置偏移或框不住人脸现象跑出来的图框的位置和人脸对不上或者框太大太小。原因Yolov5 的输入预处理是 letterbox会保持长宽比缩放并填充灰边如果你的后处理没按 letterbox 的缩放比例还原坐标框就会偏。解决用官方utils/general.py里的scale_coords函数还原坐标不要自己手写。这份源码如果改了后处理重点检查scale_coords的调用参数。4.4 表情识别结果全是同一类现象不管输入什么图表情分类输出都是 neutral 或 happy。原因表情分类模型没加载成功或者输入预处理和训练时不一致比如训练用了 BGR推理用了 RGB。解决先单独测表情模型用一张已知表情的图看输出。检查cv2.cvtColor有没有加归一化的均值方差和训练时是否一致。如果模型是别人训的问清楚预处理流程。4.5 Docker 构建时 pip 安装超时现象docker build卡在pip install那步最后报 timeout。原因容器内默认走国外源网络不稳定。解决在Dockerfile的pip install命令后加-i https://pypi.tuna.tsinghua.edu.cn/simple或者用--trusted-host。如果还慢把requirements.txt里的包版本固定提前下载 wheel 文件放到项目里Dockerfile里用pip install --no-index --find-links./wheels -r requirements.txt。5. 进阶换自己的数据集训练与模型导出5.1 用 labelImg 标注人脸和表情数据想用自己的数据跑第一步是标注。Yolov5 要求 YOLO 格式的 txt 标签每行class_id x_center y_center width height坐标归一化到 0 到 1。用labelImg这个工具安装pip install labelImg然后labelImg启动。打开图片目录选 YOLO 格式画框选类别。如果你要把表情也标进去类别列表就写face_happy、face_angry等。标完每张图对应一个同名 txt 文件。标注时注意人脸框尽量贴紧脸部轮廓不要包含太多背景同一张图多人脸都要标表情类别定义要统一不要一会儿happy一会儿smile。标完把图片和 txt 按 8:1:1 分到images/train、images/val、images/test和对应的labels/目录下。5.2 修改 data.yaml 与超参数在data/下新建face_emotion.yamltrain: ../data/images/train val: ../data/images/val test: ../data/images/test nc: 7 names: [angry, disgust, fear, happy, sad, surprise, neutral]nc是类别数names顺序要和标注时的 class_id 对应。然后改data/hyps/hyp.scratch-low.yaml里的学习率新手建议先用默认的跑通了再调。训练命令python train.py --data data/face_emotion.yaml --weights yolov5s.pt --img 640 --epochs 100 --batch-size 16 --device 0--weights yolov5s.pt是预训练权重从官方仓库下不要从零训。--epochs 100对小型数据集够了数据少的话 50 也行。--batch-size根据显存调8G 显存跑 640 分辨率一般能到 16。5.3 导出 ONNX 或 TensorRT 加速推理训练完想部署到边缘设备导出 ONNX 是常见做法python export.py --weights runs/train/exp/weights/best.pt --include onnx --img 640 --batch 1导出的best.onnx可以用 ONNX Runtime 或 TensorRT 加载。如果目标平台是树莓派或 Jetson导出 TensorRT 引擎python export.py --weights runs/train/exp/weights/best.pt --include engine --img 640 --batch 1 --device 0导出时--img要和推理时一致不一致会导致精度下降。ONNX 模型用onnxruntime推理时输入名字通常是images输出是output用 Netron 打开看一眼确认。5.4 验证模型是否真的学到了东西训练完别只看 loss 曲线用验证集跑一遍val.pypython val.py --data data/face_emotion.yaml --weights runs/train/exp/weights/best.pt --img 640 --conf 0.001 --iou 0.6看 mAP0.5 和 mAP0.5:0.95 两个指标。mAP0.5 低于 0.5 说明模型没学好检查标注质量、类别平衡、学习率。如果某一类特别低可能是该类样本太少用--augment做数据增强或者手动补样本。我一般还会把验证集里预测错的图挑出来看是框偏了还是类别错了比看数字直观。从那以后我每次拿到新数据集都强制先跑 10 个 epoch 看 mAP 有没有动静没动静就回头查标注不硬训。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑