Facial Emotion Recognition: State of the Art Performance on FER2013

[1] Khaireddin Y , Chen Z . Facial Emotion Recognition: State of the Art Performance on FER2013[J]. 2021.

本文在Fer2013数据集上实现了当时的SOTA精度,本文的并没有提出什么新的网络或者插件,使用了VGG19,只是在诸如优化器、学习率衰减等的常用选择上进行了一些比较,选出对于当前网络和数据增强上最优的组合,最终在测试集上得到了73.28%的精度。

在第3.4节讲了优化器对比实验、学习率衰减对比试验和微调实验

在3.5节讲了各种实验中一些表现好或者不好的原理分析,值得一看。

0、摘要

人脸表情识别FER对于人机交互是有重大意义的,但是由于人脸不均匀性和不同脸部姿态光照等变化,所以精度和鲁棒性这块很有挑战性。

在本文中,我们在FER2013上实现了最好的单网络(single-network)分类精度,我们使用VGGNet结构和对超参数进行微调,还对各种优化器方法进行了对比试验。最终达到了73.28%的精度,在作者所知的范围内,达到了SOTA。

1、引言

表情识别在人机交互中起着非常重要的角色,而表情识别在因其类内差异大和类间差异小而有着较大挑战性(大概就是同一类之间的变化也很大,不同类之间的变化也很小,这样就不好将不同种类很好的分开了)。

Fer2013是一个包含了困难自然条件下和具有挑战性样本的表情识别数据集,在ICML2013被提出来后就成为了FER的一个基准。Fer2013总共包含35888张图片,分成了7中不同的表情:anger, neutral, disgust, fear, happiness, sadness, and surprise。按Kaggle之前举办的论坛人类在该数据集上的精度在65%~68%之间。人类在该数据集上的精度大概是65.5%。(来自两篇paper的结论,详见论文)

在本work中,我们的目的是使用CNNs提高在FER2013数据集上的精度:

  • 采用了VGGNet
  • 构造一系列实验去探索不同优化器算法和学习率schedulers

通过微调模型和训练超参数实现了SOTA(73.28%的testing精度)–“To our best knowledge, this is the highest single-network accuracy achieved on FER2013 without using any extra training data.”

最后我们构建了几个saliency map去更好理解网络性能和“决策”过程

2、相关工作

3、实验

3.1 Dataset, Preprocessing, and Augmentation

在FER2013数据集上,官方分出了训练集、验证集和测试集,本文中也遵循这样的分割。FER2013总共包含了35888个图片总共7个类别:anger、neutral、disgust、fear、happiness、sadness、surprise。

数据增强。我们在训练时使用了大量的数据增强,包括:

  • 随机缩放图。在原图4848的尺寸上随即缩放增量为原图的±20%范围内,然再后resize到4848
  • 随机水平和垂直方向上平移。平移量为尺寸的±20%范围内。
  • 随即旋转。角度为±10°。
  • ten-cropped:裁剪到40*40,详见
  • 随机擦除:比例为50%,详见
  • 归一化:除以255即可。
# https://github.com/usef-kh/fer/blob/master/data/fer2013.py
mu, st = 0, 255
train_transform = transforms.Compose([
    transforms.RandomResizedCrop(48, scale=(0.8, 1.2)),
    transforms.RandomApply([transforms.RandomAffine(0, translate=(0.2, 0.2))], p=0.5),
    transforms.RandomHorizontalFlip(),
    transforms.RandomApply([transforms.RandomRotation(10)], p=0.5),

    transforms.TenCrop(40),
    transforms.Lambda(lambda crops: torch.stack([transforms.ToTensor()(crop) for crop in crops])),
    transforms.Lambda(lambda tensors: torch.stack([transforms.Normalize(mean=(mu,), std=(st,))(t) for t in tensors])),
    transforms.Lambda(lambda tensors: torch.stack([transforms.RandomErasing(p=0.5)(t) for t in tensors])),
])

