(Face Alignment) One Millisecond Face Alignment with an Ensemble of Regression Trees 笔记

人脸关键点检测,也可以认为是人脸对齐(face alignment)可以采用多种方法进行实现,其中一种比较有代表性的方法是使用回归来完成这一功能。2014年CVPR上“One Millisecond Face Alignment with an Ensemble of Regression Trees”这篇文章是回归方法中的一种,Dlib库中的人脸关键点检测就是依据这一方法进行了实现。

论文主要特点

1,使用级联的回归树(ensemble of regression trees)来实现人脸对齐
2,将此方法拓展使得可以轻易的处理缺失数据
3,在速度和准确率上都得到了很优秀的效果

论文主要方法

此方法与之前的“Cascaded pose regression”和“Face alignment by explicit
shape regression”方法属于同一个类型,其核心都是使用了两层的回归来建立数学模型。

在第一层回归,其迭代公式为:

S^(t+1)=S^(t)+γt(I,S^(t))

其中S是形状向量,存储着所有脸部关键点的位置,γt是一层的回归器,其输入为当前的形状向量和训练图片,其输出则是对所有的关键点的位置更新量。可以看到,在第一层的级联回归器中,每经过一级级联回归器,就会对所有关键点位置进行一次更新来达到更正确的位置。

在第二层回归,也就是γt内部也是一次回归的过程,在本篇文章中采用的是Gradient Tree Boosting Algorithm的方法来得到一系列的回归树(Regression Tree)最终完成第二级的回归,需要注意的是,第二级回归的对象是当前预测值和真实值的差值。

第一层回归训练过程

首先,有训练数据集(I1,S1),...(In,Sn),其中Ii图片,Si为人脸关键点的位置。
在第一层的回归训练中,数据组织形式可以写为(Iπi,Si^(t),ΔSi(t)),其中Iπi为数据集中的图片,Si^(t)是第一层级联回归的第t层的预测关键点位置,ΔSi(t)是这一层回归结果和真实值的差值。
其迭代公式为:

S^(t+1)=S^(t)+γt(I,S^(t))

ΔSi(t+1)=SπiS^(t+1)

按照这样的方式不断进行迭代,当第一层回归级联层数设置为K层时,就会产生γ1,γ2,...,γk这些回归器,这K个回归器就是我们通过训练所要得到的回归模型。

第二层回归训练过程

第二层的训练就是要具体到每一个γt是如何训练得到的,第二层的回归器可以有多种方法实现,比如随机蕨(Random Fern)或者本篇文章中使用的回归树。在本篇文章中使用Gradient Boosting Tree Algorithm算法实现。

回归树模型

首先简单的介绍回归树。回归树是一种将特征空间进行分割,之后在每一个分割空间进行拟合的简单模型。其数学表达式可以些为:

f(x)=m=1McmI(xRm)

式中R1,R2,...,Rm为m个划分的子空间,cm为每个子空间对应的权值,加和之后就是这一个回归树模型的输出。建立回归树的过程也就是寻找使误差和模型输出最小的划分和权值的过程。
以平方误差为例,定义误差为(yif(xi)), 首先考虑最优的cm,设定预测模型中表示为c^m,可以很容易的看到在每个划分的子空间R中,最优的cm就是当前子空间对应的真实预测值的平均,可以表示为:
c^m=ave(yixiRm)

这样就很容易找到了适合的cm,于是如何建立回归树这一问题的关键在于如何确定特征子空间的划分。这一寻找过程可以描述如下:

  1. 在特征集合中找到用于分割的点s,和分割的变量j,这样可以将空间划分为两部分;
    R1(j,s)=(XXjs)andR2(j,s)=(XXjs)
  2. 之后在最小平方准则下找到最优的j,s
    minj,s[minc1xiR1(j,s)(yic1)2+minc2xiR2(j,s)(yic2)2]
    其中的c1,c2可以通过上面提到的公式找到,即:
    c^1=ave(yixiR1(j,s))andc^2=ave(yixiR2)

于是,通过这样的方式就可以建立一个回归树模型。

Boosting 方法

Boosting方法是一种强有力的方法,既可以应用于分类问题上,也可以应用于回归问题上。这一方法的思想是将多个弱分类器进行组合,来组成一个高效的分类器。
AdaBoost算法是这一类方法中比较有代表性的,以此为例简单介绍这一方法。首先给出这一算法结构图如下:
(Face Alignment) One Millisecond Face Alignment with an Ensemble of Regression Trees 笔记
这一算法的基本流程为输入样本经过多级分类器Gn(x)最终得到最优的结果,所有的分类器的输出结果都会作为下一级分类器的输入,在这一过程中不断找寻αm作为使分类效果更优秀的m层权重。总而言之,就是在训练过程中,不断提升对正确分类有贡献样本的权重,同时减轻对错误分类贡献的样本的权重,最终将弱分类器组合,产生优秀的分类效果。
这一算法的数学描述如下:
(Face Alignment) One Millisecond Face Alignment with an Ensemble of Regression Trees 笔记

Boosting 应用于加性模型(Additive Model)

加性模型的基本思想是用多个模型累加的结果来代替单一的模型,这样的话可以在一些复杂的非线性问题中取得更优秀的效果。这一思想也可以被应用于Boosting上,具体的思路是在Boosting每层的模型所处理的都是上一步的残差,这样的话最终所有单个模型累加的和才是预测结果。而普通的Boosting只是数据依次通过每层模型,最终输出只是最后一层模型的结果,不是前几层的累加。可以将这一方法描述如下:
(Face Alignment) One Millisecond Face Alignment with an Ensemble of Regression Trees 笔记
于是可以看到和上面的AdaBoost相比,最终输出是f1(x)+f2(x)+...+fm(x).这就是Boosting应用于加性模型的方法,这一方法在后面的树模型和Gradient Boosting Tree Algorithm有很关键的作用。

