日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人工智能 > pytorch >内容正文

pytorch

PCA 实践 利用 PCA 算法对人脸数据集内所有人进行降维和特征提取 PCA原理解析+代码

發(fā)布時(shí)間:2023/12/18 pytorch 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 PCA 实践 利用 PCA 算法对人脸数据集内所有人进行降维和特征提取 PCA原理解析+代码 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

數(shù)據(jù)集


實(shí)驗(yàn)所用到的數(shù)據(jù)集在下面的鏈接中, 這些數(shù)據(jù)是來自劍橋大學(xué)提供的 AT&T 人臉數(shù)據(jù)
集,有 40 個(gè)人的人臉圖像, 每個(gè)人有 10 張不同光照和姿態(tài)的照片。


樣例:

地址: http://www.cl.cam.ac.uk/Research/DTG/attarchive/pub/data/att_faces.tar.Z


實(shí)驗(yàn)內(nèi)容


加載數(shù)據(jù)集,利用 PCA 算法對(duì)數(shù)據(jù)集內(nèi)所有人進(jìn)行降維和特征提取,然后將得到的主
成分特征向量還原成圖像進(jìn)行觀察。這里可以嘗試采用不同的降維維度 K 進(jìn)行操作,分別觀
察不同 K 下的特征圖像。


實(shí)驗(yàn)拓展


嘗試對(duì)剛降維的特征圖像進(jìn)行 PCA 逆變換,觀察變換前后的圖像差異