(个人感觉归一化是有点问题的,当输入是uint8使进行ToTensor会自动归一化到0~1,如果是非uint8则不自动归一下,无论是否为uint8最后都会转为Tensor。所以按作者可能是想归一化到0~1,但是代码中先ToTensor就归一化到0-1了,再进行Normalize执行:(tensor-mu)/std,就相当于连续除以两次255了。我运行了代码后根据数据增强后的tensor连乘两次255后,范围也的确在0-255左右,证明代码可能和作者想的确实有点不一样)

3.2 Training and Inference

我们所有的实验都训练300epochs和交叉熵损失函数,在接下来我们改变使用不同的优化器和学习率,但是保持其他参数不变。

我们固定momentum=0.9,weight decay=0.0001。在训练时使用了gradient scaline阻止梯度下溢(因为作者使用了AMP混合精度,可能在某些时候float32变成float16时,舍去小数点部分的梯度值造成下溢等情况)。

模型在验证时使用验证精度,测试时使用standard ten-crop averaging。

mu, st = 0, 255
# 验证集和测试集都是用下面这个预处理
test_transform = transforms.Compose([
    # transforms.Scale(52),
    transforms.TenCrop(40),
    transforms.Lambda(lambda crops: torch.stack([transforms.ToTensor()(crop) for crop in crops])),
    transforms.Lambda(lambda tensors: torch.stack([transforms.Normalize(mean=(mu,), std=(st,))(t) for t in tensors])),
])

3.3、VGGNet结构

VGGNet是一个分类卷积神经网络结构,通常用于大尺度图像处理和模式识别。我们的VGGNet变种结构展示在下图中:
在这里插入图片描述
该网络包含了4个卷积段和3个全连接层。每一个卷积段包含2个卷积层块和1个max-pooling层。每个卷积块=conv+ReLU+BN。BN是为了加速学习(训练)过程,减少内部协方差偏移,阻止梯度消失或爆炸。第一个和第二个全连接层后面都跟着ReLU激活函数,第三个全连接层就是分类输出。

3.4、调参

首先,我们要调我们模型结构至一个最好表现(即找到一个表现最好的模型结构)。

所有最开始的实验都是用SGD。使用网格搜索法找到最优的batch sizedropout rate(全连接层之后)。一旦找到最优的结构,我们就开始探索不同优化器学习率的影响。我们进行了一个最终的实验去尝试和微调预训练模型的权重和提高模型的表现。

3.4.1 优化器

我们探索了6中不同算法:SGD、SGD with Nesterov Momentum、Average AGD、Adam、Adam with AMSGrad、Adadelta、Adagrad。

我们试验了两个版本,一个固定学习了=0.001(使用网格搜索得到了),另一个设置初始学习率=0.01,然后若验证集精度5epoch没有突破则衰减0.75倍。

3.4.2 学习率衰减策略

在这里我们实验5种不同的学习率衰减策略:Reduce Learning Rate on Plateau (RLRP)、Cosine Annealing (Cosine)、Cosine Annealing with Warm Restarts (CosineWR)、One Cycle Learning Rate (OneCycleLR)、and Step Learning Rate(StepLR)

初始学习率都设置为0.01,各种策略的其他参数使用网格搜索。其他参数保持不变。

3.4.3 微调

为了进一步提高模型精度,我们使用lr=0.0001重新加载参数(为了确保模型的参数不偏离太远,我们使用的是一个早已训练好的模型)然后再训练50epoch,我们设置这么小的学习率是为了保持小步更新。

本实验使用Cosine Annealing和Cosine Annealing热启动,因为这两个策略都是缓慢来回震荡学习率,防止权重更新太大。第二个策略(Cosine Annealing热启动)意味着它会周期性重启模型权重回到一些好的地方。

第二次实验我们将验证集并入训练集。增大了训练集样本。

通过这两次实验,我们验证了一些事情:第一个实验我们严重了微调的有效性;第二个实验验证了增加数据的好处。

3.5、结论

3.5.1 优化器

