簡體   English   中英

MNIST Python numpy特征向量可視化錯誤

[英]MNIST Python numpy eigen vectors visualization error

我試圖在MNIST數據集上執行PCA,作為該過程的一部分,我需要生成特征向量並可視化主要特征。 以下是我的算法:

  1. 載入圖片
  2. 減去均值
  3. 產生協方差矩陣
  4. 推導特征向量和特征值

這是一個非常簡單的算法。 我的首要任務是將前10個特征向量可視化為圖像。 以下是到目前為止的代碼:

__author__      =   "Ajay Krishna Teja Kavuri"


import numpy as np 
import random
from mnist import MNIST
import matplotlib.pylab as plt

class PCAMNIST:


    #Initialization
    def __init__(self):
        #Load MNIST datset
        mnistData = MNIST('./mnistData')
        self.imgTrain,self.lblTrain=mnistData.load_training()
        self.imgTrainSmpl=self.imgTrain[:60000]
        np.seterr(all='warn')


    #1. Subtract the mean because the PCA will work better
    def subMean(self):
        try:
            self.sumImg = np.empty([784,])
            #calculate the sum
            for img in self.imgTrainSmpl:
                imgArr = np.asarray(img)
                self.sumImg = np.add(imgArr,self.sumImg)

            #Calculate the mean array
            self.meanImg = self.sumImg/(len(self.imgTrainSmpl))
            self.meanImg = np.nan_to_num(self.meanImg)

            #subtract it out
            index=0
            for img in self.imgTrainSmpl:
                imgArr = np.asarray(img)
                self.imgTrainSmpl[index] = np.subtract(imgArr,self.meanImg).tolist()
                index += 1

            #for img in self.imgTrainSmpl:
                #print img
        except:
            print Exception 


    #2. get the covaraince matrix for each digit
    def getCov(self):
        self.imgCov=[]
        dgtArr = np.asarray(self.imgTrainSmpl).T
        dgtCov = np.cov(dgtArr)
        self.imgCov.append(dgtCov)
        #for img in self.imgCov:
            #print img

    #3. get the eigen vectors from the covariance matrix
    def getEigen(self):
        self.eigVec=[]
        self.eigVal=[]
        dgtArr = np.asarray(self.imgCov)
        tmpEigVal,tmpEigVec=np.linalg.eig(dgtArr)
        self.eigVal.append(tmpEigVal.tolist())
        self.eigVec.append(tmpEigVec.tolist())

        #print "\nEigen values:\n"
        #for img in self.eigVal:
            #print img

        #print "\nEigen vectors:\n"
        #for img in self.eigVec:
            #print img


    def sortEV(self):
        self.eigValArr = np.asarray(self.eigVal[0][0])
        self.eigVecArr = np.asarray(self.eigVec[0][0])
        self.srtdInd = np.argsort(np.abs(self.eigValArr))
        self.srtdEigValArr = self.eigValArr[self.srtdInd]
        self.srtdEigVecArr = self.eigVecArr[self.srtdInd]
        self.srtdEigVec = self.srtdEigVecArr.real.tolist()
        #print self.srtdEigValArr[0]
        print len(self.srtdInd.tolist())
        #print self.eigVec[self.srtdInd[0]]
        #print np.asarray(self.srtdEigVec).shape
        #for img in self.srtdEigVecArr:
            #print img
        #self.drawEig()

    def plotVal(self):
        """
        plt.figure()
        plt.scatter(np.asarray(self.eigVal).real)
        plt.show()
        """

    def drawEig(self):
        for vec in self.srtdEigVec[:10]:
            self.drawEigV(vec)


    def drawEigV(self,digit):
        plt.figure()
        fig=plt.imshow(np.asarray(digit).reshape(28,28),origin='upper')
        fig.set_cmap('gray_r')
        fig.axes.get_xaxis().set_visible(False)
        fig.axes.get_yaxis().set_visible(False)
        plt.savefig(str(random.randint(0,10000))+".png")
        #plt.show()
        plt.close()



    def drawChar(self,digit):
        plt.figure()
        fig=plt.imshow(np.asarray(digit).reshape(28,28),clim=(-1,1.0),origin='upper')
        fig.set_cmap('gray_r')
        fig.axes.get_xaxis().set_visible(False)
        fig.axes.get_yaxis().set_visible(False)
        plt.show()
        plt.close()


    def drawSmpl(self):
        for img in self.imgTrainSmpl:
            self.drawChar(img) 


    def singleStep(self):
        self.val, self.vec = np.linalg.eig(np.cov(np.array(self.imgTrainSmpl).transpose()))
        self.srtd = np.argsort(self.val)[::-1]
        print self.val


#asnmnt4=PCAMNIST()
#asnmnt4.singleStep()
asnmnt4=PCAMNIST()
asnmnt4.subMean()
asnmnt4.getCov()
asnmnt4.getEigen()
asnmnt4.sortEV()
asnmnt4.drawEig()
#asnmnt4.plotVal()
"""
asnmnt4.getSorted()
asnmnt4.printTopEigenVal()
"""

盡管以上代碼可以完美運行,並且所有數組大小均與給定的數據集匹配,但它會生成以下圖像和特征向量: 特征向量作為圖像

顯然,特征向量毫無意義,因為它們必須表示數據集的特征,在這種情況下,特征應為數字。 任何幫助表示贊賞。 如果您嘗試運行此代碼,則可能必須安裝MNIST軟件包並從鏈接下載數據。

您正在繪制特征向量矩陣的 特征向量在矩陣的中,如您在np.linalg.eig文檔np.linalg.eig

你應該改變

self.eigVec.append(tmpEigVec.tolist())

self.eigVec.append(np.transpose(tmpEigVec).tolist())

我相信它將按預期工作。

正如一些用戶指出的那樣,問題在於特征向量可以使其工作而不是更改附加邏輯,只需將draw函數修改為:

def drawEig(self):
        for vec in self.srtdEigVecArr.T[:10]:
            self.drawEigV(vec)

現在,特征向量有意義: 在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM