Commit 4fd8980a authored by Davis King's avatar Davis King

Removed the rank_features() wrapper functions. Instead there are functions

to pick a reasonable default value for gamma.

--HG--
extra : convert_revision : svn%3Afdd8eb12-d10e-0410-9acb-85c331704f74/trunk%403243
parent c55c0994
...@@ -330,14 +330,19 @@ namespace dlib ...@@ -330,14 +330,19 @@ namespace dlib
} }
double operator() ( double operator() (
const double gamma double gamma
) const ) const
{ {
using namespace std; using namespace std;
// we are doing the optimization in log space so don't forget to convert back to normal space
gamma = std::exp(gamma);
typedef radial_basis_kernel<sample_type> kernel_type; typedef radial_basis_kernel<sample_type> kernel_type;
// make a kcentroid and find out what the gap is at the current gamma // Make a kcentroid and find out what the gap is at the current gamma. Try to pick a reasonable
kcentroid<kernel_type> kc(kernel_type(gamma), 0.0001, num_sv); // tolerance.
const double tolerance = std::min(gamma*0.01, 0.01);
kcentroid<kernel_type> kc(kernel_type(gamma), tolerance, num_sv);
scalar_type temp = centroid_gap(kc, samples, labels); scalar_type temp = centroid_gap(kc, samples, labels);
if (verbose) if (verbose)
...@@ -359,9 +364,10 @@ namespace dlib ...@@ -359,9 +364,10 @@ namespace dlib
typename sample_matrix_type, typename sample_matrix_type,
typename label_matrix_type typename label_matrix_type
> >
matrix<double,0,2> rank_features_rbf_impl ( double find_gamma_with_big_centroid_gap_impl (
const sample_matrix_type& samples, const sample_matrix_type& samples,
const label_matrix_type& labels, const label_matrix_type& labels,
double initial_gamma,
unsigned long num_sv, unsigned long num_sv,
bool verbose bool verbose
) )
...@@ -374,22 +380,17 @@ namespace dlib ...@@ -374,22 +380,17 @@ namespace dlib
cout << endl; cout << endl;
} }
// The first thing to do is to estimate what a good gamma is. Since the feature ranking
// works by ranking features by how much they separate the centroids of the two classes
// we will pick the gamma to use by finding the one that best separates the two classes.
test<sample_matrix_type, label_matrix_type> funct(samples, labels, num_sv, verbose); test<sample_matrix_type, label_matrix_type> funct(samples, labels, num_sv, verbose);
double best_gamma = 1.0; double best_gamma = std::log(initial_gamma);
find_max_single_variable(funct, best_gamma, 1e-8, 1000, 1e-3, 50); double goodness = find_max_single_variable(funct, best_gamma, -15, 15, 1e-3, 100);
typedef radial_basis_kernel<sample_type> kernel_type;
if (verbose) if (verbose)
{ {
cout << "\nNow doing feature ranking using a gamma of " << best_gamma << endl; cout << "\rBest gamma = " << std::exp(best_gamma) << ". Goodness = "
} << goodness << " " << endl;
// now just call the normal rank_features function and return whatever it says }
kcentroid<kernel_type> kc(kernel_type(best_gamma), 0.0001, num_sv);
return matrix_cast<double>(rank_features(kc, samples, labels)); return std::exp(best_gamma);
} }
} }
...@@ -399,14 +400,23 @@ namespace dlib ...@@ -399,14 +400,23 @@ namespace dlib
typename sample_matrix_type, typename sample_matrix_type,
typename label_matrix_type typename label_matrix_type
> >
matrix<double,0,2> rank_features_rbf ( double find_gamma_with_big_centroid_gap (
const sample_matrix_type& samples, const sample_matrix_type& samples,
const label_matrix_type& labels, const label_matrix_type& labels,
double initial_gamma = 0.1,
unsigned long num_sv = 40 unsigned long num_sv = 40
) )
{ {
return rank_features_helpers::rank_features_rbf_impl(vector_to_matrix(samples), DLIB_ASSERT(initial_gamma > 0 && num_sv > 0 && is_binary_classification_problem(samples, labels),
"\t double find_gamma_with_big_centroid_gap()"
<< "\n\t initial_gamma: " << initial_gamma
<< "\n\t num_sv: " << num_sv
<< "\n\t is_binary_classification_problem(): " << is_binary_classification_problem(samples, labels)
);
return rank_features_helpers::find_gamma_with_big_centroid_gap_impl(vector_to_matrix(samples),
vector_to_matrix(labels), vector_to_matrix(labels),
initial_gamma,
num_sv, num_sv,
false); false);
} }
...@@ -417,14 +427,23 @@ namespace dlib ...@@ -417,14 +427,23 @@ namespace dlib
typename sample_matrix_type, typename sample_matrix_type,
typename label_matrix_type typename label_matrix_type
> >
matrix<double,0,2> verbose_rank_features_rbf ( double verbose_find_gamma_with_big_centroid_gap (
const sample_matrix_type& samples, const sample_matrix_type& samples,
const label_matrix_type& labels, const label_matrix_type& labels,
double initial_gamma = 0.1,
unsigned long num_sv = 40 unsigned long num_sv = 40
) )
{ {
return rank_features_helpers::rank_features_rbf_impl(vector_to_matrix(samples), DLIB_ASSERT(initial_gamma > 0 && num_sv > 0 && is_binary_classification_problem(samples, labels),
"\t double verbose_find_gamma_with_big_centroid_gap()"
<< "\n\t initial_gamma: " << initial_gamma
<< "\n\t num_sv: " << num_sv
<< "\n\t is_binary_classification_problem(): " << is_binary_classification_problem(samples, labels)
);
return rank_features_helpers::find_gamma_with_big_centroid_gap_impl(vector_to_matrix(samples),
vector_to_matrix(labels), vector_to_matrix(labels),
initial_gamma,
num_sv, num_sv,
true); true);
} }
......
...@@ -61,21 +61,28 @@ namespace dlib ...@@ -61,21 +61,28 @@ namespace dlib
typename sample_matrix_type, typename sample_matrix_type,
typename label_matrix_type typename label_matrix_type
> >
matrix<double,0,2> rank_features_rbf ( double find_gamma_with_big_centroid_gap (
const sample_matrix_type& samples, const sample_matrix_type& samples,
const label_matrix_type& labels, const label_matrix_type& labels,
double initial_gamma = 0.1,
unsigned long num_sv = 40 unsigned long num_sv = 40
); );
/*! /*!
requires requires
- initial_gamma > 0
- num_sv > 0 - num_sv > 0
- is_binary_classification_problem(samples, labels) == true - is_binary_classification_problem(samples, labels) == true
ensures ensures
- This function just calls the above rank_features() function but uses the - This function uses the kcentroid object to attempt to determine what value
radial_basis_kernel and automatically picks a gamma parameter for you. of the gamma parameter of the radial_basis_kernel gives the largest
It also sets the kcentroid up to use num_sv dictionary vectors. Finally, it separation between the two classes in the given training data.
tells rank_features() to rank all the features. It also sets the kcentroid up to use num_sv dictionary vectors.
- The return value from this function is the matrix returned by rank_features() - This function does a search for the best gamma and the search starts with
the value given by initial_gamma. Better initial guesses will give
better results since the routine may get stuck in a local minima.
- returns the value of gamma that results in the largest separation
- This function is verbose in the sense that it will print status messages to
standard out during its processing.
!*/ !*/
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -84,22 +91,20 @@ namespace dlib ...@@ -84,22 +91,20 @@ namespace dlib
typename sample_matrix_type, typename sample_matrix_type,
typename label_matrix_type typename label_matrix_type
> >
matrix<double,0,2> verbose_rank_features_rbf ( double verbose_find_gamma_with_big_centroid_gap (
const sample_matrix_type& samples, const sample_matrix_type& samples,
const label_matrix_type& labels, const label_matrix_type& labels,
double initial_gamma = 0.1,
unsigned long num_sv = 40 unsigned long num_sv = 40
); );
/*! /*!
requires requires
- initial_gamma > 0
- num_sv > 0 - num_sv > 0
- is_binary_classification_problem(samples, labels) == true - is_binary_classification_problem(samples, labels) == true
ensures ensures
- This function just calls the above rank_features() function but uses the - This function does the same exact thing as the above find_gamma_with_big_centroid_gap()
radial_basis_kernel and automatically picks a gamma parameter for you. except that it is also verbose in the sense that it will print status messages to
It also sets the kcentroid up to use num_sv dictionary vectors. Finally, it
tells rank_features() to rank all the features.
- The return value from this function is the matrix returned by rank_features()
- This function is verbose in the sense that it will print status messages to
standard out during its processing. standard out during its processing.
!*/ !*/
......
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