我正在嘗試使用 sklearn 的分解.PCA 函式:
輸入是 100 個 4096x4096x3 (RGB) 人臉影像(numpy 陣列形式(uint8),RGB,[0,255] 范圍),由 cv2 讀取
我將它們轉換為 [1,4096x4096x3] 2d 形狀,例如:
[255。128. 128. ... 255. 128. 128.]
然后我將所有這些陣列放入 sklearn 的 PCA() 中,n_components=20 以找到 20 個主要特征。
計算成功完成,但 PCA.components_ 中的所有組件都非常相似并且接近零陣列。
以下是我的所有故障排除:
1.輸入影像矩陣有大約 24% 的條目與另一個輸入影像相比具有 >10(在 [0,255] 范圍內)的差異。
pca.mean_ 很正常:它是一個看起來像輸入的陣列:
[255。128. 128. ... 255. 128. 128.]
我可以用它成功地重建人臉影像
但是,我發現所有組件都是由非常接近 0 的浮點陣列成的陣列,例如:
[[ 1.4016776e-08 4.3943277e-08 2.7873748e-08]
[ 4.1034184e-08 -1.2753417e-08 6.2264380e-09]
[-6.7606822e-09 4.9416444e-09 5.4486654e-10]
...
[-0.0000000e 00 -0.0000000e 00 -0.0000000e 00]
[-0.0000000e 00 -0.0000000e 00 -0.0000000e 00]
[-0.0000000e 00 -0.0000000e 00 -0.0000000e 00]]
實際上,它們都不> 1。
2.我厭倦了使用以下引數:
pca=PCA(n_components=20,svd_solver="randomized", whiten=True)
但結果卻是一樣的。仍然非常相似的組件。
為什么會出現這種情況以及如何解決它,感謝您的任何想法!
代碼:
from sklearn.decomposition import PCA
import numpy as np
import cv2
import os
folder_path = "./normal"
input=[]
for i in range(1, 101):
if i%10 == 0: print("loading",i,"th image")
if i == 60: continue #special case, should be skipped
image_path = folder_path f"/total_matrix_tangent {i}.png"
img = cv2.imread(image_path)
input.append(img.reshape(-1))
print("Loaded all",i,"images")
# change into numpy matrix
all_image = np.stack(input,axis=0)
# trans to 0-1 format float32!
all_image = (all_image.astype(np.float64))
### shape: #_of_imag x image_RGB_pixel_num (50331648 for normal case)
# print(all_image)
# print(all_image.shape)
# PCA, keeps 20 features
pca=PCA(n_components=20)
pca.fit_transform(all_image)
print("finished PCA")
result=pca.components_
print("PCA mean:",pca.mean_)
result=result.reshape(-1,4096,4096,3)
# result shape: #_of_componets * 4096 * 4096 * 3
# print(result.shape)
dst=result/np.linalg.norm(result,axis=(3),keepdims=True)
saving_path = "./principle64"
for i in range(20):
reconImage=(dst)[i]
cv2.imwrite(os.path.join(saving_path,("p" str(i) ".png")),reconImage)
print("Saved",i 1,"principle imgs")
uj5u.com熱心網友回復:
pca.components_不是轉換后的輸入串列 - 它是將保留的主要組件的數量,在您的情況下為 20。
要獲得降維影像,您需要使用transformorfit_transform方法:
# PCA, keeps 20 features
pca = PCA(n_components=20)
# Transform all_image
result = pca.fit_transform(all_image)
# result shape: num_of_images, 20
注意,變換會將維度數從 4096 4096 3 減少到 20,所以后面的reshape操作沒有意義,不會起作用。
如果您想嘗試使用保留的資訊重建原始影像,您可以呼叫inverse_transform,即
reconImages = pca.inverse_transform(result)
# reconImages shape: num_of_images, 4096 * 4096 * 3
reconImages = reconImages.reshape(-1, 4096, 4096, 3)
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/462690.html
