12 #ifndef MLPACK_METHODS_REGULARIZED_SVD_REGULARIZED_FUNCTION_SVD_IMPL_HPP 13 #define MLPACK_METHODS_REGULARIZED_SVD_REGULARIZED_FUNCTION_SVD_IMPL_HPP 21 template <
typename MatType>
24 const double lambda) :
25 data(math::
MakeAlias(const_cast<MatType&>(data), false)),
30 numUsers = max(data.row(0)) + 1;
31 numItems = max(data.row(1)) + 1;
34 initialPoint.randu(rank, numUsers + numItems);
37 template<
typename MatType>
40 data =
data.cols(arma::shuffle(arma::linspace<arma::uvec>(0,
data.n_cols - 1,
44 template <
typename MatType>
51 template <
typename MatType>
54 const size_t batchSize)
const 64 double objective = 0.0;
65 for (
size_t i = start; i < start + batchSize; ++i)
68 const size_t user =
data(0, i);
69 const size_t item =
data(1, i) + numUsers;
72 const double rating =
data(2, i);
73 double ratingError = rating - arma::dot(parameters.col(user),
74 parameters.col(item));
75 double ratingErrorSquared = ratingError * ratingError;
78 double userVecNorm = arma::norm(parameters.col(user), 2);
79 double itemVecNorm = arma::norm(parameters.col(item), 2);
80 double regularizationError = lambda * (userVecNorm * userVecNorm +
81 itemVecNorm * itemVecNorm);
83 objective += (ratingErrorSquared + regularizationError);
89 template <
typename MatType>
91 arma::mat& gradient)
const 102 gradient.zeros(rank, numUsers + numItems);
104 for (
size_t i = 0; i <
data.n_cols; ++i)
107 const size_t user =
data(0, i);
108 const size_t item =
data(1, i) + numUsers;
111 const double rating =
data(2, i);
112 double ratingError = rating - arma::dot(parameters.col(user),
113 parameters.col(item));
117 gradient.col(user) += 2 * (lambda * parameters.col(user) -
118 ratingError * parameters.col(item));
119 gradient.col(item) += 2 * (lambda * parameters.col(item) -
120 ratingError * parameters.col(user));
124 template <
typename MatType>
125 template <
typename GradType>
129 const size_t batchSize)
const 131 gradient.zeros(rank, numUsers + numItems);
134 for (
size_t i = start; i < start + batchSize; ++i)
136 const size_t user =
data(0, i);
137 const size_t item =
data(1, i) + numUsers;
140 const double rating =
data(2, i);
141 double ratingError = rating - arma::dot(parameters.col(user),
142 parameters.col(item));
146 gradient.col(user) += 2 * (lambda * parameters.col(user) -
147 ratingError * parameters.col(item));
148 gradient.col(item) += 2 * (lambda * parameters.col(item) -
149 ratingError * parameters.col(user));
161 double StandardSGD::Optimize(
163 arma::mat& parameters)
166 const size_t numFunctions =
function.NumFunctions();
169 size_t currentFunction = 0;
170 double overallObjective = 0;
173 for (
size_t i = 0; i < numFunctions; ++i)
174 overallObjective +=
function.
Evaluate(parameters, i);
176 const arma::mat
data =
function.Dataset();
179 for (
size_t i = 1; i != maxIterations; ++i, currentFunction++)
182 if ((currentFunction % numFunctions) == 0)
184 const size_t epoch = i / numFunctions + 1;
186 << overallObjective <<
"." << std::endl;
189 overallObjective = 0;
193 const size_t numUsers =
function.NumUsers();
196 const size_t user = data(0, currentFunction);
197 const size_t item = data(1, currentFunction) + numUsers;
200 const double rating = data(2, currentFunction);
201 double ratingError = rating - arma::dot(parameters.col(user),
202 parameters.col(item));
204 double lambda =
function.Lambda();
208 parameters.col(user) -= stepSize * (lambda * parameters.col(user) -
209 ratingError * parameters.col(item));
210 parameters.col(item) -= stepSize * (lambda * parameters.col(item) -
211 ratingError * parameters.col(user));
214 overallObjective +=
function.Evaluate(parameters, currentFunction);
217 return overallObjective;
223 inline double ParallelSGD<ExponentialBackoff>::Optimize(
227 double overallObjective = DBL_MAX;
228 double lastObjective;
231 arma::Col<size_t> visitationOrder = arma::linspace<arma::Col<size_t>>(0,
232 (
function.NumFunctions() - 1),
function.
NumFunctions());
234 const arma::mat
data =
function.Dataset();
239 for (
size_t i = 1; i != maxIterations; ++i)
242 lastObjective = overallObjective;
243 overallObjective = 0;
245 #pragma omp parallel for reduction(+:overallObjective) 246 for (omp_size_t j = 0; j < (omp_size_t)
function.
NumFunctions(); ++j)
248 overallObjective +=
function.Evaluate(iterate, j);
253 << overallObjective <<
"." << std::endl;
255 if (std::isnan(overallObjective) || std::isinf(overallObjective))
258 <<
"; terminating with failure. Try a smaller step size?" 260 return overallObjective;
263 if (std::abs(lastObjective - overallObjective) < tolerance)
266 <<
"; terminating optimization." << std::endl;
267 return overallObjective;
271 double stepSize = decayPolicy.StepSize(i);
274 std::shuffle(visitationOrder.begin(), visitationOrder.end(),
283 threadId = omp_get_thread_num();
286 for (
size_t j = threadId * threadShareSize;
287 j < (threadId + 1) * threadShareSize && j < visitationOrder.n_elem;
290 const size_t numUsers =
function.NumUsers();
293 const size_t user = data(0, visitationOrder[j]);
294 const size_t item = data(1, visitationOrder[j]) + numUsers;
297 const double rating = data(2, visitationOrder[j]);
298 double ratingError = rating - arma::dot(iterate.col(user),
301 double lambda =
function.Lambda();
303 arma::mat userUpdate = stepSize * (lambda * iterate.col(user) -
304 ratingError * iterate.col(item));
305 arma::mat itemUpdate = stepSize * (lambda * iterate.col(item) -
306 ratingError * iterate.col(user));
310 for (
size_t i = 0; i < iterate.n_rows; ++i)
313 iterate(i, user) -= userUpdate(i);
315 iterate(i, item) -= itemUpdate(i);
321 << overallObjective << std::endl;
323 return overallObjective;
void Shuffle()
Shuffle the points in the dataset.
Definition: regularized_svd_function_impl.hpp:38
size_t NumFunctions() const
Return the number of training examples. Useful for SGD optimizer.
Definition: regularized_svd_function.hpp:104
Linear algebra utility functions, generally performed on matrices or vectors.
Definition: cv.hpp:1
Definition: bias_svd_function_impl.hpp:185
double Evaluate(const arma::mat ¶meters) const
Evaluates the cost function over all examples in the data.
Definition: regularized_svd_function_impl.hpp:45
void Gradient(const arma::mat ¶meters, arma::mat &gradient) const
Evaluates the full gradient of the cost function over all the training examples.
Definition: regularized_svd_function_impl.hpp:90
static MLPACK_EXPORT util::PrefixedOutStream Warn
Prints warning messages prefixed with [WARN ].
Definition: log.hpp:87
RegularizedSVDFunction(const MatType &data, const size_t rank, const double lambda)
Constructor for RegularizedSVDFunction class.
Definition: regularized_svd_function_impl.hpp:22
static MLPACK_EXPORT util::PrefixedOutStream Info
Prints informational messages if –verbose is specified, prefixed with [INFO ].
Definition: log.hpp:84
arma::Cube< ElemType > MakeAlias(arma::Cube< ElemType > &input, const bool strict=true)
Make an alias of a dense cube.
Definition: make_alias.hpp:24
The data is stored in a matrix of type MatType, so that this class can be used with both dense and sp...
Definition: regularized_svd_function.hpp:29
MLPACK_EXPORT std::mt19937 randGen
MLPACK_EXPORT is required for global variables; it exports the symbols correctly on Windows...
Definition: random.cpp:18