19 #define TRACE(A,B) (((A).array()*(B).transpose().array()).sum())
22 using namespace Eigen;
36 m_features = features;
61 SG_DEBUG(
"Entering CLMNN::train().\n")
64 CLMNNImpl::check_training_setup(m_features, m_labels, init_transform);
77 SG_DEBUG(
"Finding target nearest neighbors.\n")
80 SG_DEBUG(
"Summing outer products for (sub-)gradient initialization.\n")
81 MatrixXd gradient = (1-m_regularization)*CLMNNImpl::sum_outer_products(x, target_nn);
88 ImpostorsSetType exact_impostors, cur_impostors, prev_impostors;
94 m_statistics->resize(m_maxiter);
103 cur_impostors = CLMNNImpl::find_impostors(x,y,L,target_nn,iter,m_correction);
104 SG_DEBUG(
"Found %d impostors in the current set.\n", cur_impostors.size())
108 CLMNNImpl::update_gradient(x, gradient, cur_impostors, prev_impostors, m_regularization);
111 CLMNNImpl::gradient_step(L, gradient, stepsize, m_diagonal);
116 obj[iter] =
TRACE(L.transpose()*L,gradient) + m_regularization*cur_impostors.size();
119 CLMNNImpl::correct_stepsize(stepsize, obj, iter);
122 stop = CLMNNImpl::check_termination(stepsize, obj, iter, m_maxiter, m_stepsize_threshold, m_obj_threshold);
127 prev_impostors = cur_impostors;
130 m_statistics->set(iter-1, obj[iter-1], stepsize, cur_impostors.
size());
132 SG_DEBUG(
"iteration=%d, objective=%.4f, #impostors=%4d, stepsize=%.4E\n",
133 iter, obj[iter-1], cur_impostors.
size(), stepsize)
137 m_statistics->resize(iter);
144 SG_DEBUG(
"Leaving CLMNN::train().\n")
149 return m_linear_transform;
159 m_linear_transform.num_rows, m_linear_transform.num_cols);
161 MatrixXd M = map_linear_transform.transpose()*map_linear_transform;
164 for (
index_t i = 0; i < M.rows(); i++)
165 for (
index_t j = 0; j < M.cols(); j++)
166 mahalanobis_matrix(i,j) = M(i,j);
184 REQUIRE(k>0,
"The number of target neighbors per example must be larger than zero\n");
190 return m_regularization;
195 m_regularization = regularization;
205 REQUIRE(stepsize>0,
"The step size used in gradient descent must be larger than zero\n")
206 m_stepsize = stepsize;
211 return m_stepsize_threshold;
217 "The threshold for the step size must be larger than zero\n")
218 m_stepsize_threshold = stepsize_threshold;
228 REQUIRE(maxiter>0,
"The number of maximum iterations must be larger than zero\n")
239 m_correction = correction;
244 return m_obj_threshold;
250 "The threshold for the objective must be larger than zero\n")
251 m_obj_threshold = obj_threshold;
261 m_diagonal = diagonal;
272 SG_ADD(&m_linear_transform,
"linear_transform",
278 SG_ADD(&m_k, "k", "Number of target neighbours per example",
280 SG_ADD(&m_regularization, "regularization", "Regularization",
282 SG_ADD(&m_stepsize, "stepsize", "Step size in gradient descent",
284 SG_ADD(&m_stepsize_threshold, "stepsize_threshold", "Step size threshold",
286 SG_ADD(&m_maxiter, "maxiter", "Maximum number of iterations",
288 SG_ADD(&m_correction, "correction",
290 SG_ADD(&m_obj_threshold, "obj_threshold", "Objective threshold",
293 SG_ADD((
CSGObject**) &m_statistics, "statistics", "Training statistics",
299 m_regularization = 0.5;
301 m_stepsize_threshold = 1e-22;
304 m_obj_threshold = 1e-9;
320 return "LMNNStatistics";
325 REQUIRE(size > 0,
"The new size in CLMNNStatistics::resize must be larger than zero."
326 " Given value is %d.\n", size);
329 stepsize.resize_vector(size);
330 num_impostors.resize_vector(size);
334 uint32_t num_impostors_iter)
336 REQUIRE(iter >= 0 && iter < obj.
vlen,
"The iteration index in CLMNNStatistics::set "
337 "must be larger or equal to zero and less than the size (%d). Given valu is %d.\n", obj.
vlen, iter);
339 obj[iter] = obj_iter;
340 stepsize[iter] = stepsize_iter;
341 num_impostors[iter] = num_impostors_iter;
344 void CLMNNStatistics::init()
348 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)