共计 1799 个字符,预计需要花费 5 分钟才能阅读完成。
背景介绍
AffectNet 是当前最大的面部表情识别数据集,包含超过 100 万张面部图像,每张图像都标注了 8 类基本表情(如愤怒、快乐、悲伤等)和连续维度(如效价、唤醒度)。这种结合离散分类和连续维度的标注方式,使其在表情识别领域独树一帜。

痛点分析
- 数据分布不均衡:例如 contempt(轻蔑)类别的样本数量远少于其他类别,这会导致模型在训练时偏向于多数类。
- 标注噪声:复合表情(如又惊又喜)的标注存在歧义性,增加了模型学习的难度。
- 多任务学习的特征冲突:离散分类和连续维度标注可能要求模型学习相互冲突的特征。
技术方案
- 数据增强:使用 Albumentations 库实现鲁棒的数据增强,包括随机旋转、裁剪、颜色抖动等,以提高模型的泛化能力。
- 标签平滑:设计 Label Smoothing 损失函数,减少标注噪声对模型的影响。
- 多任务架构:采用共享主干网络(backbone)加任务特定头(task-specific heads)的架构,平衡多任务学习的特征共享与冲突。
代码示例
PyTorch 数据加载器
import torch
from torch.utils.data import Dataset
import albumentations as A
from albumentations.pytorch import ToTensorV2
class AffectNetDataset(Dataset):
def __init__(self, images, labels, transform=None):
self.images = images
self.labels = labels
self.transform = transform
def __len__(self):
return len(self.images)
def __getitem__(self, idx):
image = self.images[idx]
label = self.labels[idx]
if self.transform:
augmented = self.transform(image=image)
image = augmented['image']
return image, label
# 数据增强变换
transform = A.Compose([A.RandomRotate(30),
A.RandomCrop(224, 224),
A.ColorJitter(),
ToTensorV2(),])
多任务损失函数
import torch.nn as nn
class MultiTaskLoss(nn.Module):
def __init__(self, alpha=0.5):
super().__init__()
self.alpha = alpha # 权重参数,平衡分类和回归任务
self.ce_loss = nn.CrossEntropyLoss()
self.mse_loss = nn.MSELoss()
def forward(self, outputs, targets):
# outputs 包含分类和回归任务的输出
cls_output, reg_output = outputs
cls_target, reg_target = targets
# 计算分类和回归损失
loss_cls = self.ce_loss(cls_output, cls_target)
loss_reg = self.mse_loss(reg_output, reg_target)
# 加权总和
total_loss = self.alpha * loss_cls + (1 - self.alpha) * loss_reg
return total_loss
避坑指南
- 验证集划分:确保验证集的表情类别分布与训练集一致,避免评估偏差。
- 连续维度归一化 :对效价和唤醒度等连续维度进行归一化,通常缩放到[-1, 1] 区间。
- 混合精度训练:使用 AMP(Automatic Mixed Precision)时,注意梯度缩放(gradient scaling)以防止下溢。
延伸思考
- 小样本迁移学习:将 AffectNet 预训练的模型迁移到小样本场景时,可以冻结主干网络,仅微调任务特定头。
- 数据集对比:与 FER2013 相比,AffectNet 的规模更大、标注更丰富,但 FER2013 更易于获取和使用。
结语
通过本文的介绍和代码示例,希望能帮助初学者更好地理解和使用 AffectNet 数据集。在实际应用中,还需根据具体任务调整数据预处理和模型架构,以达到最佳效果。
正文完
