mirror of
https://github.com/davisking/dlib.git
synced 2024-11-01 10:14:53 +08:00
Changed the feature extraction interfaces for the sequence labeling and
assignment problem learning tools to also include an optional num_nonnegative_weights() method. This method can be used to tell any machine learning tools which elements of the learned parameter vector should be non-negative. As part of this change, I also removed the previous methods for doing this from the structural_assignment_trainer since they are now redundant.
This commit is contained in:
parent
3956330d1f
commit
55d21096de
@ -75,6 +75,23 @@ namespace dlib
|
||||
is "good").
|
||||
!*/
|
||||
|
||||
unsigned long num_nonnegative_weights (
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns the number of elements of the w parameter vector which should be
|
||||
non-negative. That is, this feature extractor is intended to be used
|
||||
with w vectors where the first num_nonnegative_weights() elements of w
|
||||
are >= 0. That is, it should be the case that w(i) >= 0 for all i <
|
||||
num_nonnegative_weights().
|
||||
- Note that num_nonnegative_weights() is just an optional method to allow
|
||||
you to tell a tool like the structural_assignment_trainer that the
|
||||
learned w should have a certain number of non-negative elements.
|
||||
Therefore, if you do not provide a num_nonnegative_weights() method in
|
||||
your feature extractor then it will default to a value of 0, indicating
|
||||
that all elements of the w parameter vector may be any value.
|
||||
!*/
|
||||
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
76
dlib/svm/num_nonnegative_weights.h
Normal file
76
dlib/svm/num_nonnegative_weights.h
Normal file
@ -0,0 +1,76 @@
|
||||
// Copyright (C) 2012 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_NUM_NONNEGATIVE_WEIGHtS_H__
|
||||
#define DLIB_NUM_NONNEGATIVE_WEIGHtS_H__
|
||||
|
||||
#include "../enable_if.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
namespace impl2
|
||||
{
|
||||
template <
|
||||
typename T,
|
||||
unsigned long (T::*funct)()const
|
||||
>
|
||||
struct hnnf_helper
|
||||
{
|
||||
typedef char type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
char has_num_nonnegative_weights_helper( typename hnnf_helper<T,&T::num_nonnegative_weights>::type = 0 ) { return 0;}
|
||||
|
||||
struct two_bytes
|
||||
{
|
||||
char a[2];
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
two_bytes has_num_nonnegative_weights_helper(int) { return two_bytes();}
|
||||
|
||||
template <typename T>
|
||||
struct work_around_visual_studio_bug
|
||||
{
|
||||
const static unsigned long U = sizeof(has_num_nonnegative_weights_helper<T>('a'));
|
||||
};
|
||||
|
||||
|
||||
// This is a template to tell you if a feature_extractor has a num_nonnegative_weights function or not.
|
||||
template <typename T, unsigned long U = work_around_visual_studio_bug<T>::U >
|
||||
struct has_num_nonnegative_weights
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct has_num_nonnegative_weights <T,1>
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
// call fe.num_nonnegative_weights() if it exists, otherwise return 0.
|
||||
template <typename feature_extractor>
|
||||
typename enable_if<impl2::has_num_nonnegative_weights<feature_extractor>,unsigned long>::type num_nonnegative_weights (
|
||||
const feature_extractor& fe
|
||||
)
|
||||
{
|
||||
return fe.num_nonnegative_weights();
|
||||
}
|
||||
|
||||
template <typename feature_extractor>
|
||||
typename disable_if<impl2::has_num_nonnegative_weights<feature_extractor>,unsigned long>::type num_nonnegative_weights (
|
||||
const feature_extractor& /*fe*/
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_NUM_NONNEGATIVE_WEIGHtS_H__
|
||||
|
@ -146,6 +146,23 @@ namespace dlib
|
||||
- This function only calls set_feature() with feature_index values < num_features()
|
||||
!*/
|
||||
|
||||
unsigned long num_nonnegative_weights (
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns the number of elements of the w parameter vector which should be
|
||||
non-negative. That is, this feature extractor is intended to be used
|
||||
with w vectors where the first num_nonnegative_weights() elements of w
|
||||
are >= 0. That is, it should be the case that w(i) >= 0 for all i <
|
||||
num_nonnegative_weights().
|
||||
- Note that num_nonnegative_weights() is just an optional method to allow
|
||||
you to tell a tool like the structural_sequence_labeling_trainer that the
|
||||
learned w should have a certain number of non-negative elements.
|
||||
Therefore, if you do not provide a num_nonnegative_weights() method in
|
||||
your feature extractor then it will default to a value of 0, indicating
|
||||
that all elements of the w parameter vector may be any value.
|
||||
!*/
|
||||
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "../algs.h"
|
||||
#include "../optimization.h"
|
||||
#include "structural_svm_assignment_problem.h"
|
||||
#include "num_nonnegative_weights.h"
|
||||
|
||||
|
||||
namespace dlib
|
||||
@ -55,16 +56,6 @@ namespace dlib
|
||||
return num_threads;
|
||||
}
|
||||
|
||||
bool learns_nonnegative_weights (
|
||||
) const { return learn_nonnegative_weights; }
|
||||
|
||||
void set_learns_nonnegative_weights (
|
||||
bool value
|
||||
)
|
||||
{
|
||||
learn_nonnegative_weights = value;
|
||||
}
|
||||
|
||||
void set_epsilon (
|
||||
double eps_
|
||||
)
|
||||
@ -193,13 +184,7 @@ namespace dlib
|
||||
|
||||
matrix<double,0,1> weights;
|
||||
|
||||
unsigned long num_nonnegative = 0;
|
||||
if (learn_nonnegative_weights)
|
||||
{
|
||||
num_nonnegative = fe.num_features();
|
||||
}
|
||||
|
||||
solver(prob, weights, num_nonnegative);
|
||||
solver(prob, weights, num_nonnegative_weights(fe));
|
||||
|
||||
return assignment_function<feature_extractor>(weights,fe,force_assignment);
|
||||
|
||||
@ -208,7 +193,6 @@ namespace dlib
|
||||
|
||||
private:
|
||||
|
||||
bool learn_nonnegative_weights;
|
||||
bool force_assignment;
|
||||
double C;
|
||||
oca solver;
|
||||
@ -225,7 +209,6 @@ namespace dlib
|
||||
eps = 0.1;
|
||||
num_threads = 2;
|
||||
max_cache_size = 40;
|
||||
learn_nonnegative_weights = false;
|
||||
}
|
||||
|
||||
feature_extractor fe;
|
||||
|
@ -52,7 +52,6 @@ namespace dlib
|
||||
- #get_max_cache_size() == 40
|
||||
- #get_feature_extractor() == a default initialized feature_extractor
|
||||
- #forces_assignment() == false
|
||||
- #learns_nonnegative_weights() == false
|
||||
!*/
|
||||
|
||||
explicit structural_assignment_trainer (
|
||||
@ -67,7 +66,6 @@ namespace dlib
|
||||
- #get_max_cache_size() == 40
|
||||
- #get_feature_extractor() == fe
|
||||
- #forces_assignment() == false
|
||||
- #learns_nonnegative_weights() == false
|
||||
!*/
|
||||
|
||||
const feature_extractor& get_feature_extractor (
|
||||
@ -164,23 +162,6 @@ namespace dlib
|
||||
- returns a copy of the optimizer used to solve the structural SVM problem.
|
||||
!*/
|
||||
|
||||
bool learns_nonnegative_weights (
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- The output of training is a weight vector that defines the behavior of an
|
||||
assignment_function object. If learns_nonnegative_weights() == true then
|
||||
the resulting weight vector will always have non-negative entries.
|
||||
!*/
|
||||
|
||||
void set_learns_nonnegative_weights (
|
||||
bool value
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #learns_nonnegative_weights() == value
|
||||
!*/
|
||||
|
||||
void set_c (
|
||||
double C
|
||||
);
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "../algs.h"
|
||||
#include "../optimization.h"
|
||||
#include "structural_svm_sequence_labeling_problem.h"
|
||||
#include "num_nonnegative_weights.h"
|
||||
|
||||
|
||||
namespace dlib
|
||||
@ -219,7 +220,7 @@ namespace dlib
|
||||
for (unsigned long i = 0; i < loss_values.size(); ++i)
|
||||
prob.set_loss(i,loss_values[i]);
|
||||
|
||||
solver(prob, weights);
|
||||
solver(prob, weights, num_nonnegative_weights(fe));
|
||||
|
||||
return sequence_labeler<feature_extractor>(weights,fe);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user