首页 花卉园艺 基于深度学习的人脸表情识别研究

基于深度学习的人脸表情识别研究

  随着计算机算力提升,人工智能技术迅速发展,人类对更智能更真实的人机交互的需求日益强烈。像许多科幻作品里的具有理解和表达情感的能力的机器人和计算机如果出现,也许将从根本上改变人与计算机之间的关系。表情识别是情感理解的基础,人们探索智能的道路上离不开表情识别技术的研究。

  本论文研究了人脸识别技术的历史进程,从人类对于表情的研究开始,沿着时间顺序讲述了人脸表情识别技术的发展过程,发展现状以及发展的方向,现代自动表情识别技术主要经历了两个阶段,分别是基于传统手段的自动表情识别技术和基于深度学习的自动表情识别技术。论文在文章的主体部分分别对这个阶段内的一些研究成果和结论,以及一些有特征性的方法进行了介绍。对于传统手段的部分,论文以理论为主,旨在使读者理解到一些方法的思想路线,以及对后续研究的影响。而在深度学习方向上,除却理论相关的介绍,论文重点记录了笔者基于理论进行的多次实验过程,旨在通过实战获得对深度学习神经网络模型的理解。

  面部表情的研究始于19世纪,著名生物学家达尔文在其论著《人类和动物的表情(The Expression of the Emotions in Animals and Man,1872)》中就阐述了人类与动物的面部表情之间的联系和区别。

  1971年,埃克曼(Ekman)和弗里森(Friesen)经过最早提出了人类有六类主要情感,即高兴(happiness)、悲伤(sadness)、惊讶(surprise)、厌恶(disgust)、恐惧(fear)和愤怒(anger)。这六类情感均有对应的表情来反映人类的一类独特的心理活动,由此产生了六类基本表情。他们还系统地建立了人脸面部表情图像库,用图表细致地说明了每一种表情所对应的面部器官的变化。

  然后在1972年,埃克曼和弗里森让五个不同国家的公民观察不同的表情图像并判断其属于什么情感,结果发现不同民族对表情的判断大同小异(见下表1.1)。但有一个问题是表上所列国家均来自文明程度较高的地区,研究者们又选取了新几内亚的土著民族丹尼族和赫尔族进行测试以验证居住在文明程度较低地区的人们能否得出同样的结果,结果是他们对这六种面部表情的判断也一致。更有趣的是,把赫尔族土著民的面部表情用影像记录后,带回美国让大学生来通过影像判断其情绪的时候结果也一致。由此他们得出了一个结论:全人类的表情具有很高的一致性,无关民族与社会发展的水平。

  1992年,D.Matsumot在文章《More evidence for the universality of a contempt expression》中指出鄙视可能也属于人类的一种基本表情。[[[]D.Matsumoto,“More evidence for the universality of a contempt expression,”Motivation and Emotion,vol.16,no.4,pp.363–368,1992.]]

  表1.1各国人对表情判断一致的百分数(单位:%)[[[]Source:http://old.pep.com.cn/xgjy/xlyj/xlshuku/shuku13/shuku17/201008/t20100827_815292.htm.2003.10.27]]

  表情愉快厌恶惊讶悲伤愤怒恐惧

  美国(92人)97 92 95 84 67 85

  巴西(40人)95 97 87 59 90 67

  智利(119人)95 92 93 88 94 68

  阿根廷(168人)98 92 95 78 90 54

  日本(29人)100 90 100 62 90 66

  (2)人脸表情识别技术的研究历史

  二十世纪七十年代,国际著名心理学家Paul Ekman和其研究伙伴W.V.Friesen创建了面部行为编码系统。在对人脸面部表情进行了大量观察和调查后,埃克曼和弗里森描绘出了不同表情与面部肌肉的对应关系,终于于1976年创建了“面部行为编码系统”(FACS=Facial Action Coding System)。这个系统依照解剖学建立,面部被他们划分为若干相互独立同时又相互联系的运动单元(AU)。他们分析了这些运动单元的运动特征及其所控制的主要区域,给出了大量与之相关的表情的照片说明。FACS第一次对人类的表情进行了较为系统的分类,直到现在都是面部表情的肌肉运动的权威参照标准。

  同样是在七十年代期间,Harmon等人找到了一种能增加人工面部识别系统准确性的方法。为了进行面部识别,他们手动归纳了21种主观的面部标记(见图1.1),按照一定顺序可以顺利地找出面部标记。这些标记包含了诸如嘴唇厚度,头发颜色等特征。在Bledsoe提出的方法中,实际的生物特征必须完全依靠人工进行手动计算。

  图1.1面部的21个特征[[[]Source:techguruit.com.2020.4.18]]

  1988年,Sirovich和kirby开始使用线性代数的知识来处理面部识别相关的问题。他们提出的方法被称作特征脸法(Eigenface approach)。这种方法首先致力于寻找面部图像的低维度表示。在这个过程中,他们找到了一种可以在一个面部图像集中进行特征分析并抽离出一组统计特征的方法。1991年,Turk和Pentland通过解决如何在图像中发现人脸的问题发展了特征脸法。这导致了自动面部识别技术的首次出现。

  DARPA推出FERET项目大大促进了相关技术的研究。美国的国防高级研究计划局(DARPA=Defense Advanced Research Projects Agency)和美国国家标准技术研究院(National Institute of Standards and Technology)在93年推出了一个名为人脸识别技术(FERET=Face Recongnition Technology)的项目,旨在鼓励商业化的人脸识别技术的市场。该项目的工作中包含创建面部图像测试集,这个测试集曾于2003年进行过一次更新使其包含24位通道的彩色图像。测试集里包含了856人的共2413张面部静态图像。他们希望一个大型的测试图像测试集有助于相关技术的创新,促进了人脸面部识别技术的发展。[[[]Jesse Davis West(2017),A brief history of face recognition.

  https://www.facefirst.com/blog/brief-history-of-face-recognition-software/]]

  由此开始,对人脸识别技术的研究进入了一轮高潮。利用计算机进行自动人脸识别的相关是50年前才开始发展的,并在九十年代成为了科研热点。仅1990年到1998年之间,期刊《工程索引》(EI)中可检索到的相关文献就多达数千篇[[[]张翠平,苏光大.人脸识别技术综述[J].中国图象图形学报,2000(11):7-16.]]。现在人脸识别技术[人脸表情识别技术属于广义上的人脸识别技术]的大多数方法的基本模型和方法都是这个阶段提出的。

  (3)人脸表情识别技术的研究意义

  随着计算机算力提升,人工智能技术迅速发展,人类对更智能更真实的人机交互的需求日益强烈。像许多科幻作品里的具有理解和表达情感的能力的机器人和计算机如果出现,也许将从根本上改变人与计算机之间的关系。表情识别是情感理解的基础,人们探索智能的道路上离不开表情识别技术的研究。

  人类的面部表情可以说是世界通用的一种语言,正如上文所提到的,在不同文化不同民族不同地区不同知识水平的人类之间,表情基本为通用的。表情是不同人之间交流信息的一种良好载体,FER技术的相关研究在宏观方向上即是对人类信息交流方法的研究,对全面信息化社会的发展方向有十分重要的意义。

  具体到细分领域,人脸表情识别在心理学、机器人、智能控制等领域有很大的应用价值,对动画合成以及游戏等娱乐产业也有良好的运用前景。

  1.2人脸表情识别技术的研究现状和主要发展方向

  (1)基于深度学习的人脸表情识别技术成为主要研究方法

  根据摩尔定律,计算机的算力在21世纪的前十年进步神速,随着算力的提高,利用仿生学发展而来的人工神经网络技术被纳入实际应用,2006年可以说是现代深度学习神经网络模型的发展元年,在这一年杰弗里·辛顿以及他的学生鲁斯兰·萨拉赫丁诺夫首次提出了深度学习(deep leaning)的概念。他们在世界顶级学术期刊《Science》发表了一篇文章,指出可以通过进行无监督的前向传播算法逐层训练参数后使用有监督的反向传播算法对参数调优以解决梯度消失问题。深度学习理论立即在学术圈引起了巨大的反响,诸多研究者开始对其进行实验研究。[[[]Source:http://tensornews.cn/develop_deep_learning/.2020.4.18]]2012年Hinton课题组成功使用构建出来的CNN网络AlexNet在ImageNet图像识别比赛中碾压第二名的SVM方法取得冠军,而2016年由谷歌(Google)旗下DeepMind公司开发的AlphaGo(基于深度学习)与围棋世界冠军、职业九段棋手李世石进行了围棋人机大战,最终以4比1的总比分获胜。这个事件则彻底引爆了公众对深度学习网络的关注(在这之前围棋被公认为最难被计算机征服的棋类),世界迎来深度学习浪潮。

  (2)基于复杂的野外环境的人脸表情识别技术成为了新的挑战

  目前该领域内最尖端的攻坚点在于如何在野外环境下完成人脸表情识别的任务。因为野外环境拥有非常复杂的变化,获取图像时的光照变化,遮挡,非额头姿势等外部因素都会导致利用设计好的数据集训练出来的模型失去作用。

  对于现今的深度学习技术而言,依靠人工来对图像数据集进行构筑效率过于低下且容易出现主观的偏差,研究如何在野外环境中进行数据提取从而进行人脸表情识别数据集的构筑也是可行的方向之一。

  1.3本文的主要研究内容和章节安排

  通过了解传统的自动表情识别技术的研究历史和部分有代表性的研究方法,利用tensorflow深度学习框架,对不同的网络结构及其参数进行测试,从而获得一个较为优秀的可以对人脸表情进行识别的网络模型。

  本论文共五章,阐述了人类对表情的相关研究的历史进程,详细介绍了自动表情识别技术的理论和技术,以及基于深度学习的神经网络人脸表情识别技术,并通过具体的实验获得了多个模型,最后对全文进行总结。

  第一章绪论描述了人类对于表情的研究和表情研究的历史意义,简要介绍了自动表情识别技术的发展历史进程,以及本论文的研究内容和章节安排。

  第二章则主要从理论和技术角度介绍了表情识别技术的内容,包含其学科技术分类以及常用的研究方法,从工序流程的角度分解了表情识别技术需要研究的子问题。

  第三章则从深度学习神经网络的基本知识开始介绍,剖析了后续实验使用的网络模型架构,使读者可以较为直观的理解网络结构的组织方法和功能。

  第四章为具体的实验过程,记录了笔者实验的全过程和训练模型的参数,并在此基础上给出一些猜想和结论。

  第五章则总结了实验的不足,给出了后续研究的方向。

  2.表情识别相关技术和基本理论

  2.1表情识别技术概述

  自动表情识别技术(AFER=Auto Facial Expression Recognition)是指从给定的动态视频序列或者静态图像中分捕捉人脸,从人脸上分离出情感状态,确定对象心理情绪,旨在实现计算机对人脸表情的理解的一种技术,这是计算机人工智能领域中计算机视觉(CV)下的一个细分分支。其隶属于广义上的人脸识别技术分类(早期并未对表情识别技术相关研究和人脸识别技术的相关研究进行细分),但与狭义上的人脸识别技术需要做区分。

  计算机视觉技术的最终目的是让计算机实现图像理解,一般来讲计算机视觉技术都包含以下基本流程:

  图像处理模式识别图像理解

  对应到自动表情识别上,AFER技术一般包含如下流程:

  人脸图像的获取与预处理表情特征提取表情分类

  2.2图像的预处理与人脸检测

  人脸检测是大部分人脸识别任务中的传统步骤,其主要目的是检测图片中面部存在的区域,并去除背景和非面部区域。其基本思想是用知识或者统计方法对人脸抽象后建立模型后将图像区域与模型进行匹配,从而找到人脸可能存在的区域,因为一张图像里可能有多个人脸,这个区域也可能存在多个。这一部分叫做人脸检测(face detection)。

  人脸检测算法作为广义上一切人脸识别算法(Face Recognition)的基础,目前研究已经相对成熟,主流的计算机视觉库(如opencv,dlib)均已集成了自己的成熟的Face detection函数。传统手段中,V&J面部检测器是用于面部对齐的最为经典且被广泛采用的一种实现手段,该方法功能十分强大,计算也十分便捷,主要用于检测近似正面的面部。而对于基于深度学习的方法里,目前一个优秀且开源人脸检测深度学习模型是MTCNN,详见这篇论文[[[]Kaipeng Zhang,“Joint Face Detection and Alignment using Multi-task Cascaded Convolutional Networks,”IEEE Signal Processing Letters(SPL),vol.23,no.10,pp.1499-1503,2016.]]。

  对一张包含表情(面部)的图像来说,往往会有不同的背景,光照分布,面部角度或者头部姿势。在利用深度神经网络学习有价值的面部特征之前,我们还有必要进行一些预处理,预处理一般包含面部对齐和面部标准化。

  面部对齐(face alignment),其作用是将人类面部的姿态和角度按照特征点进行对齐,从而强化面部数据的特征。其主要有基于最优的人脸对齐算法,基于级联回归的人脸对齐算法和基于深度学习的人脸对齐算法。

  面部标准化主要包括光照标准化和姿态标准化两个部分,分别解决图片里因为光照变化或者头部姿势不同等外部因素导致的面部特征数据变化引起的误差。目前光照标准化主要有三种技术,分别是基于各向同性扩散的标准化方法(isotropic diffusion-based normalization),基于离散余弦变换的标准化方法(DCT-based normalization)和高斯差分方法(DoG)。有研究[[[]D.A.Pitaloka,A.Wulandari,T.Basaruddin,and D.Y.Liliana,“Enhancing cnn with preprocessing stage in automatic emotion recognition,”Procedia Computer Science,vol.116,pp.523–529,2017.]][[[]Z.Yu and C.Zhang,“Image based static facial expression recognition with multiple deep network learning,”in Proceedings of the 2015 ACM on International Conference on Multimodal Interaction.ACM,2015,pp.435–442.]][[[]S.Ebrahimi Kahou,V.Michalski,K.Konda,R.Memisevic,and C.Pal,“Recurrent neural networks for emotion recognition in video,”in Proceedings of the 2015 ACM on International Conference on Multimodal Interaction.ACM,2015,pp.467–474.]][[[]S.A.Bargal,E.Barsoum,C.C.Ferrer,and C.Zhang,“Emotion recognition in the wild from videos using images,”in Proceedings of the 18th ACM International Conference on Multimodal Interaction.ACM,2016,pp.433–436.]]表明方向梯度直方图(HOG)结合光照标准化技巧可以得到提升人脸识别的准确率。而姿态标准化方面最为流行的是Hassner等人提出的方法,这个方法具体来说就是在定位了面部标记(facial landmarks)后用一个事先建立的通用3D纹理参考模型与之匹配,进而评估有效的面部成分,然后反投影到参考坐标系来合成正面面部。

  2.2人脸特征提取

  根据图像的性质不同表情特征提取主要被划分为基于静态图像的特征提取和动态图像序列特征提取两类。静态图像主要提取面部器官的形变几何暂态特征来表示表情特征,对形变特征提取进行必须依赖中立表情或者模型,以中立表情或者模型作为基础来统计形变。而对于动态图像序列,则在提取每一帧的图像形变特征基础上还需要提取连续序列的运动特征,这个提取过程依赖于产生表情导致的面部变化。

  2.3表情分类方法

  在提取了人脸表情特征以后,FER技术的最终步骤都是要对给定的脸部进行分类,将其归为基本表情之一。表情分类方法是基于表情特征提取后的数据就行分类,比较常见的分类方法有四种:

  (1)基于模板的匹配方法

  这种方法是将从图像中提取到的特征数据用预先设计好的一套算法转化成一个2D的或者3D的面部模型,然后与提前准备好的各种表情的模板进行匹配测试,对匹配上的表情进行输出。

  (2)基于神经网络的方法

  此方法是利用早期人工神经网络(ANN=Artificial Neural Network)进行分类的方法。ANN是由大量神经元结点互相连接构成的自适应非线性动态系统,早期因为计算机算力不足,这种方法并不具有很高的应用空间。神经网络分类器主要有:多层感知器、BP网、RBF网等。

  (3)基于概率模型的方法

  主要指贝叶斯分类算法,是一类基于贝叶斯理论开发的算法,早期主要使用朴素贝叶斯算法,后来有人提出了数增强型朴素贝叶斯方法(TAN)。因为贝叶斯理论成立的前提是各属性相对独立,对部分数据集可能需要先进行独立性证明。

  (4)基于支持向量机的方法

  支持向量机(SVM=Support Vector Machine)是一种按照监督学习方式对数据进行二元分类的广义线性分类器,其决策边界是对学习样本求解最大的边距超平面(maximum-margin hyperplane),在深度学习神经网络成为研究主流方向以前在表情识别领域可以达到较为优秀的成绩。[[[]李航.统计学习方法.北京:清华大学出版社,2012:第七章,pp.95-135]]

  2.4传统表情识别技术的技术路线

  早期的人脸识别研究领域主要有两个大的方向:

  一是几何特征法。这是一种提取人脸部图像几何特征的方法,同时解决人脸部件标准化问题。需要提取的面部集合特征一般用点间距离和比率表示,利用人脸的一些特征点和器官,如眼角、嘴角、鼻尖等构成一个二维拓扑结构。

  二是模板匹配法。为了实现识别功能,利用了计算模板和图像灰度的自相关性。现今使用的面部动作捕捉的常用算法都需要事先匹配中立表情来提升捕捉和识别的精确度,或多或少都利用了模板匹配方法的一些成果。

  当时的研究方向也主要分为二种:

  其一是基于整体的分析方法,这种方法主要考虑模式的整体属性。具有代表性的方法包括上文提到的特征脸法、等密度线分析匹配方法、弹性图匹配(elastic graph matching)方法、奇异值(SVD)分解法、隐藏马尔康夫模型(Hidden Markov Model)方法等。

  其二是基于部件特征的分析方法,这种方法的思路是将人脸基准点的相对距离和其它描述人脸脸部特征的形状参数一起构成识别特征向量。这些特征向量不仅保留了人脸各器官之间的拓扑关系,而且也保留了各参数对应的有效信息。

  是否需要基于整个图像进行分析呢?有文献[[[]Berto R,Poggio T.Face recognition,Feature versus templates.IEEE Trans.on PAM I,1993,15(10):1042~1052.]]认为基于部件的分析手段要劣于基于整个人脸的分析手段,因为后者留存的信息更多。对基于整个图像的识别图像的光照,角度以及人脸尺寸都会对结果产生影响,将这些干扰去除的方法也就成为了一个新的研究方向。至于基于部件分析的人脸识别方法有一个难点是如何建立一个好的模型,这个模型需要能良好地表达用于后续分析的部件。自然,将上述两种方法结合起来也成为了一个选择。香港理工大学的KinMan Lam就提出了一种结合二者的方法。国外学者Andreas Lanitis提出的可变形模型解释也是这种思路。

  在由Ciprian A等人共同发表的表情识别综述《Survey on RGB,3D,Thermal,and Multimodal Approaches for Facial Expression Recognition:History,Trends,and Affect-related Applications》一文中,为我们整理了传统手段的AFER下几乎所有的技术路线,见下页图2.4。

  图2.4传统AFER技术的技术路线一览,红色表示RGB图相关,绿色指3D相关,紫色是热量图检测[[[]Ciprian A.Corneanu,Marc Oliu,Jeffrey F.Cohn,and Sergio Escalera.,“Survey on RGB,3D,Thermal,and Multimodal Approaches for Facial Expression”Recognition:History,Trends,and Affect-related Applications]]

  2.5本章小结

  自动表情识别技术发展到现今,已经成为人工智能领域下的计算机视觉技术的分支。在这一章里我们了解了AFER技术的技术流程和早期的研究方向,在工序上了解到了如何把FER工作进行问题分解,以及前人是如何解决对应子问题的。了解AFER技术的研究方法和思路,有助于我们在宏观上了解人脸表情识别任务的流程和问题解决的方法。

  3基于深度学习的表情识别技术

  3.1深度学习

  人工神经网络(ANN=Artificial Neural Network)是自20世纪80年代兴起的研究热点。ANN从信息处理角度对生物神经进行了抽象从而了建立对应的数学模型。神经元们按不同的连接方式组成不同的网络。在工程与学术界常简称为神经网络或类神经网络。

  神经网络是一种运算模型,由大量的节点(或称神经元)之间相互联接构成。每个节点包含一种特定的输出函数,一般称其为激励函数(activation function)。每两个节点间的连接都代表一个对于通过该连接信号的加权值,称之为权重,这相当于人工神经网络的记忆。网络的输出则依网络的连接方式,权重值和激励函数的不同而不同。

  3.1.1前向传播和后向传播

  梯度下降(Gradient Descent)法是迭代法的一种,一般用于求解最小二乘问题。在机器学习算法的模型中,最常用的方法之一就是梯度下降法,用于逐步迭代得到最小化的损失函数(loss funtion)从而得到最优的模型参数值。

  一般所说的人工神经网络的“学习”行为,其本质是首先投入输入数据经过各个神经元结点计算得出一个代价函数(loss funtion),再根据这个得出的损失函数反向调整网络中各个神经元的参数。上面的这两个过程分别被称为前向传播(Forward propagation)和反向传播(Back Propagation)。

  (1)前向传播

  对于一个本层的结点w,上一层结点有若干结点会与之相连。结点w的输出值就是对通过上一层的若干结点及其对应的权值进行加权和运算,然后给这个和加上一个偏置项,最后通过一个即激励函数得到的结果。前向传播就是通过不断的一层层的进行这种运算得到输出层的结果这一过程。

  在前向传播中,不管网络结构有多深,其过程都可以用公式3.1.1表示:

  (公式3.1.1)

  其中,下标代表层数,乘号表示卷积运算,b表示偏置项bias,表示激励函数。

  (2)反向传播

  反向传播是多层神经网络训练中最为重要的部分,也是神经网络“智能”的核心。其本质是进行一个拟合行为,是复合函数的链式法则,其建立于梯度下降法基础上。反向传播中最重要的数学计算行为就是求偏导行为,构成目标函数对权值向量的梯度,进而修改各神经元的权值。进而达到降低代价函数的目的。

  3.1.2激励函数

  对神经元结点来说,它需要从上一层的神经元接受一个输入值,然后将值传递至下一层,神经元内的这个值转换行为是一个函数关系,这个函数被称作激励函数(activation function,又称激活函数)。

  在无预设激励函数(等价于f(x)=x)的情况下,每个节点的输出都是上层输入的线性函数,可以视为一个感知机(perceptron),难以通过自动参数调优来接近答案。所以在神经网络领域,一般采用非线性的函数关系作为激励函数。

  (1)Sigmoid函数

  早期研究神经网络时最常用的非线性激励函数,其表达式见公式3.1.2.a。

  (公式3.1.2.a)

  Sigmoid的几何图像如下:

  图3.1.2(a)sigmoid函数几何图像12

  特点:将输入的任意实数值标准化为0和1之间的一个实数,实数越大则越接近1,越小则越接近0。Sigmoid函数有三个主要缺点:

  缺点1:在反向传播时发生梯度消失(gradient vanishing)的概率较大。

  缺点2:Sigmoid函数的输出不是0均值输出(zero-connected)。

  缺点3:其解析式里有幂运算,求解耗时很高。

  Sigmoid函数在近几年的研究里使用人数越来越少,如想从数学层面了解,一些分析可见这篇文章http://neuralnetworksanddeeplearning.com/chap5.html[[[]Source:https://blog.csdn.net/tyhj_sf/article/details/79932893.2020.4.18]]。

  (2)Tanh函数

  Tanh函数的解析式见公式3.1.2.b

  (公式3.1.2.b)

  tanh函数及其导数的几何图像如下图:

  图3.1.2(b)tanh函数及其导函数的图[12]

  tanh读作Hyperbolic Tangent,这个函数虽然解决了Sigmoid函数的不是0均值输出的问题,但没有解决梯度消失问题和幂运算问题。

  (3)Relu函数

  Relu函数的解析式见公式3.1.2.c

  (公式3.1.2.c)

  Relu函数及其导数的图像如下图所示:

  图3.1.2(c)Relu函数及其导函数几何图像[12]

  ReLU函数本质是一个类似于max的取最大值函数。ReLU函数有以下几大优点:

  1)在函数的正区间,不存在梯度消失的问题。

  2)计算速度非常快,只需要判断输入是否大于0即可。

  3)在收敛速度上,远优于上文提到的sigmoid函数和tanh函数。

  ReLU函数也有几个值得关注的不足:

  1)ReLU函数在X=0时不可导,这时候我们通过取其子梯度处理。

  2)ReLU函数的输出同样不是0均值的。

  3)ReLU死亡问题,这是指某些神经元永远不会被激活,导致其内的参数无法被更新。这种情况产生可能有两个原因:比较少见的原因是是参数初始化时出现错误(或者说运气不好);常见的情况是设置了太高的学习率,因此在训练过程中内部参数更新的幅度过大,使网络进入了这种状态。ReLU死亡问题可以通过使用adagrad等自动调节学习率的算法解决。

  尽管存在这三个问题,ReLU仍是神经网络里最常见的激励函数。

  (4)MaxOut

  Maxout其实不是一个函数而是神经网络中的一层。就像池化层、卷积层一样,我们可以把maxout看成是网络的函数激活层,我们假设网络某一层的输入特征向量为:V=(v1,v2,……vn),也就是我们输入是n个神经元。Maxout隐藏层每个神经元的计算公式如下:

  (公式3.1.2.d)

  这个就是maxout隐藏层神经元i的计算公式。k是maxout层的超参,由人工设定大小。公式中Z的计算公式为:

  (公式3.1.2.e)

  权重W是一个形式为(d,m,n)三维矩阵,B是一个形式为(m,n)的二维矩阵,这两个矩阵网络中需要学习的部分。当超参k=1的时候,网络就退化为原始的MLP网络。传统的MLP算法在第i层到第i+1层,只包含一组参数,而maxout同时训练k组的w、b参数,然后选择激活值Z最大的一组作为下一层神经元的激活值,这个max(Z)函数即充当了激励函数。[12]

  3.1.2学习率和优化器

  神经网络里的学习率,是反向传播求偏导过程中的一个参数,一般为正实数,其值越高,网络一次迭代对权值的更新幅度越大。

  神经网络中的优化器(Optimizer)基本上都是基于梯度下降法的基础上设立的,是在训练过程中提高模型运行效率的方法模块。常见的优化器被分为两种,分别是以SGD为代表的学习率不会随梯度影响的固定学习率优化器,和执行过程中学习率会随梯度影响进行自适应调整的优化器。

  (1)学习率不变——随机梯度下降法SGD

  如果把标准梯度下降法理解为“在视距内寻找坡度最陡峭的路径下山”,每一步都会走向最陡峭的方向,然后停下来计算下一步的梯度。SGD则像是“盲人”下山,每一步都随机选择一个梯度方向,在走完后并不立刻计算周边的最优梯度,其优点是相比于GD的计算量被大大降低,只不过整条路径会显得弯弯曲曲,总体的数学期望还是等于GD方法的。

  1)带动量(Momentum)的SGD

  动量(Momentum)优化SGD的做法是引入了一个记录历史梯度数据的动量。因为像是一个带有惯性的小球滚下山坡,加快了下降的速度,基于这种思想做出来的优化器就是动量优化器。

  2)带牛顿加速梯度(NAG,Nesterov accelerated gradient)的SGD

  NAG是Momentum算法的变种,动量算法里的小球会坚定地获得下坡的加速度,从而导致速度过快并会冲出局部最优解,而NAG则是在此基础上提前预估小球的下一个大概位置,并根据其对应位置的梯度调整参数。

  (2)学习率自适应优化器

  1)AdaGrad算法:

  一种通用的自适应算法,做法是使用历史梯度均值和的平方根对每个参数进行反比缩放。梯度越大的参数就会有越大的学习率下降速率,而梯度较小的参数在学习率上的下降速率就会相对较慢。Adagrad在数据稀疏或者分布不平衡的数据集中表现较好。

  Adagrad的虽然可以自动调节学习率,但有一个缺点是随着迭代次数的增多学习率会变的越来越小直至趋近于0。[[[]Source:https://blog.csdn.net/weixin_40170902/java/article/details/80092628.2020.4.20]]

  2)RMSProp算法:

  RMSProp是在AdaGrad的基础上,将梯度变化为求指数加权的差值平均值,使其在非凸数据下的效果更优秀。是学习率自适应常用优化器之一。

  3)AdaDelta算法:

  AdaDelta结合了上述两种算法的优点,一个较为突出的特点是不需要设置默认的全局学习率。AdaDelta在模型训练的初期和中期表现十分突出,加速效果尤为显著,但在训练的后期会经常在局部最小值附近来回抖动。

  4)Adam优化器:

  目前最为常用的优化器,结合学习了上述各种算法的优点,被认为对超参的选择相当鲁棒,但其默认的全局学习率会需要根据经验从默认进行调整。[13]

  3.2本文所用的深度学习模型

  卷积神经网络(CNN=Convolutional Neural Networks)是一类包含卷积计算且具有深度结构的前馈神经网络,是深度学习的代表算法之一[[[]Goodfellow,I.,Bengio,Y.,Courville,A..Deep learning(Vol.1).Cambridge:MIT press,2016:326-366.]][[[]Gu,J.,Wang,Z.,Kuen,J.,Ma,L.,Shahroudy,A.,Shuai,B.,Liu,T.,Wang,X.,Wang,L.,Wang,G.and Cai,J.,2015.Recent advances in convolutional neural networks.arXiv preprint arXiv:1512.07108.]]。表征学习(representation learning)是卷积神经网络的主要能力。CNN可以按照阶层结构对输入的信息进行平移不变分类,因此有人称其为“平移不变人工神经网络”(SIANN=Shift-Invariant Artificial Neural Networks)”。[[[]Zhang,W.,1988.Shift-invariant pattern recognition neural network and its optical architecture.In Proceedings of annual conference of the Japan Society of Applied Physics.]]

  卷积神经网络是仿生学的产物,其主要仿造了生物的视知觉(visual perception)机制。卷积神经网络即可以进行监督学习,也可以进行非监督学习。其隐藏层内的卷积核参数可以共享,层间连接具有稀疏性,这两点使得卷积神经网络能以较小的计算量进行特征抽取。卷积神经网络在对图像像素和音频进行学习时,往往有稳定的效果而且对数据本身没有额外的特征工程(feature engineering)要求,故主要被用于图像识别和音频识别领域。

  在本文中,后续实验均使用了如下图的网络架构作为基础架构,具体参数和变更详见第四章:

  图3.2实验模型基础架构

  3.2.1卷积层

  卷积层(convolutional layer)的功能是对输入数据进行特征提取,其内往往包含多个卷积核,每一个卷积核中的元素都拥有一个的权重系数,类似于神经网络的神经元(neuron)。

  卷积层有三个主要参数,分别是卷积核大小,步长,和填充方法,卷积层输出的特征图的尺寸就以它们决定。以二维图像为例,其中卷积核大小指提取像素区域的大小,步长指相隔X个元素进行一次区域的提取,而填充方法则是指假设提取的区域包含了图像的边缘,为了控制卷积核的结构,其外部缺失的数据部分应该怎么填充,常用的有两种方法:

  (1)valid padding:对原始图像不进行任何处理,对于原始图像边界的部分,卷积核会变小无法超出其边界。

  (2)same padding:允许卷积核对超出原始图像边界进行填充,使卷积后结果的大小与原来的一致。

  卷积核的大小可以指定为小于图像像素的任意值,这个大小在一些文献中被称为“感受野”(receptive field),对于其具体数值,在图像识别领域的对于其具体大小有一些可信度较高的结论:

  (1)卷积核的大小往往为奇数*奇数的一个正方形区域

  首先是因为区域存在中心点,可以很轻松的找到一个卷积锚点。(卷积区域是以卷积锚点为中心进行步长移动的)

  其次是可以有效利用各种填充方法,假设图像的大小是奇数*奇数,如果使用偶数*偶数的卷积核并选择valid padding,可能会丢失图像边界的部分数据信息。

  (2)卷积核的大小不是越大越好

  AlexNet中使用11*11的大尺寸卷积核,但后来的一些网络结构中都很难见到大于7*7的尺寸。VGGNet中指出,两层3*3卷积核拥有与一层5*5卷积核相同的感受野,如下图所示:

  图3.2.1卷积核感受野[19]

  使用两层3*3卷积核有以下两个优点:

  (1)在卷积核通道数都为n时,尺寸为5*5的一层卷积层中的参数量为25n,而尺寸为3*3的两层卷积层中的参数量共18n。减少总参数数量对网络运行效率提升十分有效。

  (2)更多次数的非线性变换。俩层小卷积核的层可以使用两次非线性激活函数,而一层大卷积核的层却只有一次。更多次数的非线性变换会使得网络整体对特征的学习能力更强。

  因为这两个优点,后来3*3的小卷积核便成为了研究者们的主要选择。常见的大型卷积神经网络会先使用一个7*7的大卷积,之后采用多层3*3卷积堆叠。在轻量化的神经网络中,有全部采用3*3的卷积堆叠的网络,如MobileNetv1,v2,ShuffleNet系列等。[[[]无影.https://www.zhihu.com/question/38098038/answer/771121161.2020.4.20]]

  3.2.2池化层

  在卷积层进行特征提取后,输出的特征图就会被传递到池化层(pooling layer)进行特征选取和信息过滤。池化层将特征图中的单个点的结果使用预先设定好的池化函数替换为对相邻区域的统计量,并对提取好的特征进行压缩。主要有这三个参数:池化的目标区域(ksize),池化区域的步长(strides),填充(padding)。

  在CNN中,池化操作主要指Lp池化(Lp pooling),这是一种基于视觉皮层内阶层结构而建立的模型。[[[]Hyv?rinen,A.and K?ster,U.,2007.Complex cell pooling and the statistics of natural images.Network:Computation in Neural Systems,18(2),pp.81-100.]]最早的池化一般有两种思路:一种是均值池化(mean pooling),另一种是极大池化(max pooling)。

  随机/混合池化:在Lp池化的基础上。随机池化是按照预设的概率分布在其池化区域内随机取一值,混合池化则是指将均值池化与极大池化进行线性组合。这两者相比于基础的Lp池化都具有更强的正则化能力,能够有效过拟合的出现。

  3.2.3全连接层

  卷积神经网络中的全连接层(fully-connected layer)等价于传统前馈神经网络中的隐含层。全连接层一般是卷积神经网络的最后一部分,后面只会链接全连接层。特征图在全连接层中会失去空间拓扑结构,我们将其展开为一维向量后通过激励函数。[[[]Goodfellow,I.,Bengio,Y.,Courville,A..Deep learning(Vol.1).Cambridge:MIT press,2016:326-366.]]

  从表征学习的角度来看,对输入数据进行特征提取的任务主要是由卷积神经网络中的卷积层和池化层完成,全连接层的只需要对提取的特征进行非线性组合以得到输出,即全连接层在一个卷积神经网络网络中不被用作进行特征提取,而是试图让其利用现有的已被提取的高阶特征完成目标任务。

  在一些卷积神经网络中,全连接层的功能可由全局均值池化(global average pooling)代替[[[]Szegedy,C.,Liu,W.,Jia,Y.,Sermanet,P.,Reed,S.,Anguelov,D.,Erhan,D.,Vanhoucke,V.and Rabinovich,A.,2015.Going deeper with convolutions.In Proceedings of the IEEE conference on computer vision and pattern recognition(pp.1-9).]]。全局均值池化的做法是将全部特征图通道的值取平均数组合成向量,假设总共有7x7x256的特征图,全局均值池化将返回一个长度为256的向量,其中每个元素都是对特征图的均值池化。

  深度学习神经网络本质是端对端的过程,输出层是人为赋予的含义,自然对于不同的问题输出层的定义和解释方法都不尽相同。举例来说,对于图像分类问题,输出层使用逻辑函数或标准化指数函数(softmax function)输出分类标签[[[]Ng,A.,Kian,K.and Younes,B.Convolutional Neural Networks,Deep learning..Coursera and deeplearning.ai.2018.]];在识别物体(object detection)任务中,输出层可以为输出物体的分类、坐标、大小;在图像语义分割任务中,输出层会直接输出每个像素的分类结果。在卷积神经网络中,输出层常使用全连接层结构,其工作原理与前馈神经网络中的输出层一致。

  3.3本实验的算法流程

  (1)读取数据集文件

  从文件中读取数据进入内存。

  (2)封装一个数据集类

  使用面向对象编程思维,用一个对象(Object)使其在存储数据集中的书籍逻辑结构的同时,为神经网络提供一些可以直接调用的接口,从而保证预处理阶段和训练阶段的代码分离。

  (3)利用深度学习框架定义深度学习神经网络结构。

  以上节图3.2的架构为基础,定义神经网络结构,确定参数。

  (4)确定全局训练参数

  主要是确定全局学习率,训练所使用的的优化器,以及投喂数据的批量大小(batch size)。

  (5)投喂数据进行训练运行等待数据训练。

  (6)存储训练模型,计算模型预测准确率

  存储后的模型可以进行读取,然后用以对图像进行表情识别任务。

  (7)重复上述过程多次,对比不同模型参数对预测结果的影响,得出实验结论

  3.4其他可以采用的神经网络

  有一些其他的神经网络架构也可用于FER技术中:

  (1)深度信念网络Deep belief network(DBN)

  神经网络的一种,由Hinton等人提出[[[]G.E.Hinton,S.Osindero,andY.-W.Teh,“Afastlearningalgorithmfor deep belief nets,”Neural computation,vol.18,no.7,pp.1527–1554,2006.]]。既可以用于非监督的机器学习,类似于一个自编码机;也可以用于有监督的机器学习,作为分类器来使用。DBN由若干层神经元组成,其构成的元素是受限玻尔兹曼机(RBM)。其训练主要包含两个阶段:预训练和微调[[[]G.E.Hinton,“A practical guide to training restricted boltzmann machines,”in Neural networks:Tricks of the trade.Springer,2012,pp.599–619.]]。预训练时以一种无监督逐层贪心学习策略初始化网络。然后BP网络反向传递至每一层的RBM调整其参数。

  (2)深度编码器Deep autoencoder(DAE)

  利用深度学习网路构筑的编码器,学习如何有效地对数据进行降维编码,DAE通过最小重构误差来优化其输入。其存在诸多变体,如降噪自动编码器(denoising autoencoder)、稀疏自动编码器(DSAE)、卷积自动编码器(CAE2)等。

  (3)递归神经网络Recurrent neural network(RNN)

  RNN是一种连接器模型,可捕获时间信息,更适合于具有任意长度的顺序数据预测。除了以传统前馈方式进行训练深度神经网络外,RNN还包括跨越相邻时间步长并在所有步长上共享相同参数的递归边。其神经元结构如图3.4

  图3.4 RNN网络神经元结构

  (4)生成对抗网络Generative Adversarial Network(GAN)

  生成式对抗网络(GAN,Generative Adversarial Networks)与其说是一种网络,不如说是一种深度学习模型,被视为近年来在复杂分布上进行无监督学习最具前景的方法之一。模型的框架中包含两个模块:生成模块(Generative Model)和判别模块(Discriminative Model),基本思想是让两个模块进行互相博弈,对抗从而产生更优的输出。原始的GAN模型并不要求两个模块都是神经网络,只要是能具有拟合能力并包含生成和判断的函数即可。现在在实用中一般均使用深度学习神经网络实现这两个模块。一个优秀的基于GAN的应用需要有优秀的训练计划安排,不然输出结果可能由于神经网络的非约束性性而不甚理想。[[[]source:https://baike.baidu.com/item/Gan/22181905.2020.4.20]]

  3.5本章小结

  本章主要介绍了深度学习神经网络知识的基础概念,并着重介绍了本文后续实验所使用的的卷积神经网络(CNN)的基本网络结构,和后续实验的算法流程。也简要介绍了其他有用于FER技术的网络结构,本章中所介绍的数学相关知识虽然不是后续实验的必须知识,但了解一定的数学原理可以加深对整个神经网络系统和人工智能研究方法的理解。

  4.实验主体

  4.1实验环境

  实验使用系统:Microsoft Windows 10家庭中文版

  图4.1系统CPU环境和内存

  实验使用语言:Python 3.5

  选用Python语言作为深度学习实验的主要原因是其方便易上手的代码书写,以及非常广泛的第三方库,可以利用前人已经制作好的框架来修改和优化,专注于实验的主体而不用花费大量时间编写一些前置的相关准备函数或者类。

  实验使用框架:TensorFlow 1.2.1 CPU版本

  Google公司提出的TensorFlow框架是现今深度学习领域最火的框架之一,其社群规模,框架全面程度,序列化和部署能力的全面性均十分突出。现在的tensorflow拥有CPU使用版本,为机器配置一般的研究者提供了研究机器学习的通道。

  TensorFlow在数据流编程下运行,具体地,使用数据流图(tf.Graph)表示计算指令间的依赖关系,随后依据数据流图创建会话(tf.Session)并运行图的各个部分[[[]TensorFlow-编程人员指南-图和会话.TensorFlow.2018.9.7]]。tf.Graph包含了图结构与图集合两类相关信息,其中图结构包含图的节点(tf.Operation)和边缘(张量)对象,是各个操作组合在一起的方式,但不规定它们的使用方式,类似于汇编代码;图集合是在tf.Graph中存储元数据集合的通用机制,即对象列表与键(tf.GraphKeys)的关联[[[]TensorFlow-API r1.11-tf.Graph.TensorFlow.2018.9.27]]。当用户创建变量时,系统将其加入变量集合,并在后续操作中使用变量集合作为默认参数。[27]

  构建tf.Graph时将节点和边缘对象加入图中不会触发计算,图构建完成后将计算部分分流给tf.Session实现计算。tf.Session拥有物理资源,通常与Python的with代码块中使用,这样在离开代码块后就会自动释放资源。[[[]TensorFlow-API r1.11-tf.Session.TensorFlow.2018.9.27]]而如果不使用with代码块的情况下创建tf.Session,应在完成会话时明确调用tf.Session.close结束进程。调用Session.run创建的中间张量会在调用结束时释放。tf.Session.run是运行节点对象和评估张量的主要方式,tf.Session.run需要指定fetch并提供供给数据(feed)字典,用户也可以指定其它选项以监督会话的运行。[27][29]

  4.2实验使用的数据集

  FER2013是基于google图像搜索API自动收集的一个大型无限制图像数据库,使用.CSV格式存储。共3列,对应标签emotion;pixels;Usage。

  Emotion是一个正整数,代表表情标签,图像的标签有7类(愤怒anger,厌恶disgust,恐惧fear,开心happiness,悲伤sadness,惊奇surprise and中立neutral)。

  Pixels为一个以空格分隔的正整数序列(最大值为255),代表图像对应像素位置的灰度值。

  Usage为字符串,共3类,分别是“Trainning”、“PublicTest”、“PrivateTest”,分别对应数据集包含的28709个训练用图像(train data),3589个验证用图像(validation data),以及3589个测试图像(test data)。

  利用opencv库显示部分数据图像:

  图集4.2从FER数据集中提取的部分图像

  4.3实验方案

  (1)Python环境的配置

  首先我们需要配置python环境,我选择了使用anaconda的Miniconda(仅包含Conda和Python)进行环境隔离和配置,在安装完anaconda后,打开终端。

  图4.3 Anacoda终端

  使用语句Conda Create-n tensorflow python=3.5。

  创建一个名为tensorflow的虚拟环境,使用的python版本为3.5版本(目前兼容性最好的版本)。

  接着activate tensorflow进入虚拟环境,后续实验的运行环境均为在此虚拟环境下。

基于深度学习的人脸表情识别研究

  相关包和库的安装

  最主要的部分:

  安装tensorflow框架,在终端中输入指令conda install tensorflow。

  部分扩展:

  安装opencv包用以图片处理conda install opencv。

  (2)数据集的预处理与读取

  Fer2013数据集是一个.CSV(Comma Separated Values file,即逗号分隔值)文件,是纯文本文件,我们需要使用适当的方法读取文件中的信息,并将其重组为后续工作需要使用的数据组织结构。

  我们使用pandas包来进行.CSV文件的读取,其自带的pandas.read_csv()函数可以直接从.csv文件里读取数据,并依照列名创建对应的字典,接着对于pixels列对应的数据,其原始数据为一个2304长度的一维数组,存储了每个像素的灰度值(最大值为255),显而易见的是这种数据是不符合我们所认知的图像的数据组织结构的,所以需要对其的形状做出调整,使其成为一个48*48的二维数组,因为像素数组唯一对应一个表情标签,所以在建立数据集的时候二者之间的关系也需要保留。这样我们便成功的构筑了网络的输入层。

  为了方便后续网络的训练,我们把数据集dataset封装成一个类,其自带一个函数next_batch(batch_size,Flag of shuffle),可以指定每一个batch投入的样本数据的数目,这里有几个概念需要明晰:

  在深度学习中,iteration(有时候叫training step)指一个迭代,每次迭代更新一次网络结构中的参数;batch_size,指一次迭代里的样本数量;epoch表示过了一遍训练集中的所有样本。一般来说在训练集样本数据较大的时候,我们因为机器的内存原因,往往无法使batch_size直接等于样本总数,所有会设置多个iteration来进行训练。

  实验网路模型A:

  网络结构参数:

  Conv1:

  使用了5*5的卷积核大小,步长为1*1,padding为SAME方法,卷积核通道数为64

  使用relu函数作为隐藏层的激活函数

  池化层的ksize为3*3,strides为2*2,填充方法依然是SAME方法

  在池化层后加入了一个局部响应归一化层(Local Response Normalization)来进行drop处理防止relu激励后的数据过拟合。(此方法最早出自AlexNet[[[]《ImageNet Classification with deep ConvolutionNeural Networks》.source:http://papers.nips.cc/paper/4824-imagenet-classification-with-deep-convolutional-neural-networks.pdf 2020.4.20]])

  x_image=tf.reshape(x,[-1,48,48,1])

  #conv1

  W_conv1=weight_variables([5,5,1,64])

  b_conv1=bias_variable([64])

  h_conv1=tf.nn.relu(conv2d(x_image,W_conv1)+b_conv1)

  #pool1

  h_pool1=maxpool(h_conv1)

  #norm1

  norm1=tf.nn.lrn(h_pool1,4,bias=1.0,alpha=0.001/9.0,beta=0.8)

  Conv2:

  使用了3*3的卷积核大小,步长为1*1,padding为SAME方法,卷积核通道数为64

  使用relu函数作为隐藏层的激活函数

  池化层的ksize同样为3*3,strides为2*2,填充方法依然是SAME方法

  在池化层后加入了一个局部响应归一化层(Local Response Normalization)来进行drop处理防止relu激励后的数据过拟合。

  #conv2

  W_conv2=weight_variables([3,3,64,64])

  b_conv2=bias_variable([64])

  h_conv2=tf.nn.relu(conv2d(h_pool1,W_conv2)+b_conv2)

  norm2=tf.nn.lrn(h_conv2,4,bias=1.0,alpha=0.001/9.0,beta=0.8)

  h_pool2=maxpool(norm2)

  FC1:

  在展平上一层的输出后,使用了768个神经元对其进行全连接,激活函数依然为relu。

  #Fully connected layer

  W_fc1=weight_variables([12*12*64,768])

  b_fc1=bias_variable([768])

  h_conv3_flat=tf.reshape(h_pool2,[-1,12*12*64])

  h_fc1=tf.nn.relu(tf.matmul(h_conv3_flat,W_fc1)+b_fc1)

  FC2:

  使用了192个神经元对上一层进行全连接,激活函数依然为relu。

  #Fully connected layer

  W_fc2=weight_variables([768,192])

  b_fc2=bias_variable([192])

  h_fc2=tf.matmul(h_fc1,W_fc2)+b_fc2

  Linaer:

  7个线性分类器。

  #linear

  W_fc3=weight_variables([192,7])

  b_fc3=bias_variable([7])

  y_conv=tf.add(tf.matmul(h_fc2,W_fc3),b_fc3)

  训练参数:

  迭代次数(steps):共30000次

  优化器:AdamOptimizer,默认全局学习率参数(1e-4),最小化交叉熵

  train_step=tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)

  每批次投喂样本大小(Batch Size):50。

  训练结果及结论:

  模型准确度只有52,仅到了SVM方法的水平,尝试在下一次训练里进行调参。

  实验网络模型B

  网络结构参数:

  Conv1:

  使用了5*5的卷积核大小,步长为1*1,padding为SAME方法,卷积核通道数为64

  使用relu函数作为隐藏层的激活函数

  池化层的ksize为3*3,strides为2*2,填充方法依然是SAME方法

  在池化层后加入了一个局部响应归一化层来进行drop处理防止relu激励后的数据过拟合,调整其参数beta为0.75。

  x_image=tf.reshape(x,[-1,48,48,1])

  #conv1

  W_conv1=weight_variables([5,5,1,64])

  b_conv1=bias_variable([64])

  h_conv1=tf.nn.relu(conv2d(x_image,W_conv1)+b_conv1)

  #pool1

  h_pool1=maxpool(h_conv1)

  #norm1

  norm1=tf.nn.lrn(h_pool1,4,bias=1.0,alpha=0.001/9.0,beta=0.75)

  Conv2:

  使用了3*3的卷积核大小,步长为1*1,padding为SAME方法,按照一些常见模型思想的将第二层卷积核通道数为增加128

  使用relu函数作为隐藏层的激活函数

  池化层的ksize同样为3*3,strides为2*2,填充方法依然是SAME方法

  在池化层后加入了一个局部响应归一化层来进行drop处理防止relu激励后的数据过拟合,也修改其参数beat为0.75。

  #conv2

  W_conv2=weight_variables([3,3,64,128])

  b_conv2=bias_variable([128])

  h_conv2=tf.nn.relu(conv2d(h_pool1,W_conv2)+b_conv2)

  norm2=tf.nn.lrn(h_conv2,4,bias=1.0,alpha=0.001/9.0,beta=0.75)

  h_pool2=maxpool(norm2)

  FC1:

  在展平上一层的输出后,换做使用1024个神经元对其进行全连接,激活函数依然为relu。

  #Fully connected layer

  W_fc1=weight_variables([12*12*128,1024])

  b_fc1=bias_variable([768])

  h_conv3_flat=tf.reshape(h_pool2,[-1,12*12*128])

  h_fc1=tf.nn.relu(tf.matmul(h_conv3_flat,W_fc1)+b_fc1)

  FC2:

  该换使用98个神经元对上一层进行全连接,激活函数依然为relu。

  #Fully connected layer

  W_fc2=weight_variables([1024,98])

  b_fc2=bias_variable([98])

  h_fc2=tf.matmul(h_fc1,W_fc2)+b_fc2

  Linaer:

  7个神经元作为线性感知分类器。

  #linear

  W_fc3=weight_variables([98,7])

  b_fc3=bias_variable([7])

  y_conv=tf.add(tf.matmul(h_fc2,W_fc3),b_fc3)

  训练参数:

  迭代次数(steps):共30000次

  优化器:AdamOptimizer,默认全局学习率参数(1e-4),最小化交叉熵

  train_step=tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)

  每批次投喂样本大小(Batch Size):50。

  训练结果及结论:

  在调整部分参数后网络的准确度从52.6上升到了54.7,上升了两个百分点。因为与模型A相比,对网络结构未进行改动,主要只进行了参数调整。因为结果不甚理想,考虑在下一个模型对结构进行小规模调整。

  实验网络模型C

  网络结构参数:

  Conv1:

  使用了5*5的卷积核大小,步长为1*1,padding为SAME方法,卷积核通道数为64

  使用relu函数作为隐藏层的激活函数

  池化层的ksize为3*3,strides为2*2,填充方法依然是SAME方法

  将原有的池化层后的局部响应归一化层去除。

  x_image=tf.reshape(x,[-1,48,48,1])

  #conv1

  W_conv1=weight_variables([5,5,1,64])

  b_conv1=bias_variable([64])

  h_conv1=tf.nn.relu(conv2d(x_image,W_conv1)+b_conv1)

  #pool1

  h_pool1=maxpool_3x3(h_conv1)

  Conv2:

  使用了3*3的卷积核大小,步长为1*1,padding为SAME方法,将第二层卷积核通道数为增加128

  使用relu函数作为隐藏层的激活函数

  池化层的ksize更改为为2*2,strides为2*2,填充方法依然是SAME方法

  去除了原有的一个局部响应归一化层。

  #conv2

  W_conv2=weight_variables([3,3,64,128])

  b_conv2=bias_variable([128])

  h_conv2=tf.nn.relu(conv2d(h_pool1,W_conv2)+b_conv2)

  h_pool2=maxpool_2x2(h_conv2)

  FC1:

  在展平上一层的输出后,换做使用1024个神经元对其进行全连接,激活函数依然为relu。

  #Fully connected layer1

  W_fc1=weight_variables([12*12*128,1024])

  b_fc1=bias_variable([1024])

  h_conv3_flat=tf.reshape(h_pool2,[-1,12*12*128])

  h_fc1=tf.nn.relu(tf.matmul(h_conv3_flat,W_fc1)+b_fc1)

  FC2:

  该换使用98个神经元对上一层进行全连接,激活函数依然为relu。

  #Fully connected layer2

  W_fc2=weight_variables([1024,98])

  b_fc2=bias_variable([98])

  h_fc2=tf.matmul(h_fc1,W_fc2)+b_fc2

  Linaer:

  7个神经元感知作为线性分类器。

  #linear

  W_fc3=weight_variables([98,7])

  b_fc3=bias_variable([7])

  y_conv=tf.add(tf.matmul(h_fc2,W_fc3),b_fc3)

  训练参数:

  迭代次数(steps):共30000次

  优化器:AdamOptimizer,更改默认全局学习率参数(7*1e-5),最小化交叉熵

  train_step=tf.train.AdamOptimizer(7*1e-5).minimize(cross_entropy)

  每批次投喂样本大小(Batch Size):50。

  训练结果及结论:

  在微调整网络结构以后精度回到了52.5左右,仍未突破60大关,判断需要利用进行更大的网络结构调整。在去除了LRN层后发现精度并未发生显著改变。

  实验模型D

  网络结构参数::

  Conv1:

  使用了5*5的卷积核大小,步长为1*1,padding为SAME方法,卷积核通道数为64

  使用relu函数作为隐藏层的激活函数

  池化层的ksize为3*3,strides为2*2,填充方法依然是SAME方法。

  x_image=tf.reshape(x,[-1,48,48,1])

  #conv1

  W_conv1=weight_variables([5,5,1,64])

  b_conv1=bias_variable([64])

  h_conv1=tf.nn.relu(conv2d(x_image,W_conv1)+b_conv1)

  h_pool1=maxpool_3x3(h_conv1)

  Conv2:

  使用了3*3的卷积核大小,步长为1*1,padding为SAME方法,将第二层卷积核通道数为增加128

  使用relu函数作为隐藏层的激活函数

  池化层的ksize更改为为3*3,strides为2*2,填充方法依然是SAME方法。

  #conv2

  W_conv2=weight_variables([3,3,64,128])

  b_conv2=bias_variable([128])

  h_conv2=tf.nn.relu(conv2d(h_pool1,W_conv2)+b_conv2)

  h_pool2=maxpool_3x3(h_conv2)

  FC1:

  在展平上一层的输出后,换做使用1024个神经元对其进行全连接,激活函数依然为relu。

  使用了dorpout函数防止过拟合。

  #Fully connected layer1

  W_fc1=weight_variables([12*12*128,1024])

  b_fc1=bias_variable([1024])

  h_conv3_flat=tf.reshape(h_pool2,[-1,12*12*128])

  h_fc1=tf.nn.relu(tf.matmul(h_conv3_flat,W_fc1)+b_fc1)

  h_fc1_drop=tf.nn.dropout(h_fc1,0.8)

  FC2:

  该换使用98个神经元对上一层进行全连接,激活函数依然为relu。

  #Fully connected layer2

  W_fc2=weight_variables([1024,98])

  b_fc2=bias_variable([98])

  h_fc2=tf.matmul(h_fc1_drop,W_fc2)+b_fc2

  Linaer:

  7个神经元感知器作为线性分类器。

  #linear

  W_fc3=weight_variables([98,7])

  b_fc3=bias_variable([7])

  y_conv=tf.add(tf.matmul(h_fc2,W_fc3),b_fc3)

  训练参数:

  迭代次数(steps):共30000次

  优化器:AdamOptimizer,更改默认全局学习率参数(1e-4),最小化交叉熵

  train_step=tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)

  每批次投喂样本大小(Batch Size):60。

  训练结果及结论:

  这一次的模型在迭代到23000次的时候出现了最高的测试准确率55,但后续的训练反而降低了模型对数据评估的准确率。

  4.4实验结论与实验猜想

  表4.4模型参数一览

  模型序号CONV1卷积核通道数POOL1是否使用lrn CONV2卷积核通道数POOL2是否使用lrn FC1神经元数是否使用Dropout FC2神经元数最高准确百分比批注

  A 64是64是768否192 52.6

  B 64是128是1024否98 54.7

  C 64否128否1024否98 52.9学习率有变动

  D 64否128否1024是98 55.0

  利用深度学习神经网络进行学习,具有较大的随机性,往往需要经过不断地调参和多次训练才能获得一个较好的训练模型。受限于机器的硬件配置,笔者难以进行大批量大规模的数据训练,但仅依照上述几次实验的结果,结合学界的一些研究,可以给出如下结论:

  (1)基于深度学习神经网络技术的表情识别,可以较为轻易地达到传统AFER技术的水平,但免去了需要经验者手工提取特征的步骤,在一定程度上降低了研究的门槛,使很多非数学专业的研究工作者有能力利用深度学习神经网络开始自己的研究。

  (3)局部响应归一化层作为AlexNet中首次提出的一个概念,其在小规模的网络中起到的作用十分有限,这几年研究人员对其的使用率逐步降低也一定程度上佐证了这一观点。

  (3)在全连接层加入dropout函数虽然可以在一定程度上防止过拟合的发生,同时也可能会因为丢弃了部分有效特征导致后续训练中的网络模型预测准确度下降。

  (4)小型网络里,更建议在全连接层使用dropout而不在池化层后使用lrn来防止过拟合,防止在卷积层就丢失部分特征。

关于作者: guimow

热门文章