Using LDA as a features reduction method
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.