基于PaddleDetection框架的情绪识别的研究和实现
作者: 胡阳 李若冰 李树源 吕俊晓 王帅昊 李书涵 蔡嘉琪 张虎
摘要: 伴随人工智能技术的发展和应用的普及,表情识别成为运用人工智能理解人类情绪的重要应用方向,也是人机交互的研究热点。利用百度飞桨的PaddleDetection框架,使用公开的fer_2013数据集和WIDER-FACE数据集,分别对BlazeFace模型、ResNet50模型进行研究、训练和优化,将PaddleDetection识别出来的人脸信息输入ResNet50网络进行分类情绪识别,并应用于课堂听课状态的识别,实验结果表明,准确度虽相对较低,但精度尚在可接受范围内,符合预期的效果。
关键词: 深度学习;PaddlePaddle;情绪识别;ResNet50;人脸识别
中图分类号:TP18 文献标识码:A文章编号:1009-3044(2023)18-0001-03
0 引言
人脸表情识别(Facial Expression Recognition, FER)是计算机视觉领域中图像分类的一个最重要的应用场景,相较于目标检测、实例分割、行为识别、轨迹跟踪等难度较大的计算机视觉任务,图像分类只需要让计算机“看出”图片里的物体类别,虽较基础但极为重要。近年来,人脸表情识别引起了学术界和工业界的研究热潮,因为表情是人们在日常交流中重要的表达方式之一,在无法获取说话人语气的情况下,表情就成了理解语言含义不可或缺的一部分。FER是一门交叉学科,涉及计算机视觉、人机交互、生理学、心理学、模式识别等研究领域[1]。在社会的众多领域,例如机器人制造、自动化、人机交互、安全、医疗、驾驶和通信等,表情识别同样具有很高的实用价值。同时,表情识别应用场景丰富,以表情分析为核心技术的学生课堂状态智能分析平台来关注学生的学习生活状态、通过表情分析来协助民警对表情异常和行为可疑的嫌疑人进行筛选锁定等。
深度学习是实现机器学习的核心技术,而做深度学习有较高的门槛,开发效率较低。深度学习框架通过将深度学习算法进行模块化封装,能够实现训练、测试、调优模型的快速搭建。当前流行的深度学习框架主要包括 TensorFlow、PyTorch、Theano、Keras 和PaddlePaddle等。深度学习框架的本质是自动实现建模过程中相对通用的模块,建模者只实现模型的个性化部分,可以节省编写大量底层代码的精力[2]。
项目完成后,对通过机器识别给定的静态图像或动态视频序列中分离出特定的表情状态,从而确定被识别对象的心理情绪,实现计算机对人脸表情的理解与识别,可从根本上改变人与计算机的关系。使计算机可以更好地为人类服务,从而达到更好的人机交互。
表情识别技术是人们探索和理解智能的有效途径。
1 项目研究方法
本项目采用的研究方法如图1所示。
第一步:制作两个模型的数据集,首先下载所用的数据集图像,原始的图像数据会存在一些脏数据,需要做好数据处理工作,将图像数据整理成规范统一的形式。
第二步:数据增强处理,深度学习要求样本的数量要充足,样本数量越多,训练出来的模型效果越好,模型的泛化能力越强,所以增加训练的数据量,提高模型的泛化能力,增加噪声数据,提升模型的鲁棒性。
第三步:划分数据集,对于大数据量的数据集,将80%的数据划为训练集、20%的数据划为验证集。使用fer2013数据集进行ResNet50分类模型训练,训练ResNet50 分类模型来获得表情分析权重,使用WIDER-FACE数据集进行BlazeFace模型训练,训练BlazeFace模型来获得人脸识别权重[3]。
首先,使用PaddleDetection套件中的目标检测模型识别出人脸区域,再将此人脸区域输入基于ResNet50的表情判别网络以完成情感分类,最终实现FER任务[4]。
2 Resnet 人脸识别模型
项目使用Resnet50网路进行表情识别,Resnet网络是在2015年由来自Microsoft Research 的4位学者提出的卷积神经网络,斩获当年ImageNet竞赛中分类任务第一名,目标检测第一名[5]。获得COCO数据集中目标检测第一名,图像分割第一名。而Resnet50就是指深度为50的Resnet网络,是Resnet网络中最主流的深度选择之一。
Resnet 网络使用了一种连接方式叫作“shortcutconnection”,顾名思义,shortcut就是“抄近道”的意思。
它对每层的输入做一个reference(X) , 学习形成残差函数,而不是学习一些没有reference(X) 的函数。这种残差函数更容易优化,能使网络层数大大加深。
ResNet50有两个基本块,分别名为Conv Block和Identity Block,其中Conv Block输入和输出的维度是不一样的,所以不能连续串联,它的作用是改变网络的维度;Identity Block输入维度和输出维度相同,可以串联,用于加深网络。
3 人脸识别的实现
3.1 PaddleDetection 深度学习框架
本项目在人脸识别方面使用的是飞桨PaddleP⁃ddle深度学习框架。PaddleDetection是百度飞桨目标检测开发套件,实现了端到端地完成从训练到部署的全流程目标检测应用。基于百度飞桨的高性能内核,使模型训练速度及显存占用有明显提高,加快了整个项目的实现。本文应用PaddleDetection套件快速开发和部署人脸表情情绪分类模型,有利于得到准确的情绪分析结果。
3.2 模型选择
BlazeFace 模型用来训练识别图片中的人脸,BlazeFace模型是训练和评估在WIDER-FACE数据集上的模型,也是一个非常轻量级的人脸检测器。
WIDER FACE数据集是人脸检测的一个benchmark数据集,包含32 203个图像,以及393 703个标注人脸。
每一个数据子集都包含3个级别的检测难度:Easy、Medium、Hard。这些人脸图像在尺度、姿态、光照、表情、遮挡方面都有很大的变化范围,以便训练效果更加真实准确。
项目选择了PaddleDetection 内置的BlazeFace-FPN-SSH改进模型,增加FPN和SSH的neck结构,由原来的relu激活函数改进为hard_swish,改进模型有助于提高系统识别精度和性能。
3.3 数据增强方法
尺度变换:根据随机选择的人脸高和宽,获取到v=sqrt{width * height},然后再判断v 的值范围,其中v 值位于缩放区间[16,32,64,128] ,假设v=45,则选定32图像随机剪切:根据随机的比率aspect_ratio =math.sqrt(np.random.uniform(*ratio)) ,通过获取的比率随机对原图像进行选择剪切,获取到目标区域tar⁃get_area = img.shape[1] * img.shape[0] * np.random.uni⁃form(scale_min, scale_max) target_size = math. sqrt(tar⁃get_area)后,将原来的图片进行随机裁剪。
随机旋转:根据选择的人脸高和宽,angle = np.random.randint(-14, 15),将图片随机旋转-14到15之间的某一个角度获取图像的尺寸,旋转中心后设置选择矩阵,最后重新计算图像旋转后的新边界。loss可视化效果如图2所示。
3.4 模型训练
BlazeFace 和FaceBoxes 默认训练是以每卡batch_size=8 在4 卡GPU 上进行训练(总batch_size=32),并且训练320 000轮,但因为笔者使用的GPU数量为1,所以将学习率调制0.000 25,变化节点范围在[480 000, 640 000]。训练过程loss变化趋势loss可视化如图3所示。
在深度学习神经网络模型中,通常使用标准的随机梯度下降算法更新参数,学习率代表参数更新幅度的大小,即步长。当学习率最优时,模型的有效容量最大,最终能达到的效果最好。学习率和深度学习任务类型有关,合适的学习率往往需要大量的实验和调参经验。探索学习率最优值时需要注意如下两点:学习率不是越小越好。学习率越小,损失函数的变化速度越慢,意味着需要花费更长的时间进行收敛。学习率也不是越大越好。只根据总样本集中的一个批次计算梯度,抽样误差会导致计算出的梯度不是全局最优的方向,且存在波动。在接近最优解时,过大的学习率会导致参数在最优解附近震荡,损失难以收敛。
3.5 模型评估
对已经训练出来的权重模型在WIDER-FACE数据集上进行评估,ppdet将对数据集进行预处理,通过设置multi_scale=True 进行多尺度评估,待评估完成后,再生成每个数据txt格式的测试结果。保存在txt的评估结果信息记录评估结果信息如图4所示。
其中,第一行是文件夹文件名;第二行是图中人脸的数量;再往下是人脸信息的参数。x1, y1 代表识别的人脸框的位置(检测算法一般都要画个框框把人脸圈出来);w,h 即为识别的人脸框的宽度和高度。最后一项为记录识别的人脸得分,范围[0,1.0]之间。
WIDER-FACE 数据集中40%的数据为训练集(Training) ,10% 的数据为验证集(Valida⁃tion) ,50%的数据为测试集(Test⁃ing) 。每个集合中的数据根据人脸检测的难易程度分为“Easy”“Medium”“Hard”。最后Blaze⁃Face- FPN-SSH 改进模型在Easy/Medium/Hard Set 表现分别为0.907、0.883、0.793,如图5所示。
3.6 情绪识别Fer2013 数据集由生气(an⁃gry)、厌恶(disgust)、恐惧(fear)、开心(happy)、难过(sad)、惊讶(surprise)和中性(neutral)七个类别组成。
下面以识别出第一个人脸,输入ResNet50模型中返回的结果为例:
[152.04286193847656,140.7641143798828,225.39659118652344,236.35003662109375]
Tensor(shape=[1, 7], dtype=float32,place=CPUPlace, stop_gradient=False,
[[2.31061411,-7.43143892,-2.16615653,1.60756242,-4.08799791,5.83180237,0.78366065]])
从识别的结果来看,返回Tensor包括七个表情对应的概率值,然后lab = np.argsort(results.numpy()),取概率最大的标签作为预测输出,标签lab=0对应SAD表情、标签lab=1对应DISGUST表情、标签lab=2对应HAPPY表情、标签lab=3对应FEAR表情、标签lab=4对应SUPERISE表情、标签lab=5对应NATUREAL表情、标签lab=6对应ANGRY表情。最后单个人脸数据源识别效果如图6所示。
结合标注
通过标注代码如下:
draw = ImageDraw.Draw(image)
draw. line([(xmin, ymin), (xmin, ymax), (xmax,ymax), (xmax, ymin),(xmin, ymin)],width=2,fill=color)