* Modified AMF module so that now it uses tolerance checking rather
than minResidue checking * Added SVD batch learning
This commit is contained in:
@@ -1,9 +1,13 @@
|
||||
/**
|
||||
* @file nmf_als.hpp
|
||||
* @author Sumedh Ghaisas
|
||||
*/
|
||||
#ifndef __MLPACK_METHODS_LMF_LMF_HPP
|
||||
#define __MLPACK_METHODS_LMF_LMF_HPP
|
||||
|
||||
#include <mlpack/core.hpp>
|
||||
#include "update_rules/nmf_mult_dist.hpp"
|
||||
#include "init_rules/random_init.hpp"
|
||||
#include <amf/update_rules/nmf_mult_dist.hpp>
|
||||
#include <amf/init_rules/random_init.hpp>
|
||||
|
||||
namespace mlpack {
|
||||
namespace amf {
|
||||
@@ -63,7 +67,7 @@ class AMF
|
||||
* the W and H vector has states that it needs to store
|
||||
*/
|
||||
AMF(const size_t maxIterations = 10000,
|
||||
const double minResidue = 1e-10,
|
||||
const double tolerance = 1e-5,
|
||||
const InitializationRule initializeRule = InitializationRule(),
|
||||
const UpdateRule update = UpdateRule());
|
||||
|
||||
@@ -76,7 +80,7 @@ class AMF
|
||||
* @param r Rank r of the factorization.
|
||||
*/
|
||||
template<typename MatType>
|
||||
void Apply(const MatType& V,
|
||||
double Apply(const MatType& V,
|
||||
const size_t r,
|
||||
arma::mat& W,
|
||||
arma::mat& H) const;
|
||||
@@ -85,7 +89,7 @@ class AMF
|
||||
//! The maximum number of iterations allowed before giving up.
|
||||
size_t maxIterations;
|
||||
//! The minimum residue, below which iteration is considered converged.
|
||||
double minResidue;
|
||||
double tolerance;
|
||||
//! Instantiated initialization Rule.
|
||||
InitializationRule initializeRule;
|
||||
//! Instantiated update rule.
|
||||
@@ -97,9 +101,9 @@ class AMF
|
||||
//! Modify the maximum number of iterations.
|
||||
size_t& MaxIterations() { return maxIterations; }
|
||||
//! Access the minimum residue before termination.
|
||||
double MinResidue() const { return minResidue; }
|
||||
double Tolerance() const { return tolerance; }
|
||||
//! Modify the minimum residue before termination.
|
||||
double& MinResidue() { return minResidue; }
|
||||
double& Tolerance() { return tolerance; }
|
||||
//! Access the initialization rule.
|
||||
const InitializationRule& InitializeRule() const { return initializeRule; }
|
||||
//! Modify the initialization rule.
|
||||
@@ -118,3 +122,4 @@ class AMF
|
||||
#include "amf_impl.hpp"
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* @file nmf_als.hpp
|
||||
* @author Sumedh Ghaisas
|
||||
*/
|
||||
namespace mlpack {
|
||||
namespace amf {
|
||||
|
||||
@@ -8,19 +12,19 @@ template<typename InitializationRule,
|
||||
typename UpdateRule>
|
||||
AMF<InitializationRule, UpdateRule>::AMF(
|
||||
const size_t maxIterations,
|
||||
const double minResidue,
|
||||
const double tolerance,
|
||||
const InitializationRule initializeRule,
|
||||
const UpdateRule update) :
|
||||
maxIterations(maxIterations),
|
||||
minResidue(minResidue),
|
||||
tolerance(tolerance),
|
||||
initializeRule(initializeRule),
|
||||
update(update)
|
||||
{
|
||||
if (minResidue < 0.0)
|
||||
if (tolerance < 0.0 || tolerance > 1)
|
||||
{
|
||||
Log::Warn << "AMF::AMF(): minResidue must be a positive value ("
|
||||
<< minResidue << " given). Setting to the default value of 1e-10.\n";
|
||||
this->minResidue = 1e-10;
|
||||
Log::Warn << "AMF::AMF(): tolerance must be a positive value in the range (0-1) but value "
|
||||
<< tolerance << " is given. Setting to the default value of 1e-5.\n";
|
||||
this->tolerance = 1e-5;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +39,7 @@ AMF<InitializationRule, UpdateRule>::AMF(
|
||||
template<typename InitializationRule,
|
||||
typename UpdateRule>
|
||||
template<typename MatType>
|
||||
void AMF<InitializationRule, UpdateRule>::Apply(
|
||||
double AMF<InitializationRule, UpdateRule>::Apply(
|
||||
const MatType& V,
|
||||
const size_t r,
|
||||
arma::mat& W,
|
||||
@@ -51,12 +55,15 @@ void AMF<InitializationRule, UpdateRule>::Apply(
|
||||
|
||||
size_t iteration = 1;
|
||||
const size_t nm = n * m;
|
||||
double residue = minResidue;
|
||||
double residue = DBL_MIN;
|
||||
double oldResidue = DBL_MAX;
|
||||
double normOld = 0;
|
||||
double norm = 0;
|
||||
arma::mat WH;
|
||||
|
||||
while (residue >= minResidue && iteration != maxIterations)
|
||||
std::cout << tolerance << std::endl;
|
||||
|
||||
while (((oldResidue - residue) / oldResidue >= tolerance || iteration < 4) && iteration != maxIterations)
|
||||
{
|
||||
// Update step.
|
||||
// Update the value of W and H based on the Update Rules provided
|
||||
@@ -69,6 +76,7 @@ void AMF<InitializationRule, UpdateRule>::Apply(
|
||||
|
||||
if (iteration != 0)
|
||||
{
|
||||
oldResidue = residue;
|
||||
residue = fabs(normOld - norm);
|
||||
residue /= normOld;
|
||||
}
|
||||
@@ -76,11 +84,16 @@ void AMF<InitializationRule, UpdateRule>::Apply(
|
||||
normOld = norm;
|
||||
|
||||
iteration++;
|
||||
|
||||
std::cout << residue << std::endl;
|
||||
}
|
||||
|
||||
Log::Info << "AMF converged to residue of " << sqrt(residue) << " in "
|
||||
<< iteration << " iterations." << std::endl;
|
||||
|
||||
return residue;
|
||||
}
|
||||
|
||||
}; // namespace nmf
|
||||
}; // namespace mlpack
|
||||
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
#ifndef __MLPACK_METHODS_AMF_UPDATE_RULES_SVD_BATCHLEARNING_HPP
|
||||
#define __MLPACK_METHODS_AMF_UPDATE_RULES_SVD_BATCHLEARNING_HPP
|
||||
|
||||
#include <mlpack/core.hpp>
|
||||
|
||||
namespace mlpack
|
||||
{
|
||||
namespace amf
|
||||
{
|
||||
class SVDBatchLearning
|
||||
{
|
||||
public:
|
||||
SVDBatchLearning(double u = 0.000001,
|
||||
double kw = 0,
|
||||
double kh = 0,
|
||||
double min = -DBL_MIN,
|
||||
double max = DBL_MAX)
|
||||
: u(u), kw(kw), kh(kh), min(min), max(max) {}
|
||||
|
||||
/**
|
||||
* The update rule for the basis matrix W.
|
||||
* The function takes in all the matrices and only changes the
|
||||
* value of the W matrix.
|
||||
*
|
||||
* @param V Input matrix to be factorized.
|
||||
* @param W Basis matrix to be updated.
|
||||
* @param H Encoding matrix.
|
||||
*/
|
||||
template<typename MatType>
|
||||
inline void WUpdate(const MatType& V,
|
||||
arma::mat& W,
|
||||
const arma::mat& H) const
|
||||
{
|
||||
size_t n = V.n_rows;
|
||||
size_t m = V.n_cols;
|
||||
|
||||
size_t r = W.n_cols;
|
||||
|
||||
arma::mat deltaW(n, r);
|
||||
deltaW.zeros();
|
||||
|
||||
for(size_t i = 0; i < n; i++)
|
||||
{
|
||||
for(size_t j = 0; j < m; j++)
|
||||
if(V(i,j) != 0) deltaW.row(i) += (V(i,j) - Predict(W.row(i), H.col(j))) * arma::trans(H.col(j));
|
||||
deltaW.row(i) -= kw * W.row(i);
|
||||
}
|
||||
|
||||
W += u * deltaW;
|
||||
}
|
||||
|
||||
/**
|
||||
* The update rule for the encoding matrix H.
|
||||
* The function takes in all the matrices and only changes the
|
||||
* value of the H matrix.
|
||||
*
|
||||
* @param V Input matrix to be factorized.
|
||||
* @param W Basis matrix.
|
||||
* @param H Encoding matrix to be updated.
|
||||
*/
|
||||
template<typename MatType>
|
||||
inline void HUpdate(const MatType& V,
|
||||
const arma::mat& W,
|
||||
arma::mat& H) const
|
||||
{
|
||||
size_t n = V.n_rows;
|
||||
size_t m = V.n_cols;
|
||||
|
||||
size_t r = W.n_cols;
|
||||
|
||||
arma::mat deltaH(r, m);
|
||||
deltaH.zeros();
|
||||
|
||||
for(size_t j = 0; j < m; j++)
|
||||
{
|
||||
for(size_t i = 0; i < n; i++)
|
||||
if(V(i,j) != 0) deltaH.col(j) += (V(i,j) - Predict(W.row(i), H.col(j))) * arma::trans(W.row(i));
|
||||
deltaH.col(j) -= kh * H.col(j);
|
||||
}
|
||||
|
||||
H += u*deltaH;
|
||||
}
|
||||
private:
|
||||
|
||||
double Predict(const arma::mat& wi, const arma::mat& hj) const
|
||||
{
|
||||
arma::mat temp = (wi * hj);
|
||||
double out = temp(0,0);
|
||||
return out;
|
||||
}
|
||||
|
||||
double u;
|
||||
double kw;
|
||||
double kh;
|
||||
double min;
|
||||
double max;
|
||||
};
|
||||
} // namespace amf
|
||||
} // namespace mlpack
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user