在这里插入图片描述
首先作者在他的模型上研究了不同优化器的表现,
1)最好的是SGD Nesterov(在作者模型上),分别是73.2%和73.5%
2)Adam及其AMSGrad比Adadelta和Adagrad更好,因为Adam优化器结合了AdaGrad和RMSProp的动量梯度优势。
3)SGD的所有变种都比其他优化器表现更好

3.5.2 学习率衰减

在这里插入图片描述
学习率衰减策略的实验都在最好优化器(SGD with Nesterov momentum)上进行,结论如下:
1)RLRP表现最好。得到了73.59%的验证机精度和73.06%的测试机精度。据作者所知这超过了先前但网络SOTA的表现
下面所谓的“表现”是比较validation accuracy,因为testing accuracies严格用于report,即不能针对test set调参
2)恒定学习率比一些衰减策略(OneCycleLR和StepLR)更好。对于OneCycleLR可能是它倾向于使用更大的学习率更快的训练,可能不太适合FER2013;
3)Cosine和CosineWR表现相当。
4)StepLR和RLRP:都是较慢衰减学习率的算法。RLRP表现更好因为它监视当前模型的表现,从而决定何时降低学习率(即实时动态根据当前模型来决定何时衰减学习率,而不是固定每隔多久就衰减)

3.5.3 微调

在这里插入图片描述

为了进一步提高我们模型的表现,我们重新加载我们表现最好的模型,再微调训练50epoch。我们使用
cosine annealing schedulers策略(初始学习率很小)。

并且也进行了另一个实验:将验证集并入训练集训练。

看表,首先提供了一个预训练模型Trained VGGNet作为基准,下面分别将Cosine和CosineWR在未合并的数据集和合并的数据集(将验证集并入训练集训练)上微调得到了测试精度。

结论:
1)合并数据集的确有效:在相同策略下,合并数据集的测试精度都比未合并的高
2)未合并数据集上,CosineWR在微调阶段起到了负面影响,精度还下降了。但是Cosine策略有提升0.05%
3)合并数据集上,Cosine还是比CosineWR高,并且也是全场最佳,达到了73.28%

3.5.4 混淆矩阵

在这里插入图片描述
结论:
1)模型分类效果最好的是“happiness”和“surprise”
2)效果最差的是“disgust”和 “anger”,
3)在“disgust”和“fear”之间分类精度低是因为样本少
4)在“fear”和“sadness”之间误分类可能是因为类间相似性(fear类和sadness类的表情实际上不太好分,很相似)

3.5.5 和其他模型的比较

在这里插入图片描述

3.5.6 Saliency map(显著图?)

在这里插入图片描述
一种常用的DNN可视化技术叫saliency map。通过反向传播loss到每个像素值,saliency map能够突出像素对loss值的影响的程度。

通过将saliency map叠加到原图得到了上面的saliency map,结论:
1)首先,我们的CNN能够高效铺货每个表情的最关键区域,捕获到了几乎 每个人的所有脸部特征,比如f中saliency map展示出模型几乎完美地映射到了女人的整个脸。
2)当然我们的CNN也会有效丢弃一些无用区域(与表情识别无关的),比如
a、d、g中的背景,a、c、g的头发,以及e中的手。这些地方都没有足够的信息去描述人的表情。
3)当然也有一些实物,比如b、e和g的角落,都有saliency map的分布,saliency map在无用区域也有分布。我们认为一个模型能更高效识别一个图中的脸部特征并且丢弃所有无用信息,将会在数据集上表现更好

4、结论

本论文在FER2013的单网络方向实现了SOTA效果。我们彻底地调整所有的超参数优化模型。

探索了不同的优化器和学习率衰减策略,并得到了最好的初步测试精度73.06%。

我们在初步模型上使用Cosine Annealing并合并验证集和训练集,进行了额外的训练,进一步提高精度到73.28%。

未来,我们计划探索了不同图像处理技术和不同结构去进一步提高人脸表情识别的表现。

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是一个对称矩阵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值