Using LDA as a features reduction method

asked 2019-09-12 07:07:32 -0600

amirps gravatar image

I have a dataset of X_thousands images (60 classes )and I'm trying to classify them using an unsupervised method, I use some *functions to extract features from these images, finally I have a log file containing 800 columns and X_thousands rows representing my images features, currently I'm using PCA to reduce the size of the features and then cluster them using K_means, although I'm not achieving good accuracy ( around 50%) ... I'm trying to use LDA as a feature reduction algorithm instead of PCA to see if my results improve.

here is a simple class I wrote for this purpose, after loading the dataset and labels, I try to train the LDA and then save it to use later with unseen data, but when I save the LDA every vector in the .yml file is zero!

*:  The dataset is a Fine-grained image classification problem (large intra-class variance and small inter-class variance) 
**: I trained a CNN model I get the features from pool10 layer, and because of the color is very important in my case, im adding histogram of HSV channels to features also!
void LDAClass::loadDataset_Lables(fs::path logpath)
{
    vector<vector<float>> logs= parseFetureFileFloat(logpath.string()," ");
    Mat lbls(1,logs.size(),CV_64F,cv::Scalar(0.0));
    Mat dataset(logs.size(),logs[0].size()-1,CV_64F,cv::Scalar(0.0));
    for(int i=0;i<logs.size();i++)
    {
        for (int j=0;j<logs[i].size();j++)
        {

            if (j==logs[i].size()-1)
                lbls.at<float>(0,i)=logs[i][j];
            else
                dataset.at<float>(i,j)=logs[i][j];
        }
    }
    normalize(dataset, dataset, 0, 1, NORM_MINMAX, CV_64F);
    setDataset(dataset);
    setLables(lbls);
    vector<float> uq= uniqueinMat(Lables,false);
    setNoComponents(uq.size());

}
void LDAClass::setNoComponents(int n)
{
    noComponents=n;
}
LDAClass::LDAClass(fs::path logpath,int reduceSize,fs::path ldafilePath,bool train):lda(reduceSize)
{
    setReduceSize(reduceSize);
    if (train)
    {
        loadDataset_Lables(logpath.string()); 
        lda.compute(DataSet, Lables);
        lda.save(ldafilePath.string());

    }
    else
    {
        lda.load(ldafilePath.string());
    }
}

void LDAClass::setDataset(Mat dataset)
{
    DataSet=dataset.clone();
}
void  LDAClass::setReduceSize(int n )
{
    reduceSize=n;
}
void LDAClass::setLables(Mat lbls)
{
    Lables=lbls.clone();
}
void LDAClass::projectvector(Mat &fv)
{

    if (fv.rows==1)
        fv=lda.project(fv) ;

    else
    {
        Mat reduced(fv.rows,reduceSize,CV_64F,Scalar(0.0));
        for (int i=0;i<fv.rows;i++)
        {
            Mat rw=fv.row(i);
            rw=lda.project(rw) ;
            rw.copyTo(reduced(Rect(0,i,rw.cols,1)));
        }
        fv=reduced.clone();
    }
}
Mat LDAClass::getDataset()
{
    return DataSet;
}

but the LDA file is empty. I'm sure there is something wrong or misunderstood here, I appreciate your kind help.

edit retag flag offensive close merge delete