PCA(principal Component Analysis), 即主成分分析法。是一种广泛使用的数据压缩方法,那它被使用在人脸识别算法中的呢?
抽象理解
PCA算法本质就是通过空间变换,将原始数据变换到另一个维度更低、并且不同类别数据差异更明显的坐标系中,最后通过衡量新坐标系中新样本和训练样本差异性的大小来实现分类。因此这里将引入两个关键问题:①如何降维?②怎样变换到什么样的坐标空间中?
1)如何降维?
降维的要求是减少不同数据之间的相关性,去除信息冗余,提取主成分。具体来说,就是既要把不同人的面部数据相关性减小,又要提取最能表达其差异性的特征。假设元素数据集可以用矩阵 X X X表示, X X X的维度为 m × n m\times n m×n, 假设有一变换矩阵 P P P,其维度为 k × m k\times m k×m,那么可以得到矩阵Y: Y = P X Y=P X Y=PX,且 Y Y Y的维度是 k × n k \times n k×n。当 k < m 时 k<m时 k<m时,并且 Y Y Y可以体现 X X X数据的特性时,即可实现 X X X的降维。所以问题就变为如何得到这个变化矩阵 P P P,使得数据之间相关性最小?
2) P是什么样的矩阵?
错误理解:数据集
X
X
X中,包含样本
X
1
,
X
2
X_{1},X_{2}
X1,X2(可理解为两张不同人脸数据),其相关性可以用统计学中的协方差衡量。当协方差的值等于0时,表示样本无相关,此时数据相关性最小。
c
o
v
(
X
1
,
X
2
)
=
0
cov(X_{1},X_{2})=0
cov(X1,X2)=0。如果样本数量超过2,即认为多维样本时,可以引入协方差矩阵表示两两样本之间的相关性。
c
o
v
(
X
)
=
[
c
o
v
(
X
1
,
X
1
)
c
o
v
(
X
1
,
X
2
)
c
o
v
(
X
1
,
X
3
)
⋯
c
o
v
(
X
1
,
X
n
)
c
o
v
(
X
2
,
X
1
)
c
o
v
(
X
2
,
X
2
)
c
o
v
(
X
2
,
X
3
)
⋯
c
o
v
(
X
2
,
X
n
)
c
o
v
(
X
3
,
X
1
)
c
o
v
(
X
3
,
X
2
)
c
o
v
(
X
3
,
X
3
)
⋯
c
o
v
(
X
3
,
X
n
)
⋮
⋮
⋮
⋮
⋮
c
o
v
(
X
n
,
X
1
)
c
o
v
(
X
n
,
X
2
)
c
o
v
(
X
n
,
X
3
)
⋯
c
o
v
(
X
n
,
X
n
)
]
cov(X)=\begin{bmatrix} cov(X_{1},X_{1}) & cov(X_{1},X_{2}) & cov(X_{1},X_{3}) &\cdots &cov(X_{1},X_{n}) \\ cov(X_{2},X_{1}) & cov(X_{2},X_{2}) & cov(X_{2},X_{3}) &\cdots &cov(X_{2},X_{n}) \\ cov(X_{3},X_{1}) & cov(X_{3},X_{2}) & cov(X_{3},X_{3}) &\cdots &cov(X_{3},X_{n}) \\ \vdots& \vdots & \vdots & \vdots &\vdots \\ cov(X_{n},X_{1}) & cov(X_{n},X_{2}) & cov(X_{n},X_{3}) &\cdots &cov(X_{n},X_{n}) \\ \end{bmatrix}
cov(X)=⎣⎢⎢⎢⎢⎢⎡cov(X1,X1)cov(X2,X1)cov(X3,X1)⋮cov(Xn,X1)cov(X1,X2)cov(X2,X2)cov(X3,X2)⋮cov(Xn,X2)cov(X1,X3)cov(X2,X3)cov(X3,X3)⋮cov(Xn,X3)⋯⋯⋯⋮⋯cov(X1,Xn)cov(X2,Xn)cov(X3,Xn)⋮cov(Xn,Xn)⎦⎥⎥⎥⎥⎥⎤。所以变换矩阵P的左右应该是能够使得,
P
X
PX
PX变换到
Y
Y
Y后,
Y
Y
Y的不同样本之间的协方差为零,即使得
c
o
v
(
Y
)
=
Λ
cov(Y) = \Lambda
cov(Y)=Λ, 其中
Λ
\Lambda
Λ为对角矩阵。
正确理解:关于数据集
X
X
X,起初错误理解为
X
X
X中包含
n
n
n张人脸图像,每张图像展开的维度为
m
m
m,则一张人脸图像的应该对应
X
i
X_{i}
Xi,那么在下面简化计算协方差矩阵时,
X
X
X减去平取值就是每个
X
i
−
X
ˉ
i
X_{i}-\bar{X}_{i}
Xi−Xˉi,最后并不能得到平均人脸图。假设
X
X
X有20张图片,每张图片展开维度是65536,很容易将
X
X
X理解为有20个数据,每个数据
X
i
X_{i}
Xi包含65536离散变量,从而导致错误理解。正确理解应该是
X
X
X是65536维度,每个维度包含20个离散变量的数据,例如:一个一维随机变量
x
=
[
1
,
3
,
4
,
6
,
8...
]
x=[1,3,4,6,8...]
x=[1,3,4,6,8...], 现在只是将1维扩充到65536维。抽象理解可以是,每张图像都有对应的像素点坐标,都取20张人脸图像某一位置的数据构成一个离散变量,最后构成65536维随机变量。
3) 怎样求P
更具协方差定义可以将 X X X协方差矩阵简化计算为 C = 1 m X X T C=\frac{1}{m}XX^{T} C=m1XXT其中 X X X数据集中各样本已经减去平均值,同理 Y Y Y的协方差矩阵简化计算为 D = 1 k Y Y T D=\frac{1}{k}YY^{T} D=k1YYT由 Y = P X Y=PX Y=PX可以得到: D = 1 k Y Y T = 1 k ( P X ) ( P X ) T = m k P ( 1 m X X T ) P T = m k P C P T D=\frac{1}{k}YY^{T}=\frac{1}{k}(PX)(PX)^{T}=\frac{m}{k}P(\frac{1}{m}XX^{T})P^{T}=\frac{m}{k}PCP^{T} D=k1YYT=k1(PX)(PX)T=kmP(m1XXT)PT=kmPCPT。 其中 D D D为对角阵,因此求矩阵 P P P可以转换为求协方差矩阵 C C C对角化的过程。因为 C C C为实对称矩阵,则有性质: C C C必有正交矩阵 P P P使得 P − 1 C P = P T C P = Λ P^{-1}CP=P^{T}CP=\Lambda P−1CP=PTCP=Λ,因此可以通过对角化 C C C求出特征值和特征向量,进而得到 P P P。
4)实际计算问题
在采用PCA算法进行人脸识别时,通常样本数量远小于样本维度,假设有20张训练图像,每幅图的像素为
256
×
256
256\times 256
256×256 pixels,那每张图展开后的维度将为65536,此时训练集
X
X
X的维度为
65536
×
20
65536\times 20
65536×20, 对应的协方差矩阵
C
C
C的维度则是
65536
×
65536
65536\times 65536
65536×65536。如果直接计算
C
C
C的特征值和特征向量将是不可取的,因为
r
(
A
B
)
≤
m
i
n
(
r
(
A
)
,
r
(
B
)
)
r(AB)\leq min(r(A),r(B))
r(AB)≤min(r(A),r(B)),此时
C
C
C的秩必然小于等于
X
X
X的秩,即有:
r
(
C
)
≤
n
r(C)\leq n
r(C)≤n (
n
n
n为图片数量。此时计算
C
C
C的特征值和特征向量可以转换求
C
T
C^{T}
CT的特征值和特征向量。
假设
H
=
C
T
=
1
m
X
T
X
H=C^{T}=\frac{1}{m}X^{T}X
H=CT=m1XTX, 假设
H
H
H的特征值为
λ
i
\lambda_{i}
λi特征向量为
α
i
\alpha_{i}
αi,则有:
H
α
i
=
λ
i
α
i
H\alpha_{i}=\lambda_{i}\alpha_{i}
Hαi=λiαi
X
T
X
a
i
=
λ
i
α
i
X^{T}Xa_{i}=\lambda_{i}\alpha_{i}
XTXai=λiαi
X
X
T
X
α
i
=
λ
i
X
α
i
XX^{T}X\alpha_{i}=\lambda_{i}X\alpha_{i}
XXTXαi=λiXαi
C
(
X
α
i
)
=
λ
i
(
X
α
i
)
C(X\alpha_{i})=\lambda_{i}(X\alpha_{i})
C(Xαi)=λi(Xαi),那么
H
H
H的特征值也就等于
C
C
C的特征值,
X
α
i
X\alpha_{i}
Xαi就是
C
C
C的特征向量,此时计算
H
H
H的特征值和特征向量也就容易得多。
5)计算实例
利用MATLAB对一组实例进行计算,原始数据 X o X_{o} Xo X o = [ 1 1 1 1 3 2 2 3 3 4 4 0 2 4 4 ] X_{o}= \begin{bmatrix} 1 & 1&1 \\ 1& 3& 2\\ 2& 3&3 \\ 4& 4&0 \\ 2& 4 & 4 \end{bmatrix} Xo=⎣⎢⎢⎢⎢⎡112421334412304⎦⎥⎥⎥⎥⎤减去每列均值 X = X o − X ˉ X=X_{o}-\bar{X} X=Xo−Xˉ: X = [ − 1 − 2 − 1 − 1 0 0 0 0 1 2 1 − 2 0 1 2 ] X=\begin{bmatrix} -1 & -2&-1 \\ -1& 0& 0\\ 0 & 0&1\\ 2 & 1&-2 \\ 0 & 1& 2 \end{bmatrix} X=⎣⎢⎢⎢⎢⎡−1−1020−20011−101−22⎦⎥⎥⎥⎥⎤Matlab中有现成的PCA函数,一个是princomp()另一个是 p c a c o v ( ) pcacov() pcacov(),两者属于参数不同, p r i n c o m p princomp princomp输入参数为原始数据即: X o X_{o} Xo,pcacov输入参数为协方差矩阵 C , ( C = c o v ( X ) ) C, (C=cov(X)) C,(C=cov(X))。同时我们也可以对协方差矩阵直接进行特征值求解 e i g ( C ) eig(C) eig(C)。Matlab代码如下:
clc
clear;
Xo=[1 1 2 4 2;1 3 3 4 4;1,2,3,0,4]';
X=[-1,-1,0,2,0;-2,0,0,1,1;-1 0 1 -2 2]';
C = cov(X);
[coef,score,latent,t2]=princomp(Xo); % coef and coeff = vectors
[coeff,latent2,explained]=pcacov(C);
[eigenvectors,eigenvalues]=eig(C);
% eigenvectors,coef,coeff % eigenvectors
% eigenvalues, latent, latent2 % eigenvalues
score , X*eigenvectors % eigenvectors of C
上面代码计算结果会略有不同,是正负号与排列顺序的区别。也可利用eigs对C之间分解,得到排序后的特征值和特征向量,从而更容易得到需要的主要维度。
6)特征脸(Eigenface)
特征脸实际就是将我们计算得到的特征向量按原有图像像素排列,即可得到对应的特征脸,等同于将上面代码中计算的score或X*eigenvectors的每列的特征向量进行重新排列。采用ORL人脸数据库进行实际计算,该数据集中共包含40个人的不同人脸图像,总共400张,图像分辨率为112×92pixels。我们将计算得到的特征脸取序列取前十项特征脸和最后十项特征脸进行对比,如图1所示:
Fig1. 特征脸及对比
7)PCA人脸识别
在第3节中已经对实际的协方差矩阵的特征值和特征向量进行计算, C C C对应的特征向量为 X α i X\alpha_{i} Xαi,其变换矩阵为 E E E, E = X ( α 1 , α 2 , . . . α k ) E=X(\alpha_{1},\alpha_{2},...\alpha_{k}) E=X(α1,α2,...αk), 则 P = E T P=E^{T} P=ET。从而得到所求变换矩阵 P P P, 在实际计算中,P的维度为 n × m n\times m n×m, Y = P X Y=PX Y=PX计算得到Y的维度为 n × n n\times n n×n, 而根据主成分分析法,取 P P P的前 k k k行即可选取相应的主成分。即实际计算时可根据数据选取 P P P前 k k k行即可,记为 P k P_{k} Pk。我们利用ORL人脸数据库,将十组数据每组选取7张,共280张作为PCA计算的数据,其余120张作为测试集。在识别测试集过程中,只需要对新的数据按之前的方法展开为一列,再左乘 P k P_{k} Pk,即可得到需要的主成分数据,然后在和原始数据Y进行逐列比较,数据最相近者,则认为是同一组,最后得到人脸识别结果如图2所示。
Fig2.人脸识别结果
在实际过程中,主成分选取并不是越高越好,即 k k k值选择并不是越多越好,我们对本例计算中正确识别率和选取 k k k的大小关系进行分析,从图3中可以看出,当主成分比例选取占80%~90%时,其识别正确率最高,而当 k k k值再继续增加后,正确率又有所下降。由此可以反应出第6节中特征脸排序越靠后,其区分数据见的差异性能力越低。
Fig3.主成分与识别正确率关系