1. 项目背景与核心目标
这个课程设计/毕业设计项目聚焦于计算机视觉领域的一个经典问题:基于卷积神经网络的人脸属性识别。具体来说,我们需要同时解决两个分类任务——性别识别和情感识别。这在实际应用中具有广泛价值,比如智能零售中的顾客分析、人机交互系统的情感反馈、安防监控的嫌疑人特征提取等。
传统方法通常将这两个任务分开处理,但现代深度学习框架允许我们构建一个端到端的多任务学习模型。改进卷积模型的核心在于:如何在保证准确率的前提下,降低模型复杂度,使其能够在普通计算设备上运行。这也是本项目区别于常规方案的关键创新点。
2. 技术方案设计思路
2.1 基准模型选择
经过对比测试,我们选择MobileNetV3作为基础架构,主要基于以下考虑:
- 轻量化设计,参数量仅为传统ResNet的1/10
- 引入了注意力机制,适合细粒度分类
- 支持多任务学习的特征提取层设计
- 在移动端设备上的推理速度优势
实际测试中发现,在CelebA和FER2013数据集上,MobileNetV3的推理速度比ResNet50快3倍,而准确率仅下降2-3个百分点
2.2 改进方案详解
我们在原始MobileNetV3基础上做了三处关键改进:
多尺度特征融合模块:
- 在倒数第二个bottleneck后增加特征金字塔结构
- 通过1×1卷积统一不同层级特征图的通道数
- 使用双线性插值进行上采样融合
- 代码实现示例:
class FeatureFusion(nn.Module): def __init__(self, channels): super().__init__() self.conv1 = nn.Conv2d(channels*2, channels, 1) self.conv2 = nn.Conv2d(channels, channels, 3, padding=1) def forward(self, x_low, x_high): x_high = F.interpolate(x_high, scale_factor=2, mode='bilinear') x = torch.cat([x_low, x_high], dim=1) return self.conv2(self.conv1(x))
动态权重分配机制:
- 针对多任务学习设计自适应损失权重
- 根据各任务当前epoch的准确率动态调整
- 公式实现:
w_i = exp(r_i/t) / Σexp(r_j/t) 其中r_i表示任务i的当前准确率,t为温度系数
知识蒸馏策略:
- 使用预训练的EfficientNet作为教师模型
- 仅在训练阶段引入,不增加推理计算量
- 设计专门的蒸馏损失函数:
L_distill = α*KL(Teacher||Student) + (1-α)*CE_Loss
3. 数据集准备与预处理
3.1 数据来源
我们组合使用了两个公开数据集:
- CelebA:包含202,599张名人脸部图像,有40种属性标注(含性别)
- FER2013:35,887张面部表情图像,标注7种基本情绪
实际应用中需要注意两个数据集的标注差异:CelebA的性别标注为binary,而FER2013的情感分类包含7个类别
3.2 数据增强方案
为提高模型泛化能力,我们设计了组合增强策略:
train_transform = transforms.Compose([ transforms.RandomResizedCrop(224), transforms.RandomHorizontalFlip(), transforms.ColorJitter(brightness=0.2, contrast=0.2), transforms.RandomRotation(15), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ])特别针对人脸数据的特点:
- 限制旋转角度在±15°以内(避免五官错位)
- 色彩抖动幅度控制在0.2(保留肤色特征)
- 使用Albumentations库实现更高效的图像处理
4. 模型训练细节
4.1 超参数配置
经过网格搜索确定的最佳参数组合:
| 参数名称 | 取值 | 搜索范围 |
|---|---|---|
| 初始学习率 | 3e-4 | [1e-5, 1e-3] |
| batch_size | 64 | [32, 128] |
| 优化器 | AdamW | Adam/RMSprop |
| 学习率衰减 | Cosine | Step/Cosine |
| 温度系数t | 2.0 | [1.0, 5.0] |
| 蒸馏权重α | 0.7 | [0.5, 0.9] |
4.2 训练过程监控
我们使用WandB进行实验跟踪,关键观察指标:
- 各任务验证集准确率曲线
- 动态权重变化趋势
- 特征可视化(t-SNE降维)
- 计算资源消耗监控
典型的训练曲线显示:
- 性别分类任务在第15个epoch左右收敛
- 情感分类需要约30个epoch达到稳定
- 动态权重机制在第10个epoch后开始显著调整
5. 部署与优化技巧
5.1 模型压缩方案
为适配移动端部署,我们采用以下优化策略:
量化感知训练:
- 在训练时模拟8bit量化效果
- 使用PyTorch的QAT工具包
- 关键配置:
model.qconfig = torch.quantization.get_default_qat_qconfig('fbgemm') torch.quantization.prepare_qat(model, inplace=True)
剪枝优化:
- 基于幅度的结构化剪枝
- 移除小于阈值(1e-3)的卷积核
- 迭代式剪枝:每次剪枝20%后fine-tune
ONNX转换:
- 导出为标准化格式
- 使用TensorRT进一步优化
5.2 实际应用示例
在树莓派4B上的部署效果:
| 指标 | 原始模型 | 优化后 |
|---|---|---|
| 模型大小 | 23MB | 6.8MB |
| 推理延迟 | 120ms | 45ms |
| 内存占用 | 280MB | 90MB |
| 准确率下降 | - | <1% |
6. 常见问题与解决方案
6.1 数据不均衡处理
FER2013中各类表情样本量差异较大:
| 表情类别 | 样本数量 | 处理方案 |
|---|---|---|
| Happy | 7215 | 降采样 |
| Sad | 4830 | 保持 |
| Angry | 3995 | 过采样 |
我们采用改进的focal loss:
class BalancedFocalLoss(nn.Module): def __init__(self, alpha=0.25, gamma=2): super().__init__() self.alpha = alpha self.gamma = gamma def forward(self, inputs, targets): BCE_loss = F.binary_cross_entropy_with_logits(inputs, targets, reduction='none') pt = torch.exp(-BCE_loss) loss = self.alpha * (1-pt)**self.gamma * BCE_loss return loss.mean()6.2 跨数据集泛化问题
当测试数据与训练集分布不一致时:
- 使用Domain Adaptation技术
- 添加梯度反转层(GRL)
- 采用对抗训练策略
实测在RAF-DB数据集上的准确率提升:
- 基线模型:58.2%
- 使用DA后:63.7%
7. 扩展应用方向
基于此框架可以进一步开发:
- 实时视频分析系统
- 使用OpenCV捕获视频流
- 多线程处理框架设计
- 结合语音的情感多模态分析
- 年龄估计等附加属性预测
一个完整的应用示例代码结构:
app/ ├── core/ │ ├── model.py # 模型定义 │ ├── processor.py # 预处理流水线 ├── web/ │ ├── api.py # FastAPI接口 │ ├── static/ # 前端资源 ├── config.yaml # 配置文件在开发这类项目时,有几个关键经验值得分享:
- 多任务学习的平衡很重要,建议先单独训练各任务,再联合微调
- 人脸检测器的质量直接影响最终效果,推荐使用RetinaFace
- 实际部署时要考虑光照条件变化,建议增加测试时的光照归一化处理
- 对于课程设计项目,可以适当简化模型结构,重点展示完整流程