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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人工智能 > pytorch >内容正文

pytorch

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

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

數據集


實驗所用到的數據集在下面的鏈接中, 這些數據是來自劍橋大學提供的 AT&T 人臉數據
集,有 40 個人的人臉圖像, 每個人有 10 張不同光照和姿態的照片。


樣例:

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


實驗內容


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


實驗拓展


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

?

  • 實驗步驟與內容:
  • 分析數據集
  • 數據集中包含了40個文件夾,對應了40個志愿者人臉,每個文件夾中有一個志愿者的人臉的多種狀態。

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

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

  • 圖像顯示測試
  • 圖像的height,width=112,92,X代表我們的數據集,是一個400x10304的向量;之所以是400x10304,是因為總共400幅圖像,每個圖像是一個112x92的image,將圖像展開成一個一維向量,維度為1x10304,將400幅圖像組合得到一個400x10304的矩陣。其中Y是數據的標簽。

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

    因為窗口大小限制,此處并沒有顯示完全40副圖像。

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

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

  • 之所以使用奇異值分解而不是協方差矩陣的特征值分解,是因為如下原因:
  • 不需要計算協方差矩陣S,同時,在數值上更加精確,因為在計算機存儲中,可能會產生累計誤差。

  • K值的確定:
  • 我們設定閾值為0.95,計算保留的主成分數量。計算代碼如下:

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

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

    ?

    規范化及使用OpenCV顯示相關代碼

    使用matplotlib顯示相關代碼:

  • 圖像還原:
  • 當完成主成分提取之后,我們對圖像進行還原:

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

    ?????

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

    ???????? 我們可以看到,以上30張圖像分別對應了原始數據集中的3個人的圖像,相比于原來的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. # 計算均值 A preview of average_face 55. average_face = np.mean(X, axis=0) #對10304個列向量做平均 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(())#不顯示橫縱坐標 64. #plt.savefig("average_face.png") 65. plt.show() 66. 67. # Calculate 68. equalization_X = X - average_face #差值400*10304 69. #計算協方差矩陣 70. 71. covariance_X = np.cov(equalization_X.transpose()) 72. print(covariance_X.shape) 73. print(equalization_X.shape) 74. #特征值分解 使用sklearn中的SVD函數分解 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個主成分臉 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()

    如不知道如何去掉行號,參考個人博文中的解決方案。

    總結

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

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。