I am essentially doing face recognition and verification in Java, testing with PCA and then WMPCA. I have PCA fully implemented however it runs incredibly slow, 15 minutes to train a 7900 image data set.
I have looked at where the longest delays are, some are unavoidable such as preprocessing the data (get face region, grayscale, resize, store). However the main delays are in the Matrix calculations.
The first big delay is during the calculation of the Covariance matrix and then getting the eigenvalues and eigenvectors from the covariance matrix. I am currently using the Apache libraries to achieve this, but it seems to be single threaded and only consumes ~15% CPU while calculating this. It runs very slow and although I have found possible alternatives for the eigenvectors and eigenvalues decomposition, I cannot find an alternative fast library for the covariance matrix calculation.
Here is the code snippet for when I calculate what I describe above:
Log.append("Computing covariance matrix...");
// Compute covariance
RealMatrix matrix = new Covariance(new BlockRealMatrix(
dataWithAverageSubtracted).transpose()).getCovarianceMatrix();
Log.append("Computing eigen decomposition...");
// Get the eigenvalues and eigenvectors
EigenDecomposition eigen = new EigenDecomposition(matrix);
eigenValues = eigen.getRealEigenvalues();
// Transpose because rows need to be eigenvectors not columns
vectors = eigen.getV().transpose().getData();
I am using both Apache and Jama for other more generic Matrix calculations when obtaining the weights and eigenfaces. Both these libraries have been reviewed to be incredibly slow and I guess an alternative may be a library such as JBlas, but this will only speed up this section.
I do not want to run into the issue where I spend a long time converting between the data formats required for each library.
Does anyone know any Java solutions to the computation of the covariance matrix and then the eigen-decomposition? This seems to be the main bottleneck.
It may depend on the type of operations, but heavy computations may be faster in a lower level language such as C. You should try to benchmark them, and if the gain is important enough, you could use JNI to interface the C routines from Java.
Such optimisations are currently used in some well known applications, for example Tomcat.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With