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
)
{
// 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)"
<< "\n\t You have to give a non-empty set of basis_samples"
<< "\n\t this: " << this
......@@ -85,7 +85,7 @@ namespace dlib
kernel = lisf.get_kernel();
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)
basis[i] = lisf[i];
......
......@@ -7,7 +7,6 @@
#include "kernel_matrix_abstract.h"
#include "../matrix.h"
#include "../algs.h"
#include "../statistics/random_subset_selector.h"
namespace dlib
{
......@@ -24,8 +23,9 @@ namespace dlib
return m(i);
}
template <typename kernel_type, typename T, typename Rand_type>
inline const T& access ( const random_subset_selector<T,Rand_type>& m, long i)
// bind to anything that looks like an array and isn't a matrix
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];
}
......@@ -54,25 +54,7 @@ namespace dlib
// --------------------------------------------
template <typename kernel_type, typename T>
inline unsigned long size ( const matrix_exp<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)
inline unsigned long size ( const T& m)
{
return m.size();
}
......
......@@ -25,8 +25,8 @@ namespace dlib
requires
- 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.
- V == dlib::matrix, std::vector, dlib::std_vector_c, dlib::random_subset_selector, or
kernel_type::sample_type.
- V == dlib::matrix, std::vector, dlib::std_vector_c, dlib::random_subset_selector,
dlib::linearly_independent_subset_finder, or kernel_type::sample_type.
- if (V is a dlib::matrix) then
- is_vector(v) == true
ensures
......@@ -59,10 +59,10 @@ namespace dlib
requires
- 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.
- V1 == dlib::matrix, std::vector, dlib::std_vector_c, dlib::random_subset_selector, or
kernel_type::sample_type.
- V2 == dlib::matrix, std::vector, dlib::std_vector_c, dlib::random_subset_selector, or
kernel_type::sample_type.
- V1 == dlib::matrix, std::vector, dlib::std_vector_c, dlib::random_subset_selector,
dlib::linearly_independent_subset_finder, or kernel_type::sample_type.
- V2 == dlib::matrix, std::vector, dlib::std_vector_c, dlib::random_subset_selector,
dlib::linearly_independent_subset_finder, or kernel_type::sample_type.
- if (V1 is a dlib::matrix) then
- is_vector(v1) == true
- if (V2 is a dlib::matrix) then
......
......@@ -35,7 +35,7 @@ namespace dlib
- max_dictionary_size() == my_max_dictionary_size
- get_kernel() == kernel
- minimum_tolerance() == min_tolerance
- dictionary_size() == dictionary.size()
- size() == dictionary.size()
- get_dictionary() == vector_to_matrix(dictionary)
- K.nr() == dictionary.size()
- K.nc() == dictionary.size()
......@@ -55,6 +55,7 @@ namespace dlib
public:
typedef typename kernel_type::scalar_type scalar_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;
linearly_independent_subset_finder (
......@@ -295,7 +296,7 @@ namespace dlib
temp.swap(item.temp);
}
unsigned long dictionary_size (
unsigned long size (
) const { return dictionary.size(); }
const matrix<sample_type,0,1,mem_manager_type> get_dictionary (
......@@ -451,7 +452,7 @@ namespace dlib
const scalar_type min_tol = lisf.minimum_tolerance();
// 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;
lisf.set_minimum_tolerance(std::max(tol, min_tol));
......@@ -460,7 +461,7 @@ namespace dlib
// 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
// 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)
{
......
......@@ -20,7 +20,7 @@ namespace dlib
is a kernel function object as defined in dlib/svm/kernel_abstract.h
INITIAL VALUE
- dictionary_size() == 0
- size() == 0
WHAT THIS OBJECT REPRESENTS
This is an implementation of an online algorithm for recursively finding a
......@@ -46,6 +46,7 @@ namespace dlib
public:
typedef typename kernel_type::scalar_type scalar_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;
linearly_independent_subset_finder (
......@@ -86,7 +87,7 @@ namespace dlib
/*!
ensures
- 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().
!*/
......@@ -112,7 +113,7 @@ namespace dlib
);
/*!
ensures
- clears out all the data (e.g. #dictionary_size() == 0)
- clears out all the data (e.g. #size() == 0)
!*/
bool add (
......@@ -120,17 +121,17 @@ namespace dlib
);
/*!
ensures
- if (dictionary_size() < max_dictionary_size() then
- if (size() < max_dictionary_size() then
- if (projection_error(x) > minimum_tolerance()) then
- adds x into the dictionary
- (*this)[#dictionary_size()-1] == x
- #dictionary_size() == dictionary_size() + 1
- (*this)[#size()-1] == x
- #size() == size() + 1
- returns true
- else
- the dictionary is not changed
- returns false
- else
- #dictionary_size() == dictionary_size()
- #size() == size()
(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
remove one of the current ones. So let proj_error[i] be equal to the
......@@ -143,7 +144,7 @@ namespace dlib
- if (projection_error(x) > minimum_tolerance() && projection_error(x) > min_proj_error)
- the least linearly independent vector in this object is removed
- adds x into the dictionary
- (*this)[#dictionary_size()-1] == x
- (*this)[#size()-1] == x
- returns true
- else
- the dictionary is not changed
......@@ -172,7 +173,7 @@ namespace dlib
- swaps *this with item
!*/
unsigned long dictionary_size (
unsigned long size (
) const;
/*!
ensures
......@@ -184,7 +185,7 @@ namespace dlib
) const;
/*!
requires
- index < dictionary_size()
- index < size()
ensures
- returns the index'th element in the set of linearly independent
vectors contained in this object.
......@@ -203,7 +204,7 @@ namespace dlib
/*!
ensures
- returns a matrix K such that:
- K.nr() == K.nc() == dictionary_size()
- K.nr() == K.nc() == size()
- K == kernel_matrix(get_kernel(), get_dictionary())
i.e. K == the kernel matrix for the dictionary vectors
!*/
......@@ -212,7 +213,7 @@ namespace dlib
) const;
/*!
ensures
- if (dictionary_size() != 0)
- if (size() != 0)
- returns inv(get_kernel_matrix())
- else
- returns an empty matrix
......
......@@ -117,7 +117,7 @@ namespace dlib
linearly_independent_subset_finder<kernel_type> lisf(kernel, num_centers);
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
matrix<scalar_type,0,0,mem_manager_type> K(x.nr(), num_centers+1);
......
......@@ -96,7 +96,7 @@ namespace dlib
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,
0,
......@@ -483,7 +483,7 @@ namespace dlib
matrix<scalar_type,0,1,mem_manager_type> beta;
// 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());
......
......@@ -425,7 +425,7 @@ namespace dlib
dlib::rand::kernel_1a rnd;
// 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()));
}
......@@ -458,7 +458,7 @@ namespace dlib
{
// if the basis is already as big as it's going to get then just do the most
// accurate training right now.
if (lisf.dictionary_size() == max_basis_size)
if (lisf.size() == max_basis_size)
trainer.set_epsilon(min_epsilon);
while (true)
......@@ -484,7 +484,7 @@ namespace dlib
if (verbose)
{
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
......@@ -496,7 +496,7 @@ namespace dlib
// now add more elements to the basis
unsigned long count = 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)
{
// pick a random sample
......
......@@ -245,24 +245,24 @@ namespace
{
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;
}
}
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
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));
empirical_kernel_map<kernel_type> ekm;
ekm.load(lisf);
DLIB_TEST(ekm.basis_size() == lisf.dictionary_size());
DLIB_TEST(ekm.basis_size() == lisf.size());
std::vector<sample_type> proj_samples;
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