?

  • 實(shí)驗(yàn)步驟與內(nèi)容:
  • 分析數(shù)據(jù)集
  • 數(shù)據(jù)集中包含了40個(gè)文件夾,對(duì)應(yīng)了40個(gè)志愿者人臉,每個(gè)文件夾中有一個(gè)志愿者的人臉的多種狀態(tài)。

  • 分析PCA原理:
  • ??假設(shè)在Rn空間中有m個(gè)點(diǎn), 我們希望對(duì)這些點(diǎn)進(jìn)行有損壓縮, 使數(shù)據(jù)的維度從Rn變?yōu)镽l, 其中嚴(yán)格的有l(wèi)<n. 這時(shí)候主成分分析法(PCA)便可以實(shí)現(xiàn)我們的要求.對(duì)于每個(gè)點(diǎn)xi∈Rn, 使得其被投影為ci∈Rl, 用函數(shù)來表示下列編碼過程即是: f(x)=DTx=c。 同時(shí), 我們也希望找到一個(gè)解碼函數(shù), 使得 g(f(x))=g(c)=Dc=DDTx≈x′其中D是一個(gè)列向量彼此正交的Rn?lRn?l矩陣. PCA有兩種推導(dǎo)過程, 但它們的結(jié)論是一樣的。
  • ??PCA的兩種推導(dǎo)過程:1.最大方差理論;2.最小誤差理論;
  • ??PCA算法步驟:
  • 關(guān)于方差和協(xié)方差
  • 協(xié)方差矩陣
  • ??????

  • 讀取并處理數(shù)據(jù)集
  • 此處使用相對(duì)目錄,依次訪問每個(gè)子文件夾,通過在中間過程中輸出圖像的維度,我們觀察到圖像是112x92x3即,長寬分別為112,93,通道數(shù)為3。首先,我們先對(duì)圖像進(jìn)行灰度化處理,然后將圖像維度展開成為一列,存入列表。

  • 圖像顯示測(cè)試
  • 圖像的height,width=112,92,X代表我們的數(shù)據(jù)集,是一個(gè)400x10304的向量;之所以是400x10304,是因?yàn)榭偣?00幅圖像,每個(gè)圖像是一個(gè)112x92的image,將圖像展開成一個(gè)一維向量,維度為1x10304,將400幅圖像組合得到一個(gè)400x10304的矩陣。其中Y是數(shù)據(jù)的標(biāo)簽。

    此處,我們展示試著顯示一組圖像,在文件夾中選取每個(gè)子文件夾下的第一個(gè)圖像拼合顯示如下:

    因?yàn)榇翱诖笮∠拗?#xff0c;此處并沒有顯示完全40副圖像。

  • 計(jì)算平均臉
  • 其中,對(duì)10304個(gè)列向量做平均,即對(duì)400個(gè)人臉圖像的每一個(gè)對(duì)應(yīng)像素值做平均,計(jì)算均值,得到一個(gè)1x10304的向量。并將該向量重新轉(zhuǎn)化為和原圖像同樣大小的維度,然后顯示出來,如下:

  • 數(shù)據(jù)中心化,并進(jìn)行奇異值分解
  • 注意,計(jì)算協(xié)方差矩陣之前,需要先將每個(gè)變量減去均值,得到中心化的向量,然后通過使用sklearn中的奇異值分解函數(shù),得到前K個(gè)特征向量。

  • 之所以使用奇異值分解而不是協(xié)方差矩陣的特征值分解,是因?yàn)槿缦略?#xff1a;
  • 不需要計(jì)算協(xié)方差矩陣S,同時(shí),在數(shù)值上更加精確,因?yàn)樵谟?jì)算機(jī)存儲(chǔ)中,可能會(huì)產(chǎn)生累計(jì)誤差。

  • K值的確定:
  • 我們?cè)O(shè)定閾值為0.95,計(jì)算保留的主成分?jǐn)?shù)量。計(jì)算代碼如下:

    計(jì)算得到的K值為111,也就是說,前111個(gè)奇異值得到的結(jié)果已經(jīng)能代表90%的情況了,為方便處理,我們此處選取K=100.通過奇異值分解得到Kx10304的變換矩陣,我們可以得到如下十張主成分圖像:

    注意:如果使用OpenCV中的imshow函數(shù)進(jìn)行顯示,需要先將數(shù)據(jù)轉(zhuǎn)換為np.unit8格式,同時(shí)范圍規(guī)范化到0-255的范圍(此處使用最大最小值歸一化),而使用matplotlib則不用進(jìn)行如此操作。

    ?

    規(guī)范化及使用OpenCV顯示相關(guān)代碼

    使用matplotlib顯示相關(guān)代碼:

  • 圖像還原:
  • 當(dāng)完成主成分提取之后,我們對(duì)圖像進(jìn)行還原:

    其中,U是變換矩陣,還原方式如下:

    ?????

    ????? 并輸出30張還原之后的圖像;如下:

    ???????? 我們可以看到,以上30張圖像分別對(duì)應(yīng)了原始數(shù)據(jù)集中的3個(gè)人的圖像,相比于原來的30張,如今還原得到的圖像丟失了一部分信息,不過不是非常明顯。

    源代碼

    1. import cv2 2. import tensorflow as tf 3. import numpy as np 4. import matplotlib.pyplot as plt 5. from sklearn.decomposition import TruncatedSVD 6. 7. FACE_PATH = "orl_faces" 8. PERSON_NUM = 40 9. PERSON_FACE_NUM = 10 10. K = 10 # Number of principle components 11. 12. raw_img = [] 13. data_set = [] 14. data_set_label = [] 15. 16. 17. def read_data(): 18. height = 0 19. width = 0 20. for i in range(1, PERSON_NUM + 1): 21. person_path = FACE_PATH + '/s' + str(i) 22. 23. for j in range(1, PERSON_FACE_NUM + 1): 24. img = cv2.imread(person_path + '/' + str(j) + '.pgm') 25. #print(img.shape) 112,92,3 26. if j == 1: 27. raw_img.append(img) 28. img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 29. height, width = img_gray.shape 30. #print(height,width) 31. img_col = img_gray.reshape(height * width) 32. data_set.append(img_col) 33. data_set_label.append(i) 34. 35. return height, width 36. 37. 38. # Import Data 39. height, width = read_data() 40. print(height,width) 41. X = np.array(data_set) 42. #print(X.shape) # 400*10304 43. Y = np.array(data_set_label) 44. #print(Y.shape) 45. n_sample, n_feature = X.shape 46. 47. # Print some samples 48. raw_img = np.hstack(raw_img) 49. cv2.namedWindow("Image") 50. cv2.imshow('Image', raw_img) 51. cv2.waitKey(1) 52. cv2.destroyAllWindows() 53. 54. # 計(jì)算均值 A preview of average_face 55. average_face = np.mean(X, axis=0) #對(duì)10304個(gè)列向量做平均 56. # for i in average_face: 57. # print(i) 58. #num+=1 59. fig = plt.figure() 60. plt.imshow(average_face.reshape((height, width)), cmap=plt.cm.gray) 61. plt.title("Average Face", size=12) 62. plt.xticks(()) 63. plt.yticks(())#不顯示橫縱坐標(biāo) 64. #plt.savefig("average_face.png") 65. plt.show() 66. 67. # Calculate 68. equalization_X = X - average_face #差值400*10304 69. #計(jì)算協(xié)方差矩陣 70. 71. covariance_X = np.cov(equalization_X.transpose()) 72. print(covariance_X.shape) 73. print(equalization_X.shape) 74. #特征值分解 使用sklearn中的SVD函數(shù)分解 75. svd = TruncatedSVD(n_components=K, random_state=44) 76. svd.fit(equalization_X) 77. 78. # total_variance, n_components = 0.0, 0 79. # for variance in svd.explained_variance_ratio_: 80. # total_variance += variance 81. # n_components += 1 82. # if total_variance > 0.95: break 83. 84. #print(n_components) 9 85. #print(svd.components_.shape) 10*10304 86. print(svd.components_.shape) 87. topk=np.zeros(svd.components_.shape) 88. # for i in range(K): 89. # #print(svd.components_[i]) 90. # topk[i]=255.0*(svd.components_[i]-np.min(svd.components_[i]))/\ 91. # (np.max(svd.components_[i])-np.min(svd.components_[i])) 92. #print(topk[i]) 93. # img=topk[1].reshape(height, width) 94. # img=img.astype(np.uint8) 95. # #print(img.shape) 96. # cv2.imshow('1',img) 97. # cv2.waitKey(0) 98. # cv2.destroyAllWindows() 99. #np.matmul(equalization_X,) 100. # topk=svd.components_+average_face 101. 102. 103. # 打印輸出前K個(gè)主成分臉 104. 105. plt.figure() 106. for i in range(1, K + 1): 107. plt.subplot(2, K/2, i) 108. #print(svd.components_[i-1].shape) 109. plt.imshow((svd.components_[i - 1]).reshape(height, width), cmap=plt.cm.gray) 110. #print(svd.components_[i - 1].reshape(height, width)) 111. plt.xticks(()) 112. plt.yticks(()) 113. plt.show() 114. 115. topk=average_face+np.matmul(equalization_X,np.matmul(svd.components_.T,svd.components_)) 116. print(topk.shape) 117. K=30 118. plt.figure() 119. for i in range(1, K + 1): 120. plt.subplot(5, K/5, i) 121. #print(svd.components_[i-1].shape) 122. plt.imshow((topk[i - 1]).reshape(height, width), cmap=plt.cm.gray) 123. #print(svd.components_[i - 1].reshape(height, width)) 124. plt.xticks(()) 125. plt.yticks(()) 126. plt.show()

    如不知道如何去掉行號(hào),參考個(gè)人博文中的解決方案。

    總結(jié)

    以上是生活随笔為你收集整理的PCA 实践 利用 PCA 算法对人脸数据集内所有人进行降维和特征提取 PCA原理解析+代码的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。