Boosting Trees

以下介绍将Boosting方法应用于树的表示,在介绍回归树时我们知道了树模型就是划分特征子空间和找到对应权值的过程,于是可以将分类准则定义为

xRjf(x)=γj
表示当特征x位于空间Rj,则输出预测结果γj。这样一棵树可以如下表示:
T(x;θ)=j=1JγjI(xRj)

其中θ={Rj,γj}1J。自然,建立一颗树的过程也可以写为

θ^=argminθj=1JxiRjL(yi,γj)

Boosted Tree模型就是多棵树的加和,当有M棵树时表示为

fM(x)=m=1MT(x;θ)

于是将Boosting应用于树时,在加性模型中的每一步迭代时,可写为:

θ^m=argminθmi=1ML(yi,fm1(xi)+T(xi;θm))

Gradient Boosting Tree

这里终于可以描述本篇文章这一算法了。关于梯度下降的相关内容这里不做重复,网上有很多解释,这里主要介绍如何将梯度下降应用于Boosting Tree模型中。
在加性模型当中,对于第fm1(xi)可以将其梯度表示为:

gim=[dL(yi,f(xi))df(xi)]f(xi)=fm1(xi)

在Gradient Boosting Tree中会面临这样一个问题,如果想要在训练数据中实现梯度下降,找到误差函数的解析解是很容易的,然而当使用在这一算法中时,会面临难以计算的问题,所以此算法可以采用了这样一种思路来完成迭代,在加性模型的每一步中,寻优时的误差不是来自于真实值和预测值的误差,而是来自于加性模型中上一个模型计算的梯度。表达式为:

θ^=argminθi=1N(gimT(xi;θ))2

于是我们可以得到完整的Gradient Tree Boosting 算法:
(Face Alignment) One Millisecond Face Alignment with an Ensemble of Regression Trees 笔记
比较值得注意的就是在2.(b)中回归树Rjm区域拟合的是梯度γim,在2.(d)中使用了加性模型(Additive Model)的迭代方式。

论文中使用的Gradient Boosting Tree Algorithm

首先给出论文中使用的训练γr,即第二层回归器的训练算法。
(Face Alignment) One Millisecond Face Alignment with an Ensemble of Regression Trees 笔记
对比上面给出的原始算法可以看到,本论文中使用了平方误差12[yif(xi)]2作为Loss Function,于是直接求导得到yif(xi),在每一步迭代中使用这一梯度作为拟合对象,最终构建模型。

需要注意的一点是,在每一个二层回归中,输入回归对象是每一个第一层回归完成后的误差ΔSit作为每一个第二层回归的输入,而不是直接真实关键点位置作为输入。

以上就是这篇文章所使用算法的基本介绍,在 The Elements of Statisticlal Learning 中第9,10章对这一算法有详细和全面介绍,如有不清楚可以参考。

算法实现中的几个细节

Shape invariant split test

这一方法解决的是在输入图片每次进行回归迭代找寻最优的下一步关键点位置时,如何确定下一步关键点的坐标。这里给出的方法是采用预测值基于真实值的相对坐标。举个例子,当ku表示当前待选特征点序号时,此时这一点的横坐标为Xku,找到与其最近的真实特征点,其横坐标表示为U, 那么二者之间的差值表示为δXu=UXku,于是加入旋转和尺度变换,可以用表示为U=Xku+1siRiTδXu,同理y也是一样的,这样就可以把特征点的绝对坐标转换为相对坐标。

建立回归树时如何选择节点

在建立过程中会产生一系列的节点,之后在这其中选择最优节点。在拟合回归树中使用平方误差作为代价函数。待选节点为θ,最优节点表示为θ。此时的目标时最小化下列式子:

E(Q,θ)=s{l,r}iQ{θ,s}riμθ,s2

式子中,l,s 分别代表左右子树,μθ,s代表按照当前划分产生的结果。用回归树拟合的目的是最小化这一过程。
首先很容易理解在左右子树其平方和最小值为左右子树分别的平均值,表示为

μθ,s=1Qθ,siQ{θ,s}rifors{l,r}

将这一公式代入上式打开平方的形式,进行推导舍弃与θ无关项,可以得到

argminE(Q,θ)=argmaxs{l,r}Qθ,sμθ,sTμθ,s

根据左右子树之间的关系已知左子树的值就可以算出右子树,所以对于上面的优化问题,事实上只需要计算一边的值即可。这样就完成了单颗回归树拟合的问题。

特征点的选择

在随机选取特征的过程中,如何控制随机生成的位置距离当前特征点的距离是一个问题,距离太远显然不如距离近一些好。于是引入参数λ,使用指数形式来控制这一距离

P(u,v)eλuv

缺失值的处理

在建立回归树选择节点时,其代价函数可以被很容易的拓展为适应处理缺失值的形式,可以写为

E(Q,θ)=s{l,r}iQ{θ,s}(riμθ,s)TWi(riμθ,s)

其中WI就是处理缺失值的权向量,如果不缺失它的值为1,缺失值为0。与此相对应,在建立回归树时面对残差也可以乘上这一缺失值的权向量。

参考文献

The Elements of Statisticlal Learning
One Millisecond Face Alignment with an Ensemble of Regression Trees
Face Alignment by Explicit Shape Regression