20 #define TRACE(A,B) (((A).array()*(B).transpose().array()).sum())
23 using namespace Eigen;
37 m_features = features;
62 SG_DEBUG(
"Entering CLMNN::train().\n")
65 CLMNNImpl::check_training_setup(m_features, m_labels, init_transform);
78 SG_DEBUG(
"Finding target nearest neighbors.\n")
81 SG_DEBUG(
"Summing outer products for (sub-)gradient initialization.\n")
82 MatrixXd gradient = (1-m_regularization)*CLMNNImpl::sum_outer_products(x, target_nn);
89 ImpostorsSetType exact_impostors, cur_impostors, prev_impostors;
95 m_statistics->resize(m_maxiter);
104 cur_impostors = CLMNNImpl::find_impostors(x,y,L,target_nn,iter,m_correction);
105 SG_DEBUG(
"Found %d impostors in the current set.\n", cur_impostors.size())
109 CLMNNImpl::update_gradient(x, gradient, cur_impostors, prev_impostors, m_regularization);
112 CLMNNImpl::gradient_step(L, gradient, stepsize, m_diagonal);
117 obj[iter] =
TRACE(L.transpose()*L,gradient) + m_regularization*cur_impostors.size();
120 CLMNNImpl::correct_stepsize(stepsize, obj, iter);
123 stop = CLMNNImpl::check_termination(stepsize, obj, iter, m_maxiter, m_stepsize_threshold, m_obj_threshold);
128 prev_impostors = cur_impostors;
131 m_statistics->set(iter-1, obj[iter-1], stepsize, cur_impostors.
size());
133 SG_DEBUG(
"iteration=%d, objective=%.4f, #impostors=%4d, stepsize=%.4E\n",
134 iter, obj[iter-1], cur_impostors.
size(), stepsize)
138 m_statistics->resize(iter);
145 SG_DEBUG(
"Leaving CLMNN::train().\n")
150 return m_linear_transform;
160 m_linear_transform.num_rows, m_linear_transform.num_cols);
162 MatrixXd M = map_linear_transform.transpose()*map_linear_transform;
165 for (
index_t i = 0; i < M.rows(); i++)
166 for (
index_t j = 0; j < M.cols(); j++)
167 mahalanobis_matrix(i,j) = M(i,j);
185 REQUIRE(k>0,
"The number of target neighbors per example must be larger than zero\n");
191 return m_regularization;
196 m_regularization = regularization;
206 REQUIRE(stepsize>0,
"The step size used in gradient descent must be larger than zero\n")
207 m_stepsize = stepsize;
212 return m_stepsize_threshold;
218 "The threshold for the step size must be larger than zero\n")
219 m_stepsize_threshold = stepsize_threshold;
229 REQUIRE(maxiter>0,
"The number of maximum iterations must be larger than zero\n")
240 m_correction = correction;
245 return m_obj_threshold;
251 "The threshold for the objective must be larger than zero\n")
252 m_obj_threshold = obj_threshold;
262 m_diagonal = diagonal;
273 SG_ADD(&m_linear_transform,
"linear_transform",
279 SG_ADD(&m_k, "k", "Number of target neighbours per example",
281 SG_ADD(&m_regularization, "regularization", "Regularization",
283 SG_ADD(&m_stepsize, "stepsize", "Step size in gradient descent",
285 SG_ADD(&m_stepsize_threshold, "stepsize_threshold", "Step size threshold",
287 SG_ADD(&m_maxiter, "maxiter", "Maximum number of iterations",
289 SG_ADD(&m_correction, "correction",
291 SG_ADD(&m_obj_threshold, "obj_threshold", "Objective threshold",
294 SG_ADD((
CSGObject**) &m_statistics, "statistics", "Training statistics",
300 m_regularization = 0.5;
302 m_stepsize_threshold = 1e-22;
305 m_obj_threshold = 1e-9;
321 return "LMNNStatistics";
326 REQUIRE(size > 0,
"The new size in CLMNNStatistics::resize must be larger than zero."
327 " Given value is %d.\n", size);
330 stepsize.resize_vector(size);
331 num_impostors.resize_vector(size);
335 uint32_t num_impostors_iter)
337 REQUIRE(iter >= 0 && iter < obj.
vlen,
"The iteration index in CLMNNStatistics::set "
338 "must be larger or equal to zero and less than the size (%d). Given valu is %d.\n", obj.
vlen, iter);
340 obj[iter] = obj_iter;
341 stepsize[iter] = stepsize_iter;
342 num_impostors[iter] = num_impostors_iter;
345 void CLMNNStatistics::init()
349 SG_ADD(&num_impostors,
"num_impostors",
"Number of impostors at each iteration",
CCustomMahalanobisDistance * get_distance() const
float distance(CJLCoverTreePoint p1, CJLCoverTreePoint p2, float64_t upper_bound)
virtual const char * get_name() const
void set_regularization(const float64_t regularization)
void set_diagonal(const bool diagonal)
virtual const char * get_name() const
float64_t get_obj_threshold() const
bool get_diagonal() const
int32_t get_num_features() const
float64_t get_stepsize_threshold() const
float64_t get_stepsize() const
Class LMNNStatistics used to give access to intermediate results obtained training LMNN...
float64_t get_regularization() const
void set(index_t iter, float64_t obj_iter, float64_t stepsize_iter, uint32_t num_impostors_iter)
static T * clone_matrix(const T *matrix, int32_t nrows, int32_t ncols)
Multiclass Labels for multi-class classification.
uint32_t get_correction() const
void set_maxiter(const uint32_t maxiter)
void set_stepsize_threshold(const float64_t stepsize_threshold)
Class SGObject is the base class of all shogun objects.
virtual int32_t get_num_vectors() const
CLMNNStatistics * get_statistics() const
void set_k(const int32_t k)
Class CustomMahalanobisDistance used to compute the distance between feature vectors and as ...
virtual ~CLMNNStatistics()
void resize(int32_t size)
all of classes and functions are contained in the shogun namespace
SGMatrix< float64_t > get_linear_transform() const
void set_obj_threshold(const float64_t obj_threshold)
void train(SGMatrix< float64_t > init_transform=SGMatrix< float64_t >())
void set_correction(const uint32_t correction)
uint32_t get_maxiter() const
void set_stepsize(const float64_t stepsize)
void resize_vector(int32_t n)
static CMulticlassLabels * to_multiclass(CLabels *base_labels)