681 lines
17 KiB
C++
681 lines
17 KiB
C++
// Copyright (C) 2007 Davis E. King (davis@dlib.net)
|
|
// License: Boost Software License See LICENSE.txt for the full license.
|
|
#undef DLIB_SVm_KERNEL_ABSTRACT_
|
|
#ifdef DLIB_SVm_KERNEL_ABSTRACT_
|
|
|
|
#include <cmath>
|
|
#include <limits>
|
|
#include <sstream>
|
|
#include "../matrix/matrix_abstract.h"
|
|
#include "../algs.h"
|
|
#include "../serialize.h"
|
|
|
|
namespace dlib
|
|
{
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
// ----------------------------------------------------------------------------------------
|
|
/*!A Kernel_Function_Objects */
|
|
// ----------------------------------------------------------------------------------------
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
/*!
|
|
WHAT IS A KERNEL FUNCTION OBJECT?
|
|
In the context of the dlib library documentation a kernel function object
|
|
is an object with an interface with the following properties:
|
|
- a public typedef named sample_type
|
|
- a public typedef named scalar_type which should be a float, double, or
|
|
long double type.
|
|
- an overloaded operator() that operates on two items of sample_type
|
|
and returns a scalar_type.
|
|
(e.g. scalar_type val = kernel_function(sample1,sample2);
|
|
would be a valid expression)
|
|
- a public typedef named mem_manager_type that is an implementation of
|
|
dlib/memory_manager/memory_manager_kernel_abstract.h or
|
|
dlib/memory_manager_global/memory_manager_global_kernel_abstract.h or
|
|
dlib/memory_manager_stateless/memory_manager_stateless_kernel_abstract.h
|
|
- an overloaded == operator that tells you if two kernels are
|
|
identical or not.
|
|
|
|
THREAD SAFETY
|
|
For a kernel function to be threadsafe it means that it must be safe to
|
|
evaluate an expression like val = kernel_function(sample1,sample2)
|
|
simultaneously from multiple threads, even when the threads operate on the same
|
|
object instances (i.e. kernel_function, sample1, and sample2). The most common
|
|
way to make this safe is to ensure that the kernel function does not mutate any
|
|
data, either in itself or in its arguments.
|
|
|
|
For examples of kernel functions see the following objects
|
|
(e.g. the radial_basis_kernel).
|
|
!*/
|
|
|
|
template <
|
|
typename T
|
|
>
|
|
struct radial_basis_kernel
|
|
{
|
|
/*!
|
|
REQUIREMENTS ON T
|
|
T must be a dlib::matrix object
|
|
|
|
WHAT THIS OBJECT REPRESENTS
|
|
This object represents a radial basis function kernel
|
|
|
|
THREAD SAFETY
|
|
This kernel is threadsafe.
|
|
!*/
|
|
|
|
typedef typename T::type scalar_type;
|
|
typedef T sample_type;
|
|
typedef typename T::mem_manager_type mem_manager_type;
|
|
|
|
const scalar_type gamma;
|
|
|
|
radial_basis_kernel(
|
|
);
|
|
/*!
|
|
ensures
|
|
- #gamma == 0.1
|
|
!*/
|
|
|
|
radial_basis_kernel(
|
|
const radial_basis_kernel& k
|
|
);
|
|
/*!
|
|
ensures
|
|
- #gamma == k.gamma
|
|
!*/
|
|
|
|
radial_basis_kernel(
|
|
const scalar_type g
|
|
);
|
|
/*!
|
|
ensures
|
|
- #gamma == g
|
|
!*/
|
|
|
|
scalar_type operator() (
|
|
const sample_type& a,
|
|
const sample_type& b
|
|
) const;
|
|
/*!
|
|
requires
|
|
- a.nc() == 1
|
|
- b.nc() == 1
|
|
- a.nr() == b.nr()
|
|
ensures
|
|
- returns exp(-gamma * ||a-b||^2)
|
|
!*/
|
|
|
|
radial_basis_kernel& operator= (
|
|
const radial_basis_kernel& k
|
|
);
|
|
/*!
|
|
ensures
|
|
- #gamma = k.gamma
|
|
- returns *this
|
|
!*/
|
|
|
|
bool operator== (
|
|
const radial_basis_kernel& k
|
|
) const;
|
|
/*!
|
|
ensures
|
|
- if (k and *this are identical) then
|
|
- returns true
|
|
- else
|
|
- returns false
|
|
!*/
|
|
|
|
};
|
|
|
|
template <
|
|
typename T
|
|
>
|
|
void serialize (
|
|
const radial_basis_kernel<T>& item,
|
|
std::ostream& out
|
|
);
|
|
/*!
|
|
provides serialization support for radial_basis_kernel
|
|
!*/
|
|
|
|
template <
|
|
typename T
|
|
>
|
|
void deserialize (
|
|
radial_basis_kernel<T>& item,
|
|
std::istream& in
|
|
);
|
|
/*!
|
|
provides deserialization support for radial_basis_kernel
|
|
!*/
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
template <
|
|
typename T
|
|
>
|
|
struct sigmoid_kernel
|
|
{
|
|
/*!
|
|
REQUIREMENTS ON T
|
|
T must be a dlib::matrix object
|
|
|
|
WHAT THIS OBJECT REPRESENTS
|
|
This object represents a sigmoid kernel
|
|
|
|
THREAD SAFETY
|
|
This kernel is threadsafe.
|
|
!*/
|
|
|
|
typedef typename T::type scalar_type;
|
|
typedef T sample_type;
|
|
typedef typename T::mem_manager_type mem_manager_type;
|
|
|
|
const scalar_type gamma;
|
|
const scalar_type coef;
|
|
|
|
sigmoid_kernel(
|
|
);
|
|
/*!
|
|
ensures
|
|
- #gamma == 0.1
|
|
- #coef == -1.0
|
|
!*/
|
|
|
|
sigmoid_kernel(
|
|
const sigmoid_kernel& k
|
|
);
|
|
/*!
|
|
ensures
|
|
- #gamma == k.gamma
|
|
- #coef == k.coef
|
|
!*/
|
|
|
|
sigmoid_kernel(
|
|
const scalar_type g,
|
|
const scalar_type c
|
|
);
|
|
/*!
|
|
ensures
|
|
- #gamma == g
|
|
- #coef == c
|
|
!*/
|
|
|
|
scalar_type operator() (
|
|
const sample_type& a,
|
|
const sample_type& b
|
|
) const;
|
|
/*!
|
|
requires
|
|
- a.nc() == 1
|
|
- b.nc() == 1
|
|
- a.nr() == b.nr()
|
|
ensures
|
|
- returns tanh(gamma*trans(a)*b + coef)
|
|
!*/
|
|
|
|
sigmoid_kernel& operator= (
|
|
const sigmoid_kernel& k
|
|
);
|
|
/*!
|
|
ensures
|
|
- #gamma = k.gamma
|
|
- #coef = k.coef
|
|
- returns *this
|
|
!*/
|
|
|
|
bool operator== (
|
|
const sigmoid_kernel& k
|
|
) const;
|
|
/*!
|
|
ensures
|
|
- if (k and *this are identical) then
|
|
- returns true
|
|
- else
|
|
- returns false
|
|
!*/
|
|
};
|
|
|
|
template <
|
|
typename T
|
|
>
|
|
void serialize (
|
|
const sigmoid_kernel<T>& item,
|
|
std::ostream& out
|
|
);
|
|
/*!
|
|
provides serialization support for sigmoid_kernel
|
|
!*/
|
|
|
|
template <
|
|
typename T
|
|
>
|
|
void deserialize (
|
|
sigmoid_kernel<T>& item,
|
|
std::istream& in
|
|
);
|
|
/*!
|
|
provides deserialization support for sigmoid_kernel
|
|
!*/
|
|
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
template <
|
|
typename T
|
|
>
|
|
struct polynomial_kernel
|
|
{
|
|
/*!
|
|
REQUIREMENTS ON T
|
|
T must be a dlib::matrix object
|
|
|
|
WHAT THIS OBJECT REPRESENTS
|
|
This object represents a polynomial kernel
|
|
|
|
THREAD SAFETY
|
|
This kernel is threadsafe.
|
|
!*/
|
|
|
|
typedef typename T::type scalar_type;
|
|
typedef T sample_type;
|
|
typedef typename T::mem_manager_type mem_manager_type;
|
|
|
|
const scalar_type gamma;
|
|
const scalar_type coef;
|
|
const scalar_type degree;
|
|
|
|
polynomial_kernel(
|
|
);
|
|
/*!
|
|
ensures
|
|
- #gamma == 1
|
|
- #coef == 0
|
|
- #degree == 1
|
|
!*/
|
|
|
|
polynomial_kernel(
|
|
const polynomial_kernel& k
|
|
);
|
|
/*!
|
|
ensures
|
|
- #gamma == k.gamma
|
|
- #coef == k.coef
|
|
- #degree == k.degree
|
|
!*/
|
|
|
|
polynomial_kernel(
|
|
const scalar_type g,
|
|
const scalar_type c,
|
|
const scalar_type d
|
|
);
|
|
/*!
|
|
ensures
|
|
- #gamma == g
|
|
- #coef == c
|
|
- #degree == d
|
|
!*/
|
|
|
|
scalar_type operator() (
|
|
const sample_type& a,
|
|
const sample_type& b
|
|
) const;
|
|
/*!
|
|
requires
|
|
- a.nc() == 1
|
|
- b.nc() == 1
|
|
- a.nr() == b.nr()
|
|
ensures
|
|
- returns pow(gamma*trans(a)*b + coef, degree)
|
|
!*/
|
|
|
|
polynomial_kernel& operator= (
|
|
const polynomial_kernel& k
|
|
);
|
|
/*!
|
|
ensures
|
|
- #gamma = k.gamma
|
|
- #coef = k.coef
|
|
- #degree = k.degree
|
|
- returns *this
|
|
!*/
|
|
|
|
bool operator== (
|
|
const polynomial_kernel& k
|
|
) const;
|
|
/*!
|
|
ensures
|
|
- if (k and *this are identical) then
|
|
- returns true
|
|
- else
|
|
- returns false
|
|
!*/
|
|
};
|
|
|
|
template <
|
|
typename T
|
|
>
|
|
void serialize (
|
|
const polynomial_kernel<T>& item,
|
|
std::ostream& out
|
|
);
|
|
/*!
|
|
provides serialization support for polynomial_kernel
|
|
!*/
|
|
|
|
template <
|
|
typename T
|
|
>
|
|
void deserialize (
|
|
polynomial_kernel<T>& item,
|
|
std::istream& in
|
|
);
|
|
/*!
|
|
provides deserialization support for polynomial_kernel
|
|
!*/
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
template <
|
|
typename T
|
|
>
|
|
struct linear_kernel
|
|
{
|
|
/*!
|
|
REQUIREMENTS ON T
|
|
T must be a dlib::matrix object
|
|
|
|
WHAT THIS OBJECT REPRESENTS
|
|
This object represents a linear function kernel
|
|
|
|
THREAD SAFETY
|
|
This kernel is threadsafe.
|
|
!*/
|
|
|
|
typedef typename T::type scalar_type;
|
|
typedef T sample_type;
|
|
typedef typename T::mem_manager_type mem_manager_type;
|
|
|
|
scalar_type operator() (
|
|
const sample_type& a,
|
|
const sample_type& b
|
|
) const;
|
|
/*!
|
|
requires
|
|
- a.nc() == 1
|
|
- b.nc() == 1
|
|
- a.nr() == b.nr()
|
|
ensures
|
|
- returns trans(a)*b
|
|
!*/
|
|
|
|
bool operator== (
|
|
const linear_kernel& k
|
|
) const;
|
|
/*!
|
|
ensures
|
|
- returns true
|
|
!*/
|
|
};
|
|
|
|
template <
|
|
typename T
|
|
>
|
|
void serialize (
|
|
const linear_kernel<T>& item,
|
|
std::ostream& out
|
|
);
|
|
/*!
|
|
provides serialization support for linear_kernel
|
|
!*/
|
|
|
|
template <
|
|
typename T
|
|
>
|
|
void deserialize (
|
|
linear_kernel<T>& item,
|
|
std::istream& in
|
|
);
|
|
/*!
|
|
provides deserialization support for linear_kernel
|
|
!*/
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
template <
|
|
typename T
|
|
>
|
|
struct histogram_intersection_kernel
|
|
{
|
|
/*!
|
|
REQUIREMENTS ON T
|
|
T must be a dlib::matrix object
|
|
|
|
WHAT THIS OBJECT REPRESENTS
|
|
This object represents a histogram intersection kernel kernel
|
|
|
|
THREAD SAFETY
|
|
This kernel is threadsafe.
|
|
!*/
|
|
|
|
typedef typename T::type scalar_type;
|
|
typedef T sample_type;
|
|
typedef typename T::mem_manager_type mem_manager_type;
|
|
|
|
scalar_type operator() (
|
|
const sample_type& a,
|
|
const sample_type& b
|
|
) const;
|
|
/*!
|
|
requires
|
|
- is_vector(a)
|
|
- is_vector(b)
|
|
- a.size() == b.size()
|
|
- min(a) >= 0
|
|
- min(b) >= 0
|
|
ensures
|
|
- returns sum over all i: std::min(a(i), b(i))
|
|
!*/
|
|
|
|
bool operator== (
|
|
const histogram_intersection_kernel& k
|
|
) const;
|
|
/*!
|
|
ensures
|
|
- returns true
|
|
!*/
|
|
};
|
|
|
|
template <
|
|
typename T
|
|
>
|
|
void serialize (
|
|
const histogram_intersection_kernel<T>& item,
|
|
std::ostream& out
|
|
);
|
|
/*!
|
|
provides serialization support for histogram_intersection_kernel
|
|
!*/
|
|
|
|
template <
|
|
typename T
|
|
>
|
|
void deserialize (
|
|
histogram_intersection_kernel<T>& item,
|
|
std::istream& in
|
|
);
|
|
/*!
|
|
provides deserialization support for histogram_intersection_kernel
|
|
!*/
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
template <
|
|
typename T
|
|
>
|
|
struct offset_kernel
|
|
{
|
|
/*!
|
|
REQUIREMENTS ON T
|
|
T must be a kernel object (e.g. radial_basis_kernel, polynomial_kernel, etc.)
|
|
|
|
WHAT THIS OBJECT REPRESENTS
|
|
This object represents a kernel with a fixed value offset
|
|
added to it.
|
|
|
|
THREAD SAFETY
|
|
This kernel is threadsafe.
|
|
!*/
|
|
|
|
typedef typename T::scalar_type scalar_type;
|
|
typedef typename T::sample_type sample_type;
|
|
typedef typename T::mem_manager_type mem_manager_type;
|
|
|
|
const T kernel;
|
|
const scalar_type offset;
|
|
|
|
offset_kernel(
|
|
);
|
|
/*!
|
|
ensures
|
|
- #offset == 0.01
|
|
!*/
|
|
|
|
offset_kernel(
|
|
const offset_kernel& k
|
|
);
|
|
/*!
|
|
ensures
|
|
- #offset == k.offset
|
|
- #kernel == k.kernel
|
|
!*/
|
|
|
|
offset_kernel(
|
|
const T& k,
|
|
const scalar_type& off
|
|
);
|
|
/*!
|
|
ensures
|
|
- #kernel == k
|
|
- #offset == off
|
|
!*/
|
|
|
|
scalar_type operator() (
|
|
const sample_type& a,
|
|
const sample_type& b
|
|
) const;
|
|
/*!
|
|
ensures
|
|
- returns kernel(a,b) + offset
|
|
!*/
|
|
|
|
offset_kernel& operator= (
|
|
const offset_kernel& k
|
|
);
|
|
/*!
|
|
ensures
|
|
- #offset == k.offset
|
|
- #kernel == k.kernel
|
|
!*/
|
|
|
|
bool operator== (
|
|
const offset_kernel& k
|
|
) const;
|
|
/*!
|
|
ensures
|
|
- if (k and *this are identical) then
|
|
- returns true
|
|
- else
|
|
- returns false
|
|
!*/
|
|
};
|
|
|
|
template <
|
|
typename T
|
|
>
|
|
void serialize (
|
|
const offset_kernel<T>& item,
|
|
std::ostream& out
|
|
);
|
|
/*!
|
|
provides serialization support for offset_kernel
|
|
!*/
|
|
|
|
template <
|
|
typename T
|
|
>
|
|
void deserialize (
|
|
offset_kernel<T>& item,
|
|
std::istream& in
|
|
);
|
|
/*!
|
|
provides deserialization support for offset_kernel
|
|
!*/
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
// ----------------------------------------------------------------------------------------
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
template <
|
|
typename kernel_type
|
|
>
|
|
struct kernel_derivative
|
|
{
|
|
/*!
|
|
REQUIREMENTS ON kernel_type
|
|
kernel_type must be one of the following kernel types:
|
|
- radial_basis_kernel
|
|
- polynomial_kernel
|
|
- sigmoid_kernel
|
|
- linear_kernel
|
|
- offset_kernel
|
|
|
|
WHAT THIS OBJECT REPRESENTS
|
|
This is a function object that computes the derivative of a kernel
|
|
function object.
|
|
|
|
THREAD SAFETY
|
|
It is always safe to use distinct instances of this object in different
|
|
threads. However, when a single instance is shared between threads then
|
|
the following rules apply:
|
|
Instances of this object are allowed to have a mutable cache which is
|
|
used by const member functions. Therefore, it is not safe to use one
|
|
instance of this object from multiple threads (unless protected by a
|
|
mutex).
|
|
!*/
|
|
|
|
typedef typename kernel_type::scalar_type scalar_type;
|
|
typedef typename kernel_type::sample_type sample_type;
|
|
typedef typename kernel_type::mem_manager_type mem_manager_type;
|
|
|
|
kernel_derivative(
|
|
const kernel_type& k_
|
|
);
|
|
/*!
|
|
ensures
|
|
- this object will return derivatives of the kernel object k_
|
|
- #k == k_
|
|
!*/
|
|
|
|
const sample_type operator() (
|
|
const sample_type& x,
|
|
const sample_type& y
|
|
) const;
|
|
/*!
|
|
ensures
|
|
- returns the derivative of k with respect to y.
|
|
!*/
|
|
|
|
const kernel_type& k;
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
}
|
|
|
|
#endif // DLIB_SVm_KERNEL_ABSTRACT_
|
|
|
|
|
|
|