寫在最前面
主成分分析(PCA,Principal Component Analysis)是一項(xiàng)在高維數(shù)據(jù)中,尋找最重要特征的降維技術(shù),大大減少數(shù)據(jù)的維度,而不顯著損失信息量。
本文將通過實(shí)際的 Paddle 代碼示例,來展示所提供的高效、靈活的線性代數(shù)API,如何簡化了機(jī)器學(xué)習(xí)和深度學(xué)習(xí)中的數(shù)據(jù)處理和分析工作,為高維數(shù)據(jù)集的處理和分析提供了有效工具。
將從以下兩個(gè)板塊展開介紹。
- PCA的算法原理:介紹PCA的數(shù)學(xué)基礎(chǔ),如何從線性代數(shù)的角度理解PCA,以及PCA算法的步驟。
- PCA在人臉識別中的應(yīng)用:探索Paddle中PCA如何在人臉識別技術(shù)中使用,包括多個(gè)線性代數(shù)計(jì)算 API ,更好地支持科學(xué)計(jì)算類模型。
完整代碼及數(shù)據(jù)集可見:https://github.com/lightrain-a/PCA-face-recognition
一、PCA線性代數(shù)基礎(chǔ)
1. PCA的算法原理
PCA的算法原理基于線性代數(shù)和統(tǒng)計(jì)學(xué),旨在將原始的數(shù)據(jù)通過線性變換映射到一個(gè)新的坐標(biāo)系統(tǒng)中,新坐標(biāo)系的基是原始數(shù)據(jù)集的正交特征向量。這些新的坐標(biāo)軸被稱為主成分,它們按照能夠解釋原始數(shù)據(jù)集方差的大小排序。
2. PCA的線性代數(shù)基礎(chǔ)
要理解PCA,首先需要掌握一些線性代數(shù)的數(shù)學(xué)概念,這是進(jìn)行PCA分析的基礎(chǔ):
- 標(biāo)準(zhǔn)差(Standard Deviation)、方差(Variance)、協(xié)方差(Covariance)、特征向量(eigenvectors)、特征值(eigenvalues)
下面介紹PCA的線性代數(shù)基礎(chǔ),理解標(biāo)準(zhǔn)差、方差、協(xié)方差以及特征向量和特征值的概念,更好地掌握PCA的理論基礎(chǔ)。
2.1 標(biāo)準(zhǔn)差 Standard Deviation
標(biāo)準(zhǔn)差是衡量數(shù)據(jù)分散程度的一個(gè)重要指標(biāo),它描述了數(shù)據(jù)點(diǎn)與數(shù)據(jù)集平均值的偏離程度。標(biāo)準(zhǔn)差越大,表示數(shù)據(jù)分布越分散;標(biāo)準(zhǔn)差越小,表示數(shù)據(jù)分布越集中。標(biāo)準(zhǔn)差的數(shù)學(xué)表達(dá)式為:
σ = 1 N ∑ i = 1 N ( x i ? μ ) 2 \sigma = \sqrt{\frac{1}{N} \sum_{i=1}^{N} (x_i - \mu)^2} σ=N1?i=1∑N?(xi??μ)2?
其中, σ \sigma σ是標(biāo)準(zhǔn)差, N N N是樣本數(shù)量, x i x_i xi?是每個(gè)樣本點(diǎn),而 μ \mu μ是樣本的平均值。當(dāng)數(shù)據(jù)集是總體時(shí),分母使用 N N N;當(dāng)數(shù)據(jù)集是樣本時(shí),為了得到無偏估計(jì),分母使用 N ? 1 N-1 N?1。
2.2 方差 Variance
方差是衡量數(shù)據(jù)分散程度的另一個(gè)核心概念,它與標(biāo)準(zhǔn)差緊密相關(guān),實(shí)際上,方差就是標(biāo)準(zhǔn)差的平方。方差給出了數(shù)據(jù)分布的平均偏差(距平均值的距離)的平方,用于描述數(shù)據(jù)的波動性。方差的數(shù)學(xué)表達(dá)式為:
Var ( X ) = 1 N ∑ i = 1 N ( x i ? μ ) 2 \text{Var}(X) = \frac{1}{N} \sum_{i=1}^{N} (x_i - \mu)^2 Var(X)=N1?i=1∑N?(xi??μ)2
這里, Var ( X ) \text{Var}(X) Var(X)表示方差,其余符號含義與標(biāo)準(zhǔn)差中相同。
2.3 協(xié)方差 Covariance
協(xié)方差是衡量兩個(gè)變量之間線性關(guān)系強(qiáng)度及方向的統(tǒng)計(jì)量。正協(xié)方差表示兩個(gè)變量同時(shí)增加或減少,負(fù)協(xié)方差表示一個(gè)變量增加時(shí)另一個(gè)變量減少。協(xié)方差的數(shù)學(xué)表達(dá)式為:
Cov ( X , Y ) = 1 N ∑ i = 1 N ( x i ? μ x ) ( y i ? μ y ) \text{Cov}(X,Y) = \frac{1}{N} \sum_{i=1}^{N} (x_i - \mu_x)(y_i - \mu_y) Cov(X,Y)=N1?i=1∑N?(xi??μx?)(yi??μy?)
其中, X X X和 Y Y Y是兩個(gè)隨機(jī)變量, μ x \mu_x μx?和 μ y \mu_y μy?分別是 X X X和 Y Y Y的平均值。協(xié)方差的值越大,表示兩個(gè)變量之間的正線性關(guān)系越強(qiáng);值越?。ㄘ?fù)值),表示負(fù)線性關(guān)系越強(qiáng)。
2.4 協(xié)方差矩陣 The Covariance Matrix
協(xié)方差矩陣主要是用于當(dāng)數(shù)據(jù)的維度超過3或者更多的時(shí)候,我們可以通過一個(gè)矩陣來存儲各個(gè)維度的協(xié)方差,這個(gè)矩陣就被稱為“協(xié)方差矩陣”。
當(dāng)想要表示一個(gè)具有 N N N個(gè)變量的數(shù)據(jù)集的協(xié)方差矩陣時(shí),這個(gè)矩陣將包含每一對變量之間的協(xié)方差。如果有 N N N個(gè)變量,協(xié)方差矩陣將是一個(gè) N × N N \times N N×N的矩陣,其中矩陣中的元素 Cov ( X i , X j ) \text{Cov}(X_i, X_j) Cov(Xi?,Xj?)表示變量 X i X_i Xi?和 X j X_j Xj?之間的協(xié)方差。對于變量 X 1 , X 2 , … , X N X_1, X_2, \ldots, X_N X1?,X2?,…,XN?,協(xié)方差矩陣可以用下面的數(shù)學(xué)表達(dá)式表示:
Covariance?Matrix = [ Cov ( X 1 , X 1 ) Cov ( X 1 , X 2 ) ? Cov ( X 1 , X N ) Cov ( X 2 , X 1 ) Cov ( X 2 , X 2 ) ? Cov ( X 2 , X N ) ? ? ? ? Cov ( X N , X 1 ) Cov ( X N , X 2 ) ? Cov ( X N , X N ) ] \text{Covariance Matrix} = \begin{bmatrix} \text{Cov}(X_1, X_1) & \text{Cov}(X_1, X_2) & \cdots & \text{Cov}(X_1, X_N) \\ \text{Cov}(X_2, X_1) & \text{Cov}(X_2, X_2) & \cdots & \text{Cov}(X_2, X_N) \\ \vdots & \vdots & \ddots & \vdots \\ \text{Cov}(X_N, X_1) & \text{Cov}(X_N, X_2) & \cdots & \text{Cov}(X_N, X_N) \end{bmatrix} Covariance?Matrix= ?Cov(X1?,X1?)Cov(X2?,X1?)?Cov(XN?,X1?)?Cov(X1?,X2?)Cov(X2?,X2?)?Cov(XN?,X2?)??????Cov(X1?,XN?)Cov(X2?,XN?)?Cov(XN?,XN?)? ?
在這個(gè)矩陣中,對角線上的元素 Cov ( X i , X i ) \text{Cov}(X_i, X_i) Cov(Xi?,Xi?)表示變量 X i X_i Xi?與其自身的協(xié)方差,這實(shí)際上就是變量 X i X_i Xi?的方差。而非對角線上的元素則表示不同變量之間的協(xié)方差,用于衡量這些變量之間的線性關(guān)系。這個(gè)協(xié)方差矩陣提供了一個(gè)全面的視角來觀察數(shù)據(jù)集中所有變量之間的關(guān)系,是進(jìn)行多變量統(tǒng)計(jì)分析時(shí)不可或缺的工具。
假設(shè)有一個(gè)包含三個(gè)維度(X, Y, Z)的數(shù)據(jù)集,那么這個(gè)數(shù)據(jù)集的協(xié)方差矩陣可以表示為:
Covariance?Matrix = [ Cov ( X , X ) Cov ( X , Y ) Cov ( X , Z ) Cov ( Y , X ) Cov ( Y , Y ) Cov ( Y , Z ) Cov ( Z , X ) Cov ( Z , Y ) Cov ( Z , Z ) ] \text{Covariance Matrix} = \begin{bmatrix} \text{Cov}(X, X) & \text{Cov}(X, Y) & \text{Cov}(X, Z) \\ \text{Cov}(Y, X) & \text{Cov}(Y, Y) & \text{Cov}(Y, Z) \\ \text{Cov}(Z, X) & \text{Cov}(Z, Y) & \text{Cov}(Z, Z) \end{bmatrix} Covariance?Matrix= ?Cov(X,X)Cov(Y,X)Cov(Z,X)?Cov(X,Y)Cov(Y,Y)Cov(Z,Y)?Cov(X,Z)Cov(Y,Z)Cov(Z,Z)? ?
在這個(gè)矩陣中:
- 對角線上的元素( Cov ( X , X ) \text{Cov}(X, X) Cov(X,X), Cov ( Y , Y ) \text{Cov}(Y, Y) Cov(Y,Y), Cov ( Z , Z ) \text{Cov}(Z, Z) Cov(Z,Z))分別表示每個(gè)維度與自身的協(xié)方差,實(shí)際上就是該維度的方差。
- 非對角線上的元素(如 Cov ( X , Y ) \text{Cov}(X, Y) Cov(X,Y), Cov ( Y , Z ) \text{Cov}(Y, Z) Cov(Y,Z)等)表示不同維度之間的協(xié)方差,用于衡量這些維度之間的線性關(guān)系。
這個(gè)協(xié)方差矩陣提供了數(shù)據(jù)集中所有變量之間關(guān)系的一個(gè)全面視圖,是進(jìn)行多維數(shù)據(jù)分析和模式識別中不可或缺的工具。特別是在主成分分析(PCA)中,通過對協(xié)方差矩陣進(jìn)行特征分解,我們可以提取出數(shù)據(jù)的主成分,從而用于降維、數(shù)據(jù)壓縮或特征提取等目的。
2.5 paddle代碼demo①:計(jì)算協(xié)方差矩陣
計(jì)算一下兩個(gè)數(shù)據(jù)的協(xié)方差矩陣:
- x : ( 10 , 39 , 19 , 23 , 28 ) x:(10,39,19,23,28) x:(10,39,19,23,28)和 y : ( 43 , 13 , 32 , 21 , 20 ) y:(43,13,32,21,20) y:(43,13,32,21,20)
- x : ( 1 , ? 1 , 4 ) x:(1, -1, 4) x:(1,?1,4)、 y : ( 2 , 1 , 3 ) y:(2, 1, 3) y:(2,1,3)和 z : ( 1 , 3 , ? 1 ) z:(1, 3, -1) z:(1,3,?1)
使用paddle.linalg模塊來計(jì)算協(xié)方差矩陣。PaddlePaddle的paddle.linalg.cov函數(shù)可以用來計(jì)算協(xié)方差矩陣。
import paddle
# 初始化數(shù)據(jù)
x1 = paddle.to_tensor([10, 39, 19, 23, 28], dtype='float32')
y1 = paddle.to_tensor([43, 13, 32, 21, 20], dtype='float32')
x2 = paddle.to_tensor([1, -1, 4], dtype='float32')
y2 = paddle.to_tensor([2, 1, 3], dtype='float32')
z2 = paddle.to_tensor([1, 3, -1], dtype='float32')
# 計(jì)算協(xié)方差矩陣
# 注意: PaddlePaddle在計(jì)算協(xié)方差矩陣時(shí),需要將數(shù)據(jù)組合成一個(gè)二維tensor,其中每行是一個(gè)變量的觀測值
cov_matrix1 = paddle.linalg.cov(paddle.stack([x1, y1], axis=0))
cov_matrix2 = paddle.linalg.cov(paddle.stack([x2, y2, z2], axis=0))
print("協(xié)方差矩陣1:")
print(cov_matrix1.numpy())
# 協(xié)方差矩陣1:
# [[ 115.70003 -120.54999]
# [-120.54999 138.70001]]
print("\n協(xié)方差矩陣2:")
print(cov_matrix2.numpy())
# 協(xié)方差矩陣2:
# [[ 6.333333 2.4999995 -5. ]
# [ 2.5 1. -2. ]
# [-5. -2. 4. ]]
計(jì)算兩組數(shù)據(jù)的協(xié)方差矩陣得到的結(jié)果如下:
對于數(shù)據(jù)集 x : ( 10 , 39 , 19 , 23 , 28 ) x:(10,39,19,23,28) x:(10,39,19,23,28)和 y : ( 43 , 13 , 32 , 21 , 20 ) y:(43,13,32,21,20) y:(43,13,32,21,20),協(xié)方差矩陣為:
[ 115.7 ? 120.55 ? 120.55 138.7 ] \begin{bmatrix} 115.7 & -120.55 \\ -120.55 & 138.7 \end{bmatrix} [115.7?120.55??120.55138.7?]
而對于數(shù)據(jù)集 x : ( 1 , ? 1 , 4 ) x:(1, -1, 4) x:(1,?1,4)、 y : ( 2 , 1 , 3 ) y:(2, 1, 3) y:(2,1,3)和 z : ( 1 , 3 , ? 1 ) z:(1, 3, -1) z:(1,3,?1),協(xié)方差矩陣為:
[ 6.33 2.5 ? 5 2.5 1 ? 2 ? 5 ? 2 4 ] \begin{bmatrix} 6.33 & 2.5 & -5 \\ 2.5 & 1 & -2 \\ -5 & -2 & 4 \end{bmatrix} ?6.332.5?5?2.51?2??5?24? ?
這兩個(gè)協(xié)方差矩陣分別捕獲了數(shù)據(jù)集中變量間的相互關(guān)系。在第一個(gè)矩陣中,我們可以看到 x x x和 y y y之間存在負(fù)相關(guān)關(guān)系,因?yàn)樗鼈兊膮f(xié)方差是負(fù)值。在第二個(gè)矩陣中,各變量間的正負(fù)協(xié)方差值揭示了它們之間更復(fù)雜的相互關(guān)系。
2.6 特征向量 Eigenvectors
在協(xié)方差矩陣的上下文中,特征向量和特征值揭示了數(shù)據(jù)結(jié)構(gòu)的深層次信息。通過對協(xié)方差矩陣進(jìn)行特征分解,可以找到幾個(gè)關(guān)鍵的方向,這些方向是數(shù)據(jù)方差(也就是數(shù)據(jù)的變化)最大的方向。這正是PCA方法尋找主成分的基礎(chǔ)。
特征向量的物理意義如下:
- 方差最大的方向:協(xié)方差矩陣的每個(gè)特征向量代表數(shù)據(jù)在某個(gè)特定方向上的分散程度最大。這意味著,如果你將數(shù)據(jù)點(diǎn)投影到這些特征向量上,那么投影點(diǎn)的分布將會有最大的方差,揭示了數(shù)據(jù)最重要的結(jié)構(gòu)。
- 數(shù)據(jù)的主要變化方向:特征向量指向的方向是數(shù)據(jù)變化最顯著的方向。在多維數(shù)據(jù)集中,第一個(gè)特征向量(對應(yīng)最大特征值的特征向量)指向方差最大的方向,而其他特征向量則指向其他重要的、但方差較小的方向。
- 正交性:特別是在PCA中,協(xié)方差矩陣是對稱的,所以它的特征向量是正交(或互相垂直)的。這表明了數(shù)據(jù)的不同主要變化方向是相互獨(dú)立的。
標(biāo)準(zhǔn)化處理
為了方便處理和解釋,通常需要將特征向量標(biāo)準(zhǔn)化。標(biāo)準(zhǔn)化的特征向量有一個(gè)單位長度,這使得它們在比較不同方向的重要性時(shí)處于同一尺度。標(biāo)準(zhǔn)化處理的數(shù)學(xué)表達(dá)式為:
α ^ = α ∥ α ∥ \hat{\alpha} = \frac{\alpha}{\|\alpha\|} α^=∥α∥α?
其中,
α
\alpha
α是原始的特征向量,
∥
α
∥
\|\alpha\|
∥α∥是特征向量的模長(也就是它的L2范數(shù)
),而
α
^
\hat{\alpha}
α^是標(biāo)準(zhǔn)化后的特征向量。
這種標(biāo)準(zhǔn)化處理確保了特征向量的長度為1,使得特征向量只表示方向,而不受其原始長度的影響。在PCA分析中,這有助于集中關(guān)注數(shù)據(jù)變化的方向,而不是特征向量的具體大小。
2.7 paddle代碼demo②:計(jì)算特征值和特征向量
代碼實(shí)現(xiàn):計(jì)算一個(gè)二維數(shù)據(jù)的協(xié)方差矩陣以及該協(xié)方差矩陣的特征值和特征向量。
步驟如下:
- 計(jì)算x維和y維數(shù)據(jù)的平均值。
- 使用原始數(shù)據(jù)減去相應(yīng)的平均值,得到更新后的數(shù)據(jù)。
- 使用飛槳計(jì)算協(xié)方差矩陣。
- 計(jì)算協(xié)方差矩陣的特征值和特征向量。
以下是相應(yīng)的PaddlePaddle代碼示例:
import paddle
# 初始化數(shù)據(jù)
x = paddle.to_tensor([2.5, 0.5, 2.2, 1.9, 3.1, 2.3, 2, 1, 1.5, 1.1], dtype='float32')
y = paddle.to_tensor([2.4, 0.7, 2.9, 2.2, 3.0, 2.7, 1.6, 1.1, 1.6, 0.9], dtype='float32')
# 計(jì)算平均值
means_X = paddle.mean(x)
means_Y = paddle.mean(y)
print("x 維的平均值為:", means_X.numpy())
print("y 維的平均值為:", means_Y.numpy())
# x 維的平均值為: 1.8099998
# y 維的平均值為: 1.9100001
# 更新數(shù)據(jù),減去平均值
update_x = x - means_X
update_y = y - means_Y
# 合并更新后的數(shù)據(jù)
c = paddle.stack((update_x, update_y), axis=0)
# 計(jì)算協(xié)方差矩陣
cov_c = paddle.linalg.cov(c)
print("協(xié)方差矩陣為:", cov_c.numpy())
# 協(xié)方差矩陣為: [[0.6165555 0.6154444]
# [0.6154444 0.7165556]]
# 計(jì)算協(xié)方差矩陣的特征值和特征向量
eigenvalues, eigenvectors = paddle.linalg.eig(cov_c)
print("該協(xié)方差矩陣的特征值為:", eigenvalues.numpy())
print("該協(xié)方差矩陣的特征向量為:", eigenvectors.numpy())
# 該協(xié)方差矩陣的特征值為: [0.04908335+0.j 1.2840276 +0.j]
# 該協(xié)方差矩陣的特征向量為: [[-0.73517877+0.j -0.6778734 +0.j]
# [ 0.6778734 +0.j -0.73517877+0.j]]
請注意,在使用paddle.linalg.eig
函數(shù)計(jì)算特征值和特征向量時(shí),得到的結(jié)果是復(fù)數(shù)形式的,這是因?yàn)樵跀?shù)學(xué)上特征值和特征向量可能是復(fù)數(shù)。在實(shí)際應(yīng)用中,特別是在PCA中,協(xié)方差矩陣是實(shí)對稱矩陣,其特征值和特征向量應(yīng)該是實(shí)數(shù)。如果你得到復(fù)數(shù)結(jié)果,它們的虛部通常應(yīng)該非常接近于零,可以根據(jù)實(shí)際情況忽略。
2.8 選擇主成分并生成特征向量 Choosing components and forming a feature vector
在進(jìn)行PCA分析時(shí),選擇主成分(即特征向量)并形成特征向量是決定性的步驟,它直接影響到降維后數(shù)據(jù)的質(zhì)量。
選擇主成分的過程基于特征值的大小。特征值較大的特征向量對應(yīng)的方向上,數(shù)據(jù)的方差較大,這意味著數(shù)據(jù)在這個(gè)方向上有更多的信息量。因此,選擇特征值較大的特征向量作為主成分,可以保留數(shù)據(jù)最重要的信息。具體步驟如下:
- 特征值排序:將所有特征值按照大小降序排列。這樣,最大的特征值會排在最前面,對應(yīng)的特征向量代表了數(shù)據(jù)集中最主要的方差方向。
- 選擇主成分?jǐn)?shù)量:確定要保留的主成分?jǐn)?shù)量。這通?;谔卣髦档睦塾?jì)貢獻(xiàn)率,即前 k k k個(gè)最大特征值之和占所有特征值之和的比例。一種常見的選擇方法是保留累計(jì)貢獻(xiàn)率達(dá)到某個(gè)閾值(如85%、90%)的特征向量。
- 形成特征向量:根據(jù)選定的主成分?jǐn)?shù)量,從排序后的特征向量集合中選擇前 k k k個(gè)特征向量。這些特征向量構(gòu)成了降維后數(shù)據(jù)的新基。
2.9 通過選擇特征向量生成新的數(shù)據(jù)集 Deriving the New Data Set
生成新的數(shù)據(jù)集,即完成數(shù)據(jù)的降維,涉及以下關(guān)鍵步驟:
-
數(shù)據(jù)標(biāo)準(zhǔn)化:首先對原始數(shù)據(jù)集 X X X進(jìn)行標(biāo)準(zhǔn)化處理,以確保每個(gè)維度的均值為0。對于由維度 x x x和 y y y組成的數(shù)據(jù)集,標(biāo)準(zhǔn)化的表達(dá)式為:
rowdataAdjust = [ x 1 ? μ x x 2 ? μ x ? x n ? μ x y 1 ? μ y y 2 ? μ y ? y n ? μ y ] T \text{rowdataAdjust} = \begin{bmatrix} x_1 - \mu_x & x_2 - \mu_x & \cdots & x_n - \mu_x \\ y_1 - \mu_y & y_2 - \mu_y & \cdots & y_n - \mu_y \end{bmatrix}^T rowdataAdjust=[x1??μx?y1??μy??x2??μx?y2??μy?????xn??μx?yn??μy??]T
其中, μ x \mu_x μx?和 μ y \mu_y μy?分別代表 x x x和 y y y維度的平均值。
-
特征向量選擇與構(gòu)造:根據(jù)主成分分析(PCA)確定主要成分,并選取對應(yīng)的特征向量。如果選擇了前 P P P個(gè)主成分,則構(gòu)造特征向量矩陣 W W W:
W = [ v ? 1 , v ? 2 , … , v ? p ] W = [\vec{v}_1, \vec{v}_2, \ldots, \vec{v}_p] W=[v1?,v2?,…,vp?]
其中, v ? i \vec{v}_i vi?代表第 i i i個(gè)特征向量。
-
降維:通過將標(biāo)準(zhǔn)化后的數(shù)據(jù)矩陣與特征向量矩陣相乘,計(jì)算降維后的數(shù)據(jù)集 Y Y Y:
FinalData = rowdataAdjust ? W \text{FinalData} = \text{rowdataAdjust} \cdot W FinalData=rowdataAdjust?W
這里, FinalData \text{FinalData} FinalData是降維后的數(shù)據(jù)集,其中每一行代表原始數(shù)據(jù)點(diǎn)在新的特征空間中的坐標(biāo)。
通過這個(gè)過程,原始的高維數(shù)據(jù)被有效地映射到了一個(gè)低維空間,同時(shí)盡可能保留了數(shù)據(jù)中最重要的結(jié)構(gòu)信息。這種方法在數(shù)據(jù)壓縮、特征提取、以及數(shù)據(jù)可視化等方面非常有用,能夠幫助我們更好地理解和分析數(shù)據(jù)集的本質(zhì)特性。
二、【基于Paddle實(shí)現(xiàn)】PCA的人臉識別算法
1. 數(shù)據(jù)集
本文使用的是ORL官方數(shù)據(jù)集,可以從一下網(wǎng)址下載到ORL下載鏈接
該數(shù)據(jù)集表示的是一共有40個(gè)人的人臉圖像,其中每一個(gè)人有10張人臉圖像。相應(yīng)的PGM文件為說明。
2. 安裝庫
安裝cv2的庫:
pip install opencv-python
安裝paddle的庫:(cpu版本的即可)
pip install paddle
3. paddle代碼相關(guān)函數(shù)的實(shí)現(xiàn)
首先定義一個(gè)函數(shù)用于將人臉圖像矢量化為一個(gè)向量,向量的大小與圖片的像素有關(guān),代碼如下:
# 圖片矢量化
def img2vector(self, image):
img = cv2.imread(image, 0) # 讀取圖片
imgVector = paddle.reshape(paddle.to_tensor(img, dtype='float32'), [1, -1]) # 重塑為1行多列
return imgVector
接下來定義一個(gè)函數(shù)用來選取訓(xùn)練圖片,并對每張圖片進(jìn)行前面定義過的矢量化處理
# 讀入人臉庫,每個(gè)人選擇k張作為訓(xùn)練樣本,剩下的作為測試樣本
def load_orl(self):
'''
對訓(xùn)練數(shù)據(jù)集進(jìn)行數(shù)組初始化,用0填充,每張圖片尺寸都定為112*92,
現(xiàn)在共有40個(gè)人,每個(gè)人都選擇k張,則整個(gè)訓(xùn)練集大小為40*k,112*92
'''
train_images = []
train_labels = []
test_images = []
test_labels = []
sample = np.random.permutation(10) + 1 # 生成隨機(jī)序列
for i in range(40): # 共有40個(gè)人
people_num = i + 1
for j in range(10): # 每人10張照片
image_path = os.path.join(self.data_path, 's' + str(people_num), str(sample[j]) + '.jpg')
img = self.img2vector(image_path) # 讀取圖片并進(jìn)行矢量化
if j < self.k: # 構(gòu)成訓(xùn)練集
train_images.append(img)
train_labels.append(people_num)
else: # 構(gòu)成測試集
test_images.append(img)
test_labels.append(people_num)
if self.train:
return paddle.concat(train_images, axis=0), paddle.to_tensor(train_labels, dtype='int64')
else:
return paddle.concat(test_images, axis=0), paddle.to_tensor(test_labels, dtype='int64')
前期將所有訓(xùn)練圖片矢量化之后,開始進(jìn)行PCA算法的降維操作
def PCA(data, r): # 降低到r維
data = paddle.cast(data, 'float32')
rows, cols = data.shape
data_mean = paddle.mean(data, axis=0)
A = data - paddle.tile(data_mean, repeat_times=[rows, 1])
C = paddle.matmul(A, A, transpose_y=True) # 協(xié)方差矩陣
eig_vals, eig_vects = paddle.linalg.eigh(C) # 特征值和特征向量
eig_vects = paddle.matmul(A.T, eig_vects[:, :r])
for i in range(r):
eig_vects[:, i] = eig_vects[:, i] / paddle.norm(eig_vects[:, i])
final_data = paddle.matmul(A, eig_vects)
return final_data, data_mean, eig_vects
最后我們進(jìn)行初次訓(xùn)練,隨機(jī)選取每個(gè)人物的五張圖片作為訓(xùn)練圖片使用。將降低的維數(shù)設(shè)定為10維、20維、30維、40維,查看一下訓(xùn)練效果如何。
def face_recognize(data_path):
for r in range(10, 41, 10):
print(f"當(dāng)降維到{r}時(shí):")
dataset_train = ORLDataset(data_path, k=7, train=True)
dataset_test = ORLDataset(data_path, k=7, train=False)
train_data, train_labels = paddle.to_tensor(dataset_train.images), paddle.to_tensor(dataset_train.labels, dtype='int64')
test_data, test_labels = paddle.to_tensor(dataset_test.images), paddle.to_tensor(dataset_test.labels, dtype='int64')
data_train_new, data_mean, V_r = PCA(train_data, r)
temp_face = test_data - data_mean
data_test_new = paddle.matmul(temp_face, V_r)
true_num = 0
for i in range(len(dataset_test)):
diffMat = data_train_new - data_test_new[i]
sqDiffMat = paddle.square(diffMat)
sqDistances = paddle.sum(sqDiffMat, axis=1)
sortedDistIndices = paddle.argsort(sqDistances)
if train_labels[sortedDistIndices[0]] == test_labels[i]:
true_num += 1
accuracy = float(true_num) / len(dataset_test)
print(f'當(dāng)每個(gè)人選擇7張照片進(jìn)行訓(xùn)練時(shí),The classify accuracy is: {accuracy:.2%}')
最終訓(xùn)練得到的結(jié)果如下:
當(dāng)降維到10時(shí):
當(dāng)每個(gè)人選擇7張照片進(jìn)行訓(xùn)練時(shí),The classify accuracy is: 67.50%
當(dāng)降維到20時(shí):
當(dāng)每個(gè)人選擇7張照片進(jìn)行訓(xùn)練時(shí),The classify accuracy is: 35.00%
當(dāng)降維到30時(shí):
當(dāng)每個(gè)人選擇7張照片進(jìn)行訓(xùn)練時(shí),The classify accuracy is: 67.50%
當(dāng)降維到40時(shí):
當(dāng)每個(gè)人選擇7張照片進(jìn)行訓(xùn)練時(shí),The classify accuracy is: 40.00%
三、小結(jié)
PaddlePaddle的paddle.linalg
API為進(jìn)行數(shù)據(jù)降維和特征提取提供了強(qiáng)大的支持,這對于機(jī)器學(xué)習(xí)和深度學(xué)習(xí)應(yīng)用來說是非常重要的。特別是,paddle.linalg.eig
和paddle.linalg.svd
函數(shù)允許用戶有效地計(jì)算數(shù)據(jù)的特征值和特征向量,這是執(zhí)行主成分分析(PCA)和奇異值分解(SVD)等降維方法的關(guān)鍵。此外,paddle.linalg.matmul
可以用于矩陣乘法,幫助將數(shù)據(jù)從高維空間映射到低維空間,保留了數(shù)據(jù)中最重要的信息。
這些功能的廣泛應(yīng)用不僅限于PCA相關(guān)的任務(wù),還包括數(shù)據(jù)壓縮、特征選擇和提高學(xué)習(xí)算法的效率等領(lǐng)域。通過降維,可以顯著減少模型訓(xùn)練的計(jì)算資源需求,提高模型的泛化能力,減少過擬合的風(fēng)險(xiǎn)。PaddlePaddle通過提供這些高效、靈活的線性代數(shù)API,極大地簡化了機(jī)器學(xué)習(xí)和深度學(xué)習(xí)中的數(shù)據(jù)處理和分析工作,為高維數(shù)據(jù)集的處理和分析提供了有效工具。文章來源:http://www.zghlxwxcb.cn/news/detail-860682.html
四、參考文獻(xiàn)
- 官網(wǎng) paddle.linalg API 目錄
- PCA-Principal-Components-Analysis
歡迎大家添加好友,持續(xù)發(fā)放粉絲福利!文章來源地址http://www.zghlxwxcb.cn/news/detail-860682.html

到了這里,關(guān)于【Paddle】PCA線性代數(shù)基礎(chǔ) + 領(lǐng)域應(yīng)用:人臉識別算法(1.1w字超詳細(xì):附公式、代碼)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!