Skip to content

KerroKapple/Emo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

30 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🤖 AI表情识别系统

基于深度学习的实时人脸表情分类系统,支持多种CNN架构(ResNet、VGG、MobileNet、EfficientNet等),提供模型训练、评估、优化(量化/剪枝/知识蒸馏)及Web演示功能。

📋 项目简介

本项目实现了一个完整的表情识别系统,能够识别5种基本表情:

  • 😠 愤怒 (Anger)
  • 😨 恐惧 (Fear)
  • 😊 快乐 (Happy)
  • 😢 悲伤 (Sad)
  • 😲 惊讶 (Surprise)

✨ 主要特性

  • 多模型支持:自定义CNN、ResNet18/34/50、VGG16、MobileNetV2、EfficientNet-B0
  • 迁移学习:支持ImageNet预训练权重,大幅提升训练效率
  • 模型优化:支持动态量化、模型剪枝、知识蒸馏
  • 数据清洗:自动检测并处理损坏、重复、低质量图片
  • Web演示:基于Flask的可视化界面,支持图片上传和摄像头拍照
  • 批量训练:一键训练多个模型并生成对比报告

📁 项目结构

emotion-recognition/
├── app.py                      # Flask Web服务入口
├── pyproject.toml              # 项目依赖(uv 管理)
├── LICENSE                     # MIT 许可证
│
├── src/                        # 核心代码
│   ├── config.py              # 集中配置(路径、类别、输入尺寸、超参)
│   ├── model.py               # 模型工厂(CNN + 迁移学习注册表、按模型的输入尺寸)
│   ├── transforms.py          # 按模型构建预处理/增强管线
│   ├── inference.py           # 自描述 checkpoint 的保存/加载与单图推理
│   ├── dataset.py             # 数据集加载与清洗
│   ├── train.py               # 单模型训练脚本
│   ├── train_multiple.py      # 批量训练与对比
│   ├── evaluate.py            # 模型评估工具
│   ├── optimize_distill.py    # 模型优化(量化/剪枝/蒸馏)
│   ├── assets.py              # 运行时资产注册表(YuNet/HSEmotion 下载与缓存)
│   ├── face/                  # 人脸检测与裁剪(YuNet)
│   ├── engine/                # 可替换推理后端(onnxruntime,可扩展 RKNN/ncnn)
│   ├── runtime/               # 情绪核心运行时(单帧编排、时序平滑、Demo)
│   ├── logging_setup.py       # 统一日志
│   └── utils.py               # 工具函数(随机种子、数据划分、可视化)
│
├── templates/
│   └── index.html             # Web演示前端页面
│
├── tests/                      # pytest 测试
├── docs/                       # 设计稿与实施计划
│
├── data/                       # 数据目录(需自行准备)
│   ├── raw/                   # 原始数据(anger/fear/happy/sad/surprise)
│   ├── train/                 # 训练集(自动生成)
│   └── val/                   # 验证集(自动生成)
│
├── models/                     # 模型权重
│   ├── best_model_*.pth       # 训练产物
│   ├── face/yunet.onnx        # 人脸检测(自动下载)
│   └── emotion/*.onnx         # 情绪模型(自动下载)
│
└── results/                    # 训练结果(自动生成)

🚀 快速开始

1. 环境配置

# 克隆项目
git clone <repository-url>
cd emotion-recognition

# 安装依赖(使用 uv)
uv sync

2. 准备数据

将表情图片按类别放入 data/raw/ 目录:

data/raw/
├── anger/      # 愤怒表情图片
├── fear/       # 恐惧表情图片
├── happy/      # 快乐表情图片
├── sad/        # 悲伤表情图片
└── surprise/   # 惊讶表情图片

支持的图片格式:JPG、JPEG、PNG、BMP

3. 数据划分

uv run python -m src.utils

这将自动清洗数据并按8:2比例划分为训练集和验证集。

4. 模型训练

训练单个模型:

# 默认 EfficientNet-B0;用命令行参数覆盖
uv run python -m src.train --model resnet18 --epochs 20 --batch-size 64 --lr 0.001
# 强制 CPU
uv run python -m src.train --model mobilenet --cpu

可选模型:cnn, resnet18, resnet34, resnet50, vgg16, mobilenet, efficientnet。 训练已内置:类别加权损失、label smoothing、weight decay、随机种子、早停、CUDA 自动混合精度。

输入尺寸自动按模型选择:迁移学习骨干用 224×224(ImageNet 标准),自定义 CNN 用 48×48。

批量训练多个模型:

# 训练全部
uv run python -m src.train_multiple
# 仅训练指定模型
uv run python -m src.train_multiple --models resnet18 mobilenet efficientnet

自动生成对比报告与图表。

5. 模型评估

# 评估 models/ 下所有模型并生成对比报告
uv run python -m src.evaluate --all
# 评估单个 checkpoint
uv run python -m src.evaluate --model-path models/best_model_resnet18.pth
# 预测单张图片
uv run python -m src.evaluate --model-path models/best_model_resnet18.pth --image path/to/img.jpg

checkpoint 自带模型类型等元信息,评估/部署时无需手动指定 model_type

6. 启动Web演示

# 启动 Web(默认仅本机访问 127.0.0.1:5000,使用 waitress 生产服务器)
uv run python app.py
# 对外访问(waitress):FLASK_HOST=0.0.0.0 uv run python app.py
# 开发调试(仅限本机;调试器有 RCE 风险,代码会强制 127.0.0.1):
# FLASK_DEBUG=1 uv run python app.py

访问 http://localhost:5000 查看 Web 界面。启动时会自动加载首个 best_model_*.pth

🤖 情绪核心(边缘推理)

硬件无关的实时人脸情绪推理闭环,可作陪伴机器人等嵌入式设备的感知核心。

# 开箱即用:自动下载 YuNet + HSEmotion 预训练模型(AffectNet 8 类,含 Neutral)
uv run python -m src.runtime.demo --camera 0
# 或对单张图片推理
uv run python -m src.runtime.demo --image face.jpg
# 预先下载全部运行时资产
uv run python -m src.assets

# 换用自训模型(如 Plan 1B 蒸馏量化产物)
uv run python -m src.runtime.demo --camera 0 \
    --emotion-model models/emotion_int8.onnx \
    --labels anger fear happy sad surprise --input-size 112

链路:取帧 → YuNet 检测裁脸 → ONNX 情绪模型(onnxruntime)→ 时序平滑 → 情绪事件。 推理后端(src/engine/)可替换为 RKNN/ncnn 而不改动 runtime;设计见 docs/superpowers/specs/2026-06-11-embedded-emotion-core-design.md

🔧 模型详解

可用模型对比

模型 参数量 预计准确率 训练速度 推荐场景
Custom CNN ~590万 60-70% 学习CNN原理
ResNet18 ~1120万 75-85% 推荐首选
ResNet34 ~2150万 78-88% 更高准确率
ResNet50 ~2350万 80-90% 最高准确率
VGG16 ~1.38亿 75-85% 很慢 经典架构学习
MobileNetV2 ~220万 70-80% 最快 移动端部署
EfficientNet-B0 ~410万 78-88% 最佳平衡

模型选择建议

  • 初学者/快速实验:MobileNet(训练最快)
  • 实际项目首选:ResNet18 或 EfficientNet-B0
  • 追求最高准确率:ResNet50
  • 移动端部署:MobileNet + 量化
  • 学习CNN原理:Custom CNN

⚡ 模型优化

动态量化

将 FP32 模型的线性层转换为 INT8(eager 模式动态量化仅作用于 nn.Linear):

uv run python -m src.optimize_distill --mode quantize --model-path models/best_model_resnet18.pth

模型剪枝

全局非结构化 L1 剪枝(剪枝后建议微调以恢复准确率):

uv run python -m src.optimize_distill --mode prune --model-path models/best_model_resnet18.pth --amount 0.3

知识蒸馏

将大模型的知识迁移到小模型:

uv run python -m src.optimize_distill --mode distill \
  --teacher-path models/best_model_resnet50.pth --student resnet18 --epochs 15

推荐组合:

  • ResNet50 → ResNet18
  • EfficientNet → MobileNet
  • ResNet18 → MobileNet

📊 API接口说明

获取可用模型

GET /api/models

加载模型

POST /api/load_model
Content-Type: application/json

{
    "model_filename": "best_model_resnet18.pth"
}

预测表情

POST /api/predict
Content-Type: application/json

{
    "image": "data:image/jpeg;base64,..."
}

响应示例:

{
    "predicted_class": "happy",
    "predicted_class_zh": "快乐",
    "emoji": "😊",
    "confidence": 0.953,
    "probabilities": {
        "anger": {"zh": "愤怒", "emoji": "😠", "probability": 0.01},
        "fear": {"zh": "恐惧", "emoji": "😨", "probability": 0.02},
        "happy": {"zh": "快乐", "emoji": "😊", "probability": 0.953},
        "sad": {"zh": "悲伤", "emoji": "😢", "probability": 0.01},
        "surprise": {"zh": "惊讶", "emoji": "😲", "probability": 0.007}
    }
}

服务状态

GET /api/status

📈 训练技巧

数据增强

训练时默认启用以下增强:

  • 随机水平翻转 (p=0.5)
  • 随机旋转 (±10°)
  • 颜色抖动 (亮度/对比度 ±0.2)

学习率调度

使用 ReduceLROnPlateau:当验证准确率不再提升时自动降低学习率。

防止过拟合

  • Dropout (Conv层: 0.25, FC层: 0.5)
  • BatchNormalization
  • 早停(保存最佳模型)

🔍 数据清洗

系统自动检测并处理以下问题:

  • 损坏图片:无法打开或读取
  • 格式错误:非标准图像格式
  • 尺寸异常:过小(<32px)或过大(>2000px)
  • 质量过低:全黑/全白或方差过小
  • 重复图片:基于MD5哈希去重

问题文件会被移动到 data/quarantine/ 目录。

⚙️ 配置要求

最低配置

  • Python 3.10+
  • 8GB RAM
  • 10GB 磁盘空间

推荐配置

  • Python 3.10+
  • 16GB RAM
  • NVIDIA GPU (CUDA 11.0+)
  • 20GB+ 磁盘空间

🧪 开发

# 运行测试
uv run pytest -q
# 代码检查
uv run ruff check src app.py tests

📝 注意事项

  1. GPU加速:如有NVIDIA GPU,确保安装CUDA版本的PyTorch
  2. 数据隐私:训练数据不会上传到任何服务器
  3. 模型文件.pth 文件较大,已在 .gitignore 中排除
  4. 首次训练:预训练模型权重会自动从网络下载

🤝 贡献指南

欢迎提交Issue和Pull Request!

  1. Fork本仓库
  2. 创建特性分支 (git checkout -b feature/AmazingFeature)
  3. 提交更改 (git commit -m 'Add some AmazingFeature')
  4. 推送到分支 (git push origin feature/AmazingFeature)
  5. 开启Pull Request

📄 许可证

本项目采用 MIT 许可证。详见 LICENSE 文件。

📧 联系方式

如有问题或建议,请通过以下方式联系:


如果这个项目对你有帮助,请给个 ⭐ Star!

About

基于深度学习的实时人脸表情分类系统,支持多种CNN架构(ResNet、VGG、MobileNet、EfficientNet等),提供模型训练、评估、优化(量化/剪枝/知识蒸馏)及Web演示功能。

Topics

Resources

License

Stars

3 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors