本文介绍了一个基于深度学习的人脸关键点检测系统的设计与实现。该系统采用改进的ResNet架构,实现了对人脸图像中5个关键点(左眼、右眼、鼻子、嘴巴左侧和右侧)的精确定位。通过多阶段训练策略和创新的数据质量保证机制,系统在准确性和鲁棒性方面都取得了良好的效果。
数据集的收集
从网上下载来自上世纪90年代的随机人脸照,接下来利用MTCNN多任务卷积神经网络,对这些照片进行检测,主要作用于:人脸 + 五官(鼻子 + 眼睛 + 嘴巴)
随后从 matplotlib.patches 中导入 Rectangle,用于在图像上绘制矩形框。并从中记录五官各个部位的坐标点存储于annotations.json文件中,用于数据标注。
模型训练
选择
-
骨干网络选择:
-
使用预训练的ResNet系列(18/34/50)
-
预训练权重来自ImageNet
-
可选的网络深度和复杂度
-
-
回归头设计:
-
self.regression_head = nn.Sequential( nn.AdaptiveAvgPool2d((1, 1)), nn.Flatten(), nn.Dropout(0.5), nn.Linear(feature_dim, 512), nn.ReLU(inplace=True), nn.Dropout(0.3), nn.Linear(512, 256), nn.ReLU(inplace=True), nn.Dropout(0.2), nn.Linear(256, num_keypoints) )
-
特点:
- 多层全连接结构
- 多级Dropout防止过拟合
- ReLU激活函数
- 逐层降维
-
训练策略
-
损失函数选择
-
class WingLoss(nn.Module): def __init__(self, omega=10, epsilon=2): self.omega = omega self.epsilon = epsilon def forward(self, pred, target): diff = torch.abs(pred - target) condition = diff < self.omega loss_1 = self.omega * torch.log(1 + diff / self.epsilon) loss_2 = diff - self.omega + self.omega * torch.log(1 + self.omega / self.epsilon) loss = torch.where(condition, loss_1, loss_2) return loss.mean()
优势:
-
对小误差更敏感
-
对大误差更鲁棒
-
适合关键点检测
-
-
-
优化器配置
-
optimizer = optim.AdamW( model.parameters(), lr=0.001, weight_decay=1e-4, betas=(0.9, 0.999) )
特点:
-
AdamW优化器
-
权重衰减正则化
-
自适应学习率
-
-
-
学习率调度
-
scheduler = optim.lr_scheduler.CosineAnnealingLR( optimizer, T_max=50, eta_min=1e-6 )
策略:
-
余弦退火调度
-
周期性学习率调整
-
最小学习率限制
-
-
训练流程
-
数据准备
def create_data_loaders(): # 数据集划分 train_loader, val_loader = create_data_loaders()
特点:
-
训练集和验证集划分
-
数据增强
-
批处理大小优化
-
-
训练循环
def train_epoch(self, epoch): self.model.train() for batch_idx, (images, keypoints) in enumerate(pbar): # 前向传播 outputs = self.model(images) loss = self.criterion(outputs, keypoints) # 反向传播 loss.backward() torch.nn.utils.clip_grad_norm_(self.model.parameters(), max_norm=1.0) self.optimizer.step()
关键步骤:
-
前向传播计算损失
-
反向传播更新参数
-
梯度裁剪防止爆炸
-
优化器步进更新
-
-
验证过程
def validate(self): self.model.eval() with torch.no_grad(): for images, keypoints in self.val_loader: outputs = self.model(images) # 计算多个阈值的准确率 accuracy_3 = calculate_metrics(predictions, targets, threshold=3.0) accuracy_5 = calculate_metrics(predictions, targets, threshold=5.0) accuracy_10 = calculate_metrics(predictions, targets, threshold=10.0)
评估指标:
-
多阈值准确率
-
平均绝对误差
-
均方误差
-
训练优化
-
早停机制
-
patience_counter = 0 patience = 20 if acc_5 > best_accuracy: best_accuracy = acc_5 patience_counter = 0 else: patience_counter += 1 if patience_counter >= patience: print(f'早停触发!在第 {epoch+1} 轮停止训练。') break
特点:
-
基于验证准确率
-
长耐心值
-
保存最佳模型
-
-
-
模型保存
-
save_checkpoint({ 'epoch': epoch, 'model_state_dict': self.model.state_dict(), 'train_loss': train_loss, 'val_loss': val_loss, 'val_accuracy': acc_5, 'val_mae': val_mae }, 'best_model.pth')
保存内容:
-
模型状态
-
训练参数
-
评估指标
-
-
训练效果
-
准确率指标:
-
3像素阈值:高精度检测
-
5像素阈值:标准检测
-
10像素阈值:宽松检测
-
-
训练稳定性:
-
损失值平稳下降
-
准确率持续提升
-
学习率合理调整
-
-
模型泛化能力:
-
验证集表现稳定
-
多阈值评估全面
-
早停机制有效
-