Search code examples
matlabclassificationsvmlibsvmvlfeat

SVM prediction of data in cells rather than the expected matrix


For my svm training and prediction I am using vl_svmtrain, the documentation of which can be found here: http://www.vlfeat.org/matlab/vl_svmtrain.html

[W B] = VL_SVMTRAIN(X, Y, LAMBDA) trains a linear Support Vector Machine (SVM) from the data vectors X and the labels Y. X is a D by N matrix, with one column per example and D feature dimensions (SINGLE or DOUBLE). Y is a DOUBLE vector with N elements with a binary (-1 or +1) label for each training point.

According to the documentation the data X must be in a D by N matrix having one sample per column.

The thing is my data is not arranged in this way at all and I don't think I can arrange it like this even if I wanted. Each of my image is represented by a feature matrix of size 512 * 257, these are stored in a cell. Similarly each test image is also of the same size.

So for the sake of simplification I assume that I only have 3 classes, each class is represented by a model of size 512 * 257 and I have thousands of tests that I must compare agains each model, more like a one vs all approach. But its the data arrangement that I am having difficulty with.

Is it possible to present the data to SVM in cell format rather than the matrix format?

Update:

The cell array I mentioned consists of 28 models. So I have a total of 28 classes, each class is represented by a array of size 512 * 257. Writing models(1) presents ans = [512x257 double] and writing models{1} produces the 512*257 double matrix.

This is what I am using to train the SVM, similarly each test is also of the same size, and in the same arrangement.

How I got this matrix for each model? I extracted the RootSIFT features from 100 images for each class/model. I then presented these features to a gaussian mixture model script and set the number of clusters to be 512. This gave me the means, covariances and weights of the 512 clusters. I then concatenated them using models{i} = [gmm_models{i}.w(:) gmm_models{i}.mu' gmm_models{i}.sigma'];

As for the test, RootSIFT features are extracted from 5 images, and then they undergo the same process as with the models to get the concatenated matrix of the same size. So naturally for each model there are hundreds of test matrices.

I hope this has clarified it more than before.


Solution

  • There isn't a way to represent the data to the vl_svmtrain method other than the D x N matrix that it's talking about. However, what you can do is unroll the cell array and transform each feature matrix so that it becomes a column vector. You would then construct your matrix such that each column vector represents a single feature matrix and concatenate these column vectors width-wise to produce your final D x N matrix.

    As such, you can do a bit of pre-processing to get your desired matrix X. First, unroll your cell array so that it becomes a 3D matrix where each slice is one feature matrix. Then, reshape this matrix so that each slice becomes a single column for a final 2D matrix. Therefore, do something like this, assuming that your cell array is stored in A:

    X_3D = cat(3, A{:});
    X = reshape(X_3D, size(X_3D,1)*size(X_3D,2), []);
    

    X will contain that final 2D matrix we talked about. Bear in mind that each feature matrix will get unrolled on a column basis. This means that for each feature matrix you have, the columns are stacked on top of each other to create a single column for the output 2D matrix. You can now use X as input into vl_svmtrain.

    However, I will give you fair warning in that each column would technically be 512 x 257 = 131584 elements. If you have 1000s of feature matrices, this matrix may be infeasible for use into vl_svmtrain due to memory requirements. Therefore, you may have to either subsample your feature matrix, or use a decreased number of feature matrices for the input.

    Good luck!