mlpack
sparse_coding_impl.hpp
Go to the documentation of this file.
1 
13 #ifndef MLPACK_METHODS_SPARSE_CODING_SPARSE_CODING_IMPL_HPP
14 #define MLPACK_METHODS_SPARSE_CODING_SPARSE_CODING_IMPL_HPP
15 
16 // In case it hasn't already been included.
17 #include "sparse_coding.hpp"
18 
19 namespace mlpack {
20 namespace sparse_coding {
21 
22 template<typename DictionaryInitializer>
24  const arma::mat& data,
25  const size_t atoms,
26  const double lambda1,
27  const double lambda2,
28  const size_t maxIterations,
29  const double objTolerance,
30  const double newtonTolerance,
31  const DictionaryInitializer& initializer) :
32  atoms(atoms),
33  lambda1(lambda1),
34  lambda2(lambda2),
35  maxIterations(maxIterations),
36  objTolerance(objTolerance),
37  newtonTolerance(newtonTolerance)
38 {
39  Train(data, initializer);
40 }
41 
42 template<typename DictionaryInitializer>
44  const arma::mat& data,
45  const DictionaryInitializer& initializer)
46 {
47  // Now, train.
48  Timer::Start("sparse_coding");
49 
50  // Initialize the dictionary.
51  initializer.Initialize(data, atoms, dictionary);
52 
53  double lastObjVal = DBL_MAX;
54 
55  // Take the initial coding step, which has to happen before entering the main
56  // optimization loop.
57  Log::Info << "Initial coding step." << std::endl;
58 
59  arma::mat codes(atoms, data.n_cols);
60  Encode(data, codes);
61  arma::uvec adjacencies = find(codes);
62 
63  Log::Info << " Sparsity level: " << 100.0 * ((double) (adjacencies.n_elem))
64  / ((double) (atoms * data.n_cols)) << "%." << std::endl;
65  Log::Info << " Objective value: " << Objective(data, codes) << "."
66  << std::endl;
67 
68  for (size_t t = 1; t != maxIterations; ++t)
69  {
70  // Print current iteration, and maximum number of iterations (if it isn't
71  // 0).
72  Log::Info << "Iteration " << t;
73  if (maxIterations != 0)
74  Log::Info << " of " << maxIterations;
75  Log::Info << "." << std::endl;
76 
77  // First step: optimize the dictionary.
78  Log::Info << "Performing dictionary step... " << std::endl;
79  OptimizeDictionary(data, codes, adjacencies);
80  Log::Info << " Objective value: " << Objective(data, codes) << "."
81  << std::endl;
82 
83  // Second step: perform the coding.
84  Log::Info << "Performing coding step..." << std::endl;
85  Encode(data, codes);
86  // Get the indices of all the nonzero elements in the codes.
87  adjacencies = find(codes);
88  Log::Info << " Sparsity level: " << 100.0 * ((double) (adjacencies.n_elem))
89  / ((double) (atoms * data.n_cols)) << "%." << std::endl;
90 
91  // Find the new objective value and improvement so we can check for
92  // convergence.
93  double curObjVal = Objective(data, codes);
94  double improvement = lastObjVal - curObjVal;
95  Log::Info << " Objective value: " << curObjVal << " (improvement "
96  << std::scientific << improvement << ")." << std::endl;
97 
98  lastObjVal = curObjVal;
99 
100  // Have we converged?
101  if (improvement < objTolerance)
102  {
103  Log::Info << "Converged within tolerance " << objTolerance << ".\n";
104  break;
105  }
106  }
107 
108  Timer::Stop("sparse_coding");
109  return lastObjVal;
110 }
111 
112 template<typename Archive>
113 void SparseCoding::serialize(Archive& ar, const uint32_t /* version */)
114 {
115  ar(CEREAL_NVP(atoms));
116  ar(CEREAL_NVP(dictionary));
117  ar(CEREAL_NVP(lambda1));
118  ar(CEREAL_NVP(lambda2));
119  ar(CEREAL_NVP(maxIterations));
120  ar(CEREAL_NVP(objTolerance));
121  ar(CEREAL_NVP(newtonTolerance));
122 }
123 
124 } // namespace sparse_coding
125 } // namespace mlpack
126 
127 #endif
static void Start(const std::string &name)
Start the given timer.
Definition: timers.cpp:28
Linear algebra utility functions, generally performed on matrices or vectors.
Definition: cv.hpp:1
double Train(const arma::mat &data, const DictionaryInitializer &initializer=DictionaryInitializer())
Train the sparse coding model on the given dataset.
Definition: sparse_coding_impl.hpp:43
SparseCoding(const arma::mat &data, const size_t atoms, const double lambda1, const double lambda2=0, const size_t maxIterations=0, const double objTolerance=0.01, const double newtonTolerance=1e-6, const DictionaryInitializer &initializer=DictionaryInitializer())
Set the parameters to SparseCoding.
Definition: sparse_coding_impl.hpp:23
void serialize(Archive &ar, const uint32_t)
Serialize the sparse coding model.
Definition: sparse_coding_impl.hpp:113
double Objective(const arma::mat &data, const arma::mat &codes) const
Compute the objective function.
Definition: sparse_coding.cpp:258
static void Stop(const std::string &name)
Stop the given timer.
Definition: timers.cpp:36
static MLPACK_EXPORT util::PrefixedOutStream Info
Prints informational messages if –verbose is specified, prefixed with [INFO ].
Definition: log.hpp:84
double OptimizeDictionary(const arma::mat &data, const arma::mat &codes, const arma::uvec &adjacencies)
Learn dictionary via Newton method based on Lagrange dual.
Definition: sparse_coding.cpp:62
void Encode(const arma::mat &data, arma::mat &codes)
Sparse code each point in the given dataset via LARS, using the current dictionary and store the enco...
Definition: sparse_coding.cpp:36