Search code examples
machine-learningneural-networkautoencodermlpack

mlpack sparse coding solution not found


I am trying to learn how to use the Sparse Coding algorithm with the mlpack library. When I call Encode() on my instance of mlpack::sparse_coding:SparseCoding, I get the error

[WARN] There are 63 inactive atoms. They will be reinitialized randomly. 
error: solve(): solution not found

Is it simply that the algorithm cannot learn a latent representation of the data. Or perhaps it is my usage? The relevant section follows EDIT: One line was modified to fix an unrelated error, but the original error remains.

double* Application::GetSparseCodes(arma::mat* trainingExample, int atomCount)
{
    double* latentRep = new double[atomCount];
    mlpack::sparse_coding::SparseCoding<mlpack::sparse_coding::DataDependentRandomInitializer> sc(*trainingExample, Utils::ATOM_COUNT, 1.0);
    sc.Encode(Utils::MAX_ITERATIONS);
    arma::mat& latentRepMat = sc.Codes();
    for (int i = 0; i < atomCount; i++)
        latentRep[i] = latentRepMat.at(i, 0);
    return latentRep;
}

Some relevant parameters

const static int IMAGE_WIDTH = 20;
const static int IMAGE_HEIGHT = 20;
const static int PIXEL_COUNT = IMAGE_WIDTH * IMAGE_HEIGHT;
const static int ATOM_COUNT = 64;
const static int MAX_ITERATIONS = 100000;

Solution

  • This could be one of a handful of issues but given the description it's a little difficult to tell which of these it is (or if it is something else entirely). However, these three ideas should provide a good place to start:

    • Matrices in mlpack are column-major. That means each observation should represent a column. If you use mlpack::data::Load() to load, e.g., a CSV file (which are generally one row per observation), it will automatically transpose the dataset. SparseCoding will act oddly if you pass it transposed data. See also http://www.mlpack.org/doxygen.php?doc=matrices.html.

    • If there are 63 inactive atoms, then only one atom is actually active (given that ATOM_COUNT is 64). This means that the algorithm has found that the best way to represent the dictionary (at a given step) uses only one atom. This could happen if the matrix you are passing consists of all zeros.

    • mlpack will provide verbose output, which may also be helpful for debugging. Usually this is used by using mlpack's CLI class to parse command-line input, but you can enable verbose output with mlpack::Log::Info.ignoreInput = false. You may obtain a lot of output that way, but it will give a better look at what is going on...

    The mlpack project has its own mailing list where you may be likely to get a quicker or more comprehensive response, by the way.