Commit 03ee2169 authored by Davis King's avatar Davis King

- Renamed the linearly_independent_subset_finder's dictionary_size() member function to

   size().  This way, linearly_independent_subset_finder objects can be used in many
   templated functions which expect objects which look like arrays.
 - Generalized the kernel_matrix() function slightly so that it can work with anything
   that looks like an array.  This now includes linearly_independent_subset_finder objects.

--HG--
extra : convert_revision : svn%3Afdd8eb12-d10e-0410-9acb-85c331704f74/trunk%403893
parent d3bccacd
...@@ -77,7 +77,7 @@ namespace dlib ...@@ -77,7 +77,7 @@ namespace dlib
) )
{ {
// make sure requires clause is not broken // make sure requires clause is not broken
DLIB_ASSERT(lisf.dictionary_size() > 0, DLIB_ASSERT(lisf.size() > 0,
"\tvoid empirical_kernel_map::load(linearly_independent_subset_finder)" "\tvoid empirical_kernel_map::load(linearly_independent_subset_finder)"
<< "\n\t You have to give a non-empty set of basis_samples" << "\n\t You have to give a non-empty set of basis_samples"
<< "\n\t this: " << this << "\n\t this: " << this
...@@ -85,7 +85,7 @@ namespace dlib ...@@ -85,7 +85,7 @@ namespace dlib
kernel = lisf.get_kernel(); kernel = lisf.get_kernel();
weights = trans(chol(lisf.get_inv_kernel_marix())); weights = trans(chol(lisf.get_inv_kernel_marix()));
basis.resize(lisf.dictionary_size()); basis.resize(lisf.size());
for (unsigned long i = 0; i < basis.size(); ++i) for (unsigned long i = 0; i < basis.size(); ++i)
basis[i] = lisf[i]; basis[i] = lisf[i];
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#include "kernel_matrix_abstract.h" #include "kernel_matrix_abstract.h"
#include "../matrix.h" #include "../matrix.h"
#include "../algs.h" #include "../algs.h"
#include "../statistics/random_subset_selector.h"
namespace dlib namespace dlib
{ {
...@@ -24,8 +23,9 @@ namespace dlib ...@@ -24,8 +23,9 @@ namespace dlib
return m(i); return m(i);
} }
template <typename kernel_type, typename T, typename Rand_type> // bind to anything that looks like an array and isn't a matrix
inline const T& access ( const random_subset_selector<T,Rand_type>& m, long i) template <typename kernel_type, typename T>
inline const typename disable_if<is_matrix<T>,typename T::type>::type& access ( const T& m, long i)
{ {
return m[i]; return m[i];
} }
...@@ -54,25 +54,7 @@ namespace dlib ...@@ -54,25 +54,7 @@ namespace dlib
// -------------------------------------------- // --------------------------------------------
template <typename kernel_type, typename T> template <typename kernel_type, typename T>
inline unsigned long size ( const matrix_exp<T>& m) inline unsigned long size ( const T& m)
{
return m.size();
}
template <typename kernel_type, typename T, typename Rand_type>
inline unsigned long size ( const random_subset_selector<T,Rand_type>& m)
{
return m.size();
}
template <typename kernel_type, typename T, typename alloc>
inline unsigned long size ( const std::vector<T,alloc>& m)
{
return m.size();
}
template <typename kernel_type, typename T, typename alloc>
inline unsigned long size ( const std_vector_c<T,alloc>& m)
{ {
return m.size(); return m.size();
} }
......
...@@ -25,8 +25,8 @@ namespace dlib ...@@ -25,8 +25,8 @@ namespace dlib
requires requires
- kernel == a kernel function object as defined by the file dlib/svm/kernel_abstract.h. - kernel == a kernel function object as defined by the file dlib/svm/kernel_abstract.h.
This kernel must also be capable of operating on the contents of v. This kernel must also be capable of operating on the contents of v.
- V == dlib::matrix, std::vector, dlib::std_vector_c, dlib::random_subset_selector, or - V == dlib::matrix, std::vector, dlib::std_vector_c, dlib::random_subset_selector,
kernel_type::sample_type. dlib::linearly_independent_subset_finder, or kernel_type::sample_type.
- if (V is a dlib::matrix) then - if (V is a dlib::matrix) then
- is_vector(v) == true - is_vector(v) == true
ensures ensures
...@@ -59,10 +59,10 @@ namespace dlib ...@@ -59,10 +59,10 @@ namespace dlib
requires requires
- kernel == a kernel function object as defined by the file dlib/svm/kernel_abstract.h - kernel == a kernel function object as defined by the file dlib/svm/kernel_abstract.h
This kernel must also be capable of operating on the contents of v1 and v2. This kernel must also be capable of operating on the contents of v1 and v2.
- V1 == dlib::matrix, std::vector, dlib::std_vector_c, dlib::random_subset_selector, or - V1 == dlib::matrix, std::vector, dlib::std_vector_c, dlib::random_subset_selector,
kernel_type::sample_type. dlib::linearly_independent_subset_finder, or kernel_type::sample_type.
- V2 == dlib::matrix, std::vector, dlib::std_vector_c, dlib::random_subset_selector, or - V2 == dlib::matrix, std::vector, dlib::std_vector_c, dlib::random_subset_selector,
kernel_type::sample_type. dlib::linearly_independent_subset_finder, or kernel_type::sample_type.
- if (V1 is a dlib::matrix) then - if (V1 is a dlib::matrix) then
- is_vector(v1) == true - is_vector(v1) == true
- if (V2 is a dlib::matrix) then - if (V2 is a dlib::matrix) then
......
...@@ -35,7 +35,7 @@ namespace dlib ...@@ -35,7 +35,7 @@ namespace dlib
- max_dictionary_size() == my_max_dictionary_size - max_dictionary_size() == my_max_dictionary_size
- get_kernel() == kernel - get_kernel() == kernel
- minimum_tolerance() == min_tolerance - minimum_tolerance() == min_tolerance
- dictionary_size() == dictionary.size() - size() == dictionary.size()
- get_dictionary() == vector_to_matrix(dictionary) - get_dictionary() == vector_to_matrix(dictionary)
- K.nr() == dictionary.size() - K.nr() == dictionary.size()
- K.nc() == dictionary.size() - K.nc() == dictionary.size()
...@@ -55,6 +55,7 @@ namespace dlib ...@@ -55,6 +55,7 @@ namespace dlib
public: public:
typedef typename kernel_type::scalar_type scalar_type; typedef typename kernel_type::scalar_type scalar_type;
typedef typename kernel_type::sample_type sample_type; typedef typename kernel_type::sample_type sample_type;
typedef typename kernel_type::sample_type type;
typedef typename kernel_type::mem_manager_type mem_manager_type; typedef typename kernel_type::mem_manager_type mem_manager_type;
linearly_independent_subset_finder ( linearly_independent_subset_finder (
...@@ -295,7 +296,7 @@ namespace dlib ...@@ -295,7 +296,7 @@ namespace dlib
temp.swap(item.temp); temp.swap(item.temp);
} }
unsigned long dictionary_size ( unsigned long size (
) const { return dictionary.size(); } ) const { return dictionary.size(); }
const matrix<sample_type,0,1,mem_manager_type> get_dictionary ( const matrix<sample_type,0,1,mem_manager_type> get_dictionary (
...@@ -451,7 +452,7 @@ namespace dlib ...@@ -451,7 +452,7 @@ namespace dlib
const scalar_type min_tol = lisf.minimum_tolerance(); const scalar_type min_tol = lisf.minimum_tolerance();
// run many rounds of random sampling. In each round we drop the tolerance lower. // run many rounds of random sampling. In each round we drop the tolerance lower.
while (tol >= min_tol && lisf.dictionary_size() < lisf.max_dictionary_size()) while (tol >= min_tol && lisf.size() < lisf.max_dictionary_size())
{ {
tol *= 0.5; tol *= 0.5;
lisf.set_minimum_tolerance(std::max(tol, min_tol)); lisf.set_minimum_tolerance(std::max(tol, min_tol));
...@@ -460,7 +461,7 @@ namespace dlib ...@@ -460,7 +461,7 @@ namespace dlib
// Keep picking random samples and adding them into the lisf. Stop when we either // Keep picking random samples and adding them into the lisf. Stop when we either
// fill it up or can't find any more samples with projection error larger than the // fill it up or can't find any more samples with projection error larger than the
// current tolerance. // current tolerance.
while (lisf.dictionary_size() < lisf.max_dictionary_size() && add_failures < sampling_size) while (lisf.size() < lisf.max_dictionary_size() && add_failures < sampling_size)
{ {
if (lisf.add(samples(rnd.get_random_32bit_number()%samples.size())) == false) if (lisf.add(samples(rnd.get_random_32bit_number()%samples.size())) == false)
{ {
......
...@@ -20,7 +20,7 @@ namespace dlib ...@@ -20,7 +20,7 @@ namespace dlib
is a kernel function object as defined in dlib/svm/kernel_abstract.h is a kernel function object as defined in dlib/svm/kernel_abstract.h
INITIAL VALUE INITIAL VALUE
- dictionary_size() == 0 - size() == 0
WHAT THIS OBJECT REPRESENTS WHAT THIS OBJECT REPRESENTS
This is an implementation of an online algorithm for recursively finding a This is an implementation of an online algorithm for recursively finding a
...@@ -46,6 +46,7 @@ namespace dlib ...@@ -46,6 +46,7 @@ namespace dlib
public: public:
typedef typename kernel_type::scalar_type scalar_type; typedef typename kernel_type::scalar_type scalar_type;
typedef typename kernel_type::sample_type sample_type; typedef typename kernel_type::sample_type sample_type;
typedef typename kernel_type::sample_type type;
typedef typename kernel_type::mem_manager_type mem_manager_type; typedef typename kernel_type::mem_manager_type mem_manager_type;
linearly_independent_subset_finder ( linearly_independent_subset_finder (
...@@ -86,7 +87,7 @@ namespace dlib ...@@ -86,7 +87,7 @@ namespace dlib
/*! /*!
ensures ensures
- returns the maximum number of dictionary vectors this object - returns the maximum number of dictionary vectors this object
will accumulate. That is, dictionary_size() will never be will accumulate. That is, size() will never be
greater than max_dictionary_size(). greater than max_dictionary_size().
!*/ !*/
...@@ -112,7 +113,7 @@ namespace dlib ...@@ -112,7 +113,7 @@ namespace dlib
); );
/*! /*!
ensures ensures
- clears out all the data (e.g. #dictionary_size() == 0) - clears out all the data (e.g. #size() == 0)
!*/ !*/
bool add ( bool add (
...@@ -120,17 +121,17 @@ namespace dlib ...@@ -120,17 +121,17 @@ namespace dlib
); );
/*! /*!
ensures ensures
- if (dictionary_size() < max_dictionary_size() then - if (size() < max_dictionary_size() then
- if (projection_error(x) > minimum_tolerance()) then - if (projection_error(x) > minimum_tolerance()) then
- adds x into the dictionary - adds x into the dictionary
- (*this)[#dictionary_size()-1] == x - (*this)[#size()-1] == x
- #dictionary_size() == dictionary_size() + 1 - #size() == size() + 1
- returns true - returns true
- else - else
- the dictionary is not changed - the dictionary is not changed
- returns false - returns false
- else - else
- #dictionary_size() == dictionary_size() - #size() == size()
(i.e. the number of vectors in this object doesn't change) (i.e. the number of vectors in this object doesn't change)
- since the dictionary is full adding a new element means we have to - since the dictionary is full adding a new element means we have to
remove one of the current ones. So let proj_error[i] be equal to the remove one of the current ones. So let proj_error[i] be equal to the
...@@ -143,7 +144,7 @@ namespace dlib ...@@ -143,7 +144,7 @@ namespace dlib
- if (projection_error(x) > minimum_tolerance() && projection_error(x) > min_proj_error) - if (projection_error(x) > minimum_tolerance() && projection_error(x) > min_proj_error)
- the least linearly independent vector in this object is removed - the least linearly independent vector in this object is removed
- adds x into the dictionary - adds x into the dictionary
- (*this)[#dictionary_size()-1] == x - (*this)[#size()-1] == x
- returns true - returns true
- else - else
- the dictionary is not changed - the dictionary is not changed
...@@ -172,7 +173,7 @@ namespace dlib ...@@ -172,7 +173,7 @@ namespace dlib
- swaps *this with item - swaps *this with item
!*/ !*/
unsigned long dictionary_size ( unsigned long size (
) const; ) const;
/*! /*!
ensures ensures
...@@ -184,7 +185,7 @@ namespace dlib ...@@ -184,7 +185,7 @@ namespace dlib
) const; ) const;
/*! /*!
requires requires
- index < dictionary_size() - index < size()
ensures ensures
- returns the index'th element in the set of linearly independent - returns the index'th element in the set of linearly independent
vectors contained in this object. vectors contained in this object.
...@@ -203,7 +204,7 @@ namespace dlib ...@@ -203,7 +204,7 @@ namespace dlib
/*! /*!
ensures ensures
- returns a matrix K such that: - returns a matrix K such that:
- K.nr() == K.nc() == dictionary_size() - K.nr() == K.nc() == size()
- K == kernel_matrix(get_kernel(), get_dictionary()) - K == kernel_matrix(get_kernel(), get_dictionary())
i.e. K == the kernel matrix for the dictionary vectors i.e. K == the kernel matrix for the dictionary vectors
!*/ !*/
...@@ -212,7 +213,7 @@ namespace dlib ...@@ -212,7 +213,7 @@ namespace dlib
) const; ) const;
/*! /*!
ensures ensures
- if (dictionary_size() != 0) - if (size() != 0)
- returns inv(get_kernel_matrix()) - returns inv(get_kernel_matrix())
- else - else
- returns an empty matrix - returns an empty matrix
......
...@@ -117,7 +117,7 @@ namespace dlib ...@@ -117,7 +117,7 @@ namespace dlib
linearly_independent_subset_finder<kernel_type> lisf(kernel, num_centers); linearly_independent_subset_finder<kernel_type> lisf(kernel, num_centers);
fill_lisf(lisf, x); fill_lisf(lisf, x);
const long num_centers = lisf.dictionary_size(); const long num_centers = lisf.size();
// fill the K matrix with the output of the kernel for all the center and sample point pairs // fill the K matrix with the output of the kernel for all the center and sample point pairs
matrix<scalar_type,0,0,mem_manager_type> K(x.nr(), num_centers+1); matrix<scalar_type,0,0,mem_manager_type> K(x.nr(), num_centers+1);
......
...@@ -96,7 +96,7 @@ namespace dlib ...@@ -96,7 +96,7 @@ namespace dlib
matrix<scalar_type,0,1,mem_manager_type> alpha; matrix<scalar_type,0,1,mem_manager_type> alpha;
alpha = lisf.get_inv_kernel_marix()*(kernel_matrix(kern,lisf.get_dictionary(),dec_funct.basis_vectors)*dec_funct.alpha); alpha = lisf.get_inv_kernel_marix()*(kernel_matrix(kern,lisf,dec_funct.basis_vectors)*dec_funct.alpha);
decision_function<kernel_type> new_df(alpha, decision_function<kernel_type> new_df(alpha,
0, 0,
...@@ -483,7 +483,7 @@ namespace dlib ...@@ -483,7 +483,7 @@ namespace dlib
matrix<scalar_type,0,1,mem_manager_type> beta; matrix<scalar_type,0,1,mem_manager_type> beta;
// Now we compute the fist approximate decision function. // Now we compute the fist approximate decision function.
beta = lisf.get_inv_kernel_marix()*(kernel_matrix(kern,lisf.get_dictionary(),dec_funct.basis_vectors)*dec_funct.alpha); beta = lisf.get_inv_kernel_marix()*(kernel_matrix(kern,lisf,dec_funct.basis_vectors)*dec_funct.alpha);
matrix<sample_type,0,1,mem_manager_type> out_vectors(lisf.get_dictionary()); matrix<sample_type,0,1,mem_manager_type> out_vectors(lisf.get_dictionary());
......
...@@ -425,7 +425,7 @@ namespace dlib ...@@ -425,7 +425,7 @@ namespace dlib
dlib::rand::kernel_1a rnd; dlib::rand::kernel_1a rnd;
// first pick the initial basis set randomly // first pick the initial basis set randomly
for (unsigned long i = 0; i < 10*initial_basis_size && lisf.dictionary_size() < initial_basis_size; ++i) for (unsigned long i = 0; i < 10*initial_basis_size && lisf.size() < initial_basis_size; ++i)
{ {
lisf.add(x(rnd.get_random_32bit_number()%x.size())); lisf.add(x(rnd.get_random_32bit_number()%x.size()));
} }
...@@ -458,7 +458,7 @@ namespace dlib ...@@ -458,7 +458,7 @@ namespace dlib
{ {
// if the basis is already as big as it's going to get then just do the most // if the basis is already as big as it's going to get then just do the most
// accurate training right now. // accurate training right now.
if (lisf.dictionary_size() == max_basis_size) if (lisf.size() == max_basis_size)
trainer.set_epsilon(min_epsilon); trainer.set_epsilon(min_epsilon);
while (true) while (true)
...@@ -484,7 +484,7 @@ namespace dlib ...@@ -484,7 +484,7 @@ namespace dlib
if (verbose) if (verbose)
{ {
std::cout << "svm objective: " << svm_objective << std::endl; std::cout << "svm objective: " << svm_objective << std::endl;
std::cout << "basis size: " << lisf.dictionary_size() << std::endl; std::cout << "basis size: " << lisf.size() << std::endl;
} }
// if we failed to make progress on this iteration then we are done // if we failed to make progress on this iteration then we are done
...@@ -496,7 +496,7 @@ namespace dlib ...@@ -496,7 +496,7 @@ namespace dlib
// now add more elements to the basis // now add more elements to the basis
unsigned long count = 0; unsigned long count = 0;
for (unsigned long j = 0; for (unsigned long j = 0;
(j < 100*basis_size_increment) && (count < basis_size_increment) && (lisf.dictionary_size() < max_basis_size); (j < 100*basis_size_increment) && (count < basis_size_increment) && (lisf.size() < max_basis_size);
++j) ++j)
{ {
// pick a random sample // pick a random sample
......
...@@ -245,24 +245,24 @@ namespace ...@@ -245,24 +245,24 @@ namespace
{ {
if (lisf.add(samples[i])) if (lisf.add(samples[i]))
{ {
DLIB_TEST(equal(lisf[lisf.dictionary_size()-1], samples[i])); DLIB_TEST(equal(lisf[lisf.size()-1], samples[i]));
++count; ++count;
} }
} }
DLIB_TEST(count == lisf.dictionary_size()); DLIB_TEST(count == lisf.size());
DLIB_TEST(lisf.dictionary_size() == (unsigned int)n); DLIB_TEST(lisf.size() == (unsigned int)n);
dlog << LINFO << "lisf.dictionary_size(): "<< lisf.dictionary_size(); dlog << LINFO << "lisf.size(): "<< lisf.size();
// make sure the kernel matrices coming out of the lisf are correct // make sure the kernel matrices coming out of the lisf are correct
DLIB_TEST(dlib::equal(lisf.get_kernel_matrix(), kernel_matrix(kern, lisf.get_dictionary()), 1e-8)); DLIB_TEST(dlib::equal(lisf.get_kernel_matrix(), kernel_matrix(kern, lisf), 1e-8));
DLIB_TEST(dlib::equal(lisf.get_inv_kernel_marix(), inv(kernel_matrix(kern, lisf.get_dictionary())), 1e-8)); DLIB_TEST(dlib::equal(lisf.get_inv_kernel_marix(), inv(kernel_matrix(kern, lisf.get_dictionary())), 1e-8));
empirical_kernel_map<kernel_type> ekm; empirical_kernel_map<kernel_type> ekm;
ekm.load(lisf); ekm.load(lisf);
DLIB_TEST(ekm.basis_size() == lisf.dictionary_size()); DLIB_TEST(ekm.basis_size() == lisf.size());
std::vector<sample_type> proj_samples; std::vector<sample_type> proj_samples;
for (unsigned long i = 0; i < samples.size(); ++i) for (unsigned long i = 0; i < samples.size(); ++i)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment