void SparseCoding<DictionaryInitializer>::Encode(const size_t maxIterations, const double objTolerance, const double newtonTolerance) { Timer::Start("sparse_coding"); double lastObjVal = DBL_MAX; // Take the initial coding step, which has to happen before entering the main // optimization loop. Log::Info << "Initial Coding Step." << std::endl; OptimizeCode(); arma::uvec adjacencies = find(codes); Log::Info << " Sparsity level: " << 100.0 * ((double) (adjacencies.n_elem)) / ((double) (atoms * data.n_cols)) << "%." << std::endl; Log::Info << " Objective value: " << Objective() << "." << std::endl; for (size_t t = 1; t != maxIterations; ++t) { // Print current iteration, and maximum number of iterations (if it isn't // 0). Log::Info << "Iteration " << t; if (maxIterations != 0) Log::Info << " of " << maxIterations; Log::Info << "." << std::endl; // First step: optimize the dictionary. Log::Info << "Performing dictionary step... " << std::endl; OptimizeDictionary(adjacencies, newtonTolerance); Log::Info << " Objective value: " << Objective() << "." << std::endl; // Second step: perform the coding. Log::Info << "Performing coding step..." << std::endl; OptimizeCode(); // Get the indices of all the nonzero elements in the codes. adjacencies = find(codes); Log::Info << " Sparsity level: " << 100.0 * ((double) (adjacencies.n_elem)) / ((double) (atoms * data.n_cols)) << "%." << std::endl; // Find the new objective value and improvement so we can check for // convergence. double curObjVal = Objective(); double improvement = lastObjVal - curObjVal; Log::Info << " Objective value: " << curObjVal << " (improvement " << std::scientific << improvement << ")." << std::endl; // Have we converged? if (improvement < objTolerance) { Log::Info << "Converged within tolerance " << objTolerance << ".\n"; break; } lastObjVal = curObjVal; } Timer::Stop("sparse_coding"); }
void LocalCoordinateCoding::Train( const arma::mat& data, const DictionaryInitializer& initializer) { Timer::Start("local_coordinate_coding"); // Initialize the dictionary. initializer.Initialize(data, atoms, dictionary); double lastObjVal = DBL_MAX; // Take the initial coding step, which has to happen before entering the main // loop. Log::Info << "Initial Coding Step." << std::endl; arma::mat codes; Encode(data, codes); arma::uvec adjacencies = find(codes); Log::Info << " Sparsity level: " << 100.0 * ((double)(adjacencies.n_elem)) / ((double)(atoms * data.n_cols)) << "%.\n"; Log::Info << " Objective value: " << Objective(data, codes, adjacencies) << "." << std::endl; for (size_t t = 1; t != maxIterations; t++) { Log::Info << "Iteration " << t << " of " << maxIterations << "." << std::endl; // First step: optimize the dictionary. Log::Info << "Performing dictionary step..." << std::endl; OptimizeDictionary(data, codes, adjacencies); double dsObjVal = Objective(data, codes, adjacencies); Log::Info << " Objective value: " << dsObjVal << "." << std::endl; // Second step: perform the coding. Log::Info << "Performing coding step..." << std::endl; Encode(data, codes); adjacencies = find(codes); Log::Info << " Sparsity level: " << 100.0 * ((double) (adjacencies.n_elem)) / ((double)(atoms * data.n_cols)) << "%.\n"; // Terminate if the objective increased in the coding step. double curObjVal = Objective(data, codes, adjacencies); if (curObjVal > dsObjVal) { Log::Warn << "Objective increased in coding step! Terminating." << std::endl; break; } // Find the new objective value and improvement so we can check for // convergence. double improvement = lastObjVal - curObjVal; Log::Info << "Objective value: " << curObjVal << " (improvement " << std::scientific << improvement << ")." << std::endl; if (improvement < tolerance) { Log::Info << "Converged within tolerance " << tolerance << ".\n"; break; } lastObjVal = curObjVal; } Timer::Stop("local_coordinate_coding"); }