Commit 5009d5d0 authored by Davis King's avatar Davis King

Added a set of kernels that can operate on sparse vectors.

--HG--
extra : convert_revision : svn%3Afdd8eb12-d10e-0410-9acb-85c331704f74/trunk%402949
parent 9b3dca55
......@@ -13,6 +13,7 @@
#include "svm/reduced.h"
#include "svm/rvm.h"
#include "svm/pegasos.h"
#include "svm/sparse_kernel.h"
#endif // DLIB_SVm_HEADER
......
// Copyright (C) 2009 Davis E. King (davisking@users.sourceforge.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_SVm_SPARSE_KERNEL
#define DLIB_SVm_SPARSE_KERNEL
#include "sparse_kernel_abstract.h"
#include <cmath>
#include <limits>
#include "../algs.h"
#include "../serialize.h"
#include "sparse_vector.h"
namespace dlib
{
// ----------------------------------------------------------------------------------------
template <
typename T
>
struct sparse_radial_basis_kernel
{
typedef typename T::value_type::second_type scalar_type;
typedef T sample_type;
typedef dlib::memory_manager<char>::kernel_1a mem_manager_type;
sparse_radial_basis_kernel(const scalar_type g) : gamma(g) {}
sparse_radial_basis_kernel() : gamma(0.1) {}
sparse_radial_basis_kernel(
const sparse_radial_basis_kernel& k
) : gamma(k.gamma) {}
const scalar_type gamma;
scalar_type operator() (
const sample_type& a,
const sample_type& b
) const
{
const scalar_type d = sparse_vector::distance_squared(a,b);
return std::exp(-gamma*d);
}
sparse_radial_basis_kernel& operator= (
const sparse_radial_basis_kernel& k
)
{
const_cast<scalar_type&>(gamma) = k.gamma;
return *this;
}
bool operator== (
const sparse_radial_basis_kernel& k
) const
{
return gamma == k.gamma;
}
};
template <
typename T
>
void serialize (
const sparse_radial_basis_kernel<T>& item,
std::ostream& out
)
{
try
{
serialize(item.gamma, out);
}
catch (serialization_error& e)
{
throw serialization_error(e.info + "\n while serializing object of type sparse_radial_basis_kernel");
}
}
template <
typename T
>
void deserialize (
sparse_radial_basis_kernel<T>& item,
std::istream& in
)
{
typedef typename T::type scalar_type;
try
{
deserialize(const_cast<scalar_type&>(item.gamma), in);
}
catch (serialization_error& e)
{
throw serialization_error(e.info + "\n while deserializing object of type sparse_radial_basis_kernel");
}
}
// ----------------------------------------------------------------------------------------
template <
typename T
>
struct sparse_polynomial_kernel
{
typedef typename T::value_type::second_type scalar_type;
typedef T sample_type;
typedef dlib::memory_manager<char>::kernel_1a mem_manager_type;
sparse_polynomial_kernel(const scalar_type g, const scalar_type c, const scalar_type d) : gamma(g), coef(c), degree(d) {}
sparse_polynomial_kernel() : gamma(1), coef(0), degree(1) {}
sparse_polynomial_kernel(
const sparse_polynomial_kernel& k
) : gamma(k.gamma), coef(k.coef), degree(k.degree) {}
typedef T type;
const scalar_type gamma;
const scalar_type coef;
const scalar_type degree;
scalar_type operator() (
const sample_type& a,
const sample_type& b
) const
{
return std::pow(gamma*(sparse_vector::dot_product(a,b)) + coef, degree);
}
sparse_polynomial_kernel& operator= (
const sparse_polynomial_kernel& k
)
{
const_cast<scalar_type&>(gamma) = k.gamma;
const_cast<scalar_type&>(coef) = k.coef;
const_cast<scalar_type&>(degree) = k.degree;
return *this;
}
bool operator== (
const sparse_polynomial_kernel& k
) const
{
return (gamma == k.gamma) && (coef == k.coef) && (degree == k.degree);
}
};
template <
typename T
>
void serialize (
const sparse_polynomial_kernel<T>& item,
std::ostream& out
)
{
try
{
serialize(item.gamma, out);
serialize(item.coef, out);
serialize(item.degree, out);
}
catch (serialization_error& e)
{
throw serialization_error(e.info + "\n while serializing object of type sparse_polynomial_kernel");
}
}
template <
typename T
>
void deserialize (
sparse_polynomial_kernel<T>& item,
std::istream& in
)
{
typedef typename T::type scalar_type;
try
{
deserialize(const_cast<scalar_type&>(item.gamma), in);
deserialize(const_cast<scalar_type&>(item.coef), in);
deserialize(const_cast<scalar_type&>(item.degree), in);
}
catch (serialization_error& e)
{
throw serialization_error(e.info + "\n while deserializing object of type sparse_polynomial_kernel");
}
}
// ----------------------------------------------------------------------------------------
template <
typename T
>
struct sparse_sigmoid_kernel
{
typedef typename T::value_type::second_type scalar_type;
typedef T sample_type;
typedef dlib::memory_manager<char>::kernel_1a mem_manager_type;
sparse_sigmoid_kernel(const scalar_type g, const scalar_type c) : gamma(g), coef(c) {}
sparse_sigmoid_kernel() : gamma(0.1), coef(-1.0) {}
sparse_sigmoid_kernel(
const sparse_sigmoid_kernel& k
) : gamma(k.gamma), coef(k.coef) {}
typedef T type;
const scalar_type gamma;
const scalar_type coef;
scalar_type operator() (
const sample_type& a,
const sample_type& b
) const
{
return std::tanh(gamma*(sparse_vector::dot_product(a,b)) + coef);
}
sparse_sigmoid_kernel& operator= (
const sparse_sigmoid_kernel& k
)
{
const_cast<scalar_type&>(gamma) = k.gamma;
const_cast<scalar_type&>(coef) = k.coef;
return *this;
}
bool operator== (
const sparse_sigmoid_kernel& k
) const
{
return (gamma == k.gamma) && (coef == k.coef);
}
};
template <
typename T
>
void serialize (
const sparse_sigmoid_kernel<T>& item,
std::ostream& out
)
{
try
{
serialize(item.gamma, out);
serialize(item.coef, out);
}
catch (serialization_error& e)
{
throw serialization_error(e.info + "\n while serializing object of type sparse_sigmoid_kernel");
}
}
template <
typename T
>
void deserialize (
sparse_sigmoid_kernel<T>& item,
std::istream& in
)
{
typedef typename T::type scalar_type;
try
{
deserialize(const_cast<scalar_type&>(item.gamma), in);
deserialize(const_cast<scalar_type&>(item.coef), in);
}
catch (serialization_error& e)
{
throw serialization_error(e.info + "\n while deserializing object of type sparse_sigmoid_kernel");
}
}
// ----------------------------------------------------------------------------------------
template <typename T>
struct sparse_linear_kernel
{
typedef typename T::value_type::second_type scalar_type;
typedef T sample_type;
typedef dlib::memory_manager<char>::kernel_1a mem_manager_type;
scalar_type operator() (
const sample_type& a,
const sample_type& b
) const
{
return sparse_vector::dot_product(a,b);
}
bool operator== (
const sparse_linear_kernel& k
) const
{
return true;
}
};
template <
typename T
>
void serialize (
const sparse_linear_kernel<T>& item,
std::ostream& out
){}
template <
typename T
>
void deserialize (
sparse_linear_kernel<T>& item,
std::istream& in
){}
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_SVm_SPARSE_KERNEL
// Copyright (C) 2009 Davis E. King (davisking@users.sourceforge.net)
// License: Boost Software License See LICENSE.txt for the full license.
#undef DLIB_SVm_SPARSE_KERNEL_ABSTRACT_
#ifdef DLIB_SVm_SPARSE_KERNEL_ABSTRACT_
#include <cmath>
#include <limits>
#include "../algs.h"
#include "../serialize.h"
#include "kernel_abstract.h"
#include "sparse_vector_abstract.h"
namespace dlib
{
// ----------------------------------------------------------------------------------------
template <
typename T
>
struct sparse_radial_basis_kernel
{
/*!
REQUIREMENTS ON T
Must be a sparse vector as defined in dlib/svm/sparse_vector_abstract.h
WHAT THIS OBJECT REPRESENTS
This object represents a radial basis function kernel
that works with sparse vectors.
!*/
typedef typename T::value_type::second_type scalar_type;
typedef T sample_type;
typedef dlib::memory_manager<char>::kernel_1a mem_manager_type;
const scalar_type gamma;
sparse_radial_basis_kernel(
);
/*!
ensures
- #gamma == 0.1
!*/
sparse_radial_basis_kernel(
const sparse_radial_basis_kernel& k
);
/*!
ensures
- #gamma == k.gamma
!*/
sparse_radial_basis_kernel(
const scalar_type g
);
/*!
ensures
- #gamma == g
!*/
scalar_type operator() (
const sample_type& a,
const sample_type& b
) const;
/*!
requires
- a contains a sorted range
- b contains a sorted range
ensures
- returns exp(-gamma * sparse_vector::distance_squared(a,b))
!*/
sparse_radial_basis_kernel& operator= (
const sparse_radial_basis_kernel& k
);
/*!
ensures
- #gamma = k.gamma
- returns *this
!*/
bool operator== (
const sparse_radial_basis_kernel& k
) const;
/*!
ensures
- if (k and *this are identical) then
- returns true
- else
- returns false
!*/
};
template <
typename T
>
void serialize (
const sparse_radial_basis_kernel<T>& item,
std::ostream& out
);
/*!
provides serialization support for sparse_radial_basis_kernel
!*/
template <
typename T
>
void deserialize (
sparse_radial_basis_kernel<T>& item,
std::istream& in
);
/*!
provides deserialization support for sparse_radial_basis_kernel
!*/
// ----------------------------------------------------------------------------------------
template <
typename T
>
struct sparse_sigmoid_kernel
{
/*!
REQUIREMENTS ON T
Must be a sparse vector as defined in dlib/svm/sparse_vector_abstract.h
WHAT THIS OBJECT REPRESENTS
This object represents a sigmoid kernel
that works with sparse vectors.
!*/
typedef typename T::value_type::second_type scalar_type;
typedef T sample_type;
typedef dlib::memory_manager<char>::kernel_1a mem_manager_type;
const scalar_type gamma;
const scalar_type coef;
sparse_sigmoid_kernel(
);
/*!
ensures
- #gamma == 0.1
- #coef == -1.0
!*/
sparse_sigmoid_kernel(
const sparse_sigmoid_kernel& k
);
/*!
ensures
- #gamma == k.gamma
- #coef == k.coef
!*/
sparse_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 contains a sorted range
- b contains a sorted range
ensures
- returns tanh(gamma * sparse_vector::dot(a,b) + coef)
!*/
sparse_sigmoid_kernel& operator= (
const sparse_sigmoid_kernel& k
);
/*!
ensures
- #gamma = k.gamma
- #coef = k.coef
- returns *this
!*/
bool operator== (
const sparse_sigmoid_kernel& k
) const;
/*!
ensures
- if (k and *this are identical) then
- returns true
- else
- returns false
!*/
};
template <
typename T
>
void serialize (
const sparse_sigmoid_kernel<T>& item,
std::ostream& out
);
/*!
provides serialization support for sparse_sigmoid_kernel
!*/
template <
typename T
>
void deserialize (
sparse_sigmoid_kernel<T>& item,
std::istream& in
);
/*!
provides deserialization support for sparse_sigmoid_kernel
!*/
// ----------------------------------------------------------------------------------------
template <
typename T
>
struct sparse_polynomial_kernel
{
/*!
REQUIREMENTS ON T
Must be a sparse vector as defined in dlib/svm/sparse_vector_abstract.h
WHAT THIS OBJECT REPRESENTS
This object represents a polynomial kernel
that works with sparse vectors.
!*/
typedef typename T::value_type::second_type scalar_type;
typedef T sample_type;
typedef dlib::memory_manager<char>::kernel_1a mem_manager_type;
const scalar_type gamma;
const scalar_type coef;
const scalar_type degree;
sparse_polynomial_kernel(
);
/*!
ensures
- #gamma == 1
- #coef == 0
- #degree == 1
!*/
sparse_polynomial_kernel(
const sparse_polynomial_kernel& k
);
/*!
ensures
- #gamma == k.gamma
- #coef == k.coef
- #degree == k.degree
!*/
sparse_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 contains a sorted range
- b contains a sorted range
ensures
- returns pow(gamma * sparse_vector::dot(a,b) + coef, degree)
!*/
sparse_polynomial_kernel& operator= (
const sparse_polynomial_kernel& k
);
/*!
ensures
- #gamma = k.gamma
- #coef = k.coef
- #degree = k.degree
- returns *this
!*/
bool operator== (
const sparse_polynomial_kernel& k
) const;
/*!
ensures
- if (k and *this are identical) then
- returns true
- else
- returns false
!*/
};
template <
typename T
>
void serialize (
const sparse_polynomial_kernel<T>& item,
std::ostream& out
);
/*!
provides serialization support for sparse_polynomial_kernel
!*/
template <
typename T
>
void deserialize (
sparse_polynomial_kernel<T>& item,
std::istream& in
);
/*!
provides deserialization support for sparse_polynomial_kernel
!*/
// ----------------------------------------------------------------------------------------
template <
typename T
>
struct sparse_linear_kernel
{
/*!
REQUIREMENTS ON T
Must be a sparse vector as defined in dlib/svm/sparse_vector_abstract.h
WHAT THIS OBJECT REPRESENTS
This object represents a linear function kernel
that works with sparse vectors.
!*/
typedef typename T::value_type::second_type scalar_type;
typedef T sample_type;
typedef dlib::memory_manager<char>::kernel_1a mem_manager_type;
scalar_type operator() (
const sample_type& a,
const sample_type& b
) const;
/*!
requires
- a contains a sorted range
- b contains a sorted range
ensures
- returns sparse_vector::dot(a,b)
!*/
bool operator== (
const sparse_linear_kernel& k
) const;
/*!
ensures
- returns true
!*/
};
template <
typename T
>
void serialize (
const sparse_linear_kernel<T>& item,
std::ostream& out
);
/*!
provides serialization support for sparse_linear_kernel
!*/
template <
typename T
>
void deserialize (
sparse_linear_kernel<T>& item,
std::istream& in
);
/*!
provides deserialization support for sparse_linear_kernel
!*/
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_SVm_SPARSE_KERNEL_ABSTRACT_
// Copyright (C) 2009 Davis E. King (davisking@users.sourceforge.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_SVm_SPARSE_VECTOR
#define DLIB_SVm_SPARSE_VECTOR
#include "sparse_vector_abstract.h"
#include <cmath>
#include <limits>
#include "../algs.h"
namespace dlib
{
// ----------------------------------------------------------------------------------------
namespace sparse_vector
{
template <typename T, typename U>
typename T::value_type::second_type distance_squared (
const T& a,
const U& b
)
{
typedef typename T::value_type::second_type scalar_type;
typedef typename U::value_type::second_type scalar_typeU;
// Both T and U must contain the same kinds of elements
COMPILE_TIME_ASSERT((is_same_type<scalar_type, scalar_typeU>::value));
typename T::const_iterator ai = a.begin();
typename U::const_iterator bi = b.begin();
scalar_type sum = 0, temp = 0;
while (ai != a.end() && bi != b.end())
{
if (ai->first == bi->first)
{
temp = ai->second - bi->second;
++ai;
++bi;
}
else if (ai->first < bi->first)
{
temp = ai->second;
++ai;
}
else
{
temp = bi->second;
++bi;
}
sum += temp*temp;
}
while (ai != a.end())
{
sum += ai->second*ai->second;
}
while (bi != b.end())
{
sum += bi->second*bi->second;
}
return sum;
}
// ------------------------------------------------------------------------------------
template <typename T, typename U>
typename T::value_type::second_type dot_product (
const T& a,
const U& b
)
{
typedef typename T::value_type::second_type scalar_type;
typedef typename U::value_type::second_type scalar_typeU;
// Both T and U must contain the same kinds of elements
COMPILE_TIME_ASSERT((is_same_type<scalar_type, scalar_typeU>::value));
typename T::const_iterator ai = a.begin();
typename U::const_iterator bi = b.begin();
scalar_type sum = 0;
while (ai != a.end() && bi != b.end())
{
if (ai->first == bi->first)
{
sum += ai->second * bi->second;
++ai;
++bi;
}
else if (ai->first < bi->first)
{
++ai;
}
else
{
++bi;
}
}
return sum;
}
// ------------------------------------------------------------------------------------
template <typename T>
typename T::value_type::second_type length_squared (
const T& a
)
{
typedef typename T::value_type::second_type scalar_type;
typename T::const_iterator i = a.begin();
scalar_type sum = 0;
while (i != a.end())
{
sum += i->second * i->second;
}
return sum;
}
}
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_SVm_SPARSE_VECTOR
// Copyright (C) 2009 Davis E. King (davisking@users.sourceforge.net)
// License: Boost Software License See LICENSE.txt for the full license.
#undef DLIB_SVm_SPARSE_VECTOR_ABSTRACT_
#ifdef DLIB_SVm_SPARSE_VECTOR_ABSTRACT_
#include <cmath>
#include "../algs.h"
#include "../serialize.h"
namespace dlib
{
// ----------------------------------------------------------------------------------------
/*!
In dlib, sparse vectors are represented using the container objects
in the C++ STL. In particular, a sparse vector is any container that
contains a sorted range of std::pair<key, scalar_value> objects where:
- key is any type that can serve as a unique index or identifier (e.g. long)
- scalar_value is float, double, or long double
So examples of valid sparse vectors are:
- std::map<long, double>
- std::vector<std::pair<long, float> > where the vector is sorted.
(you could make sure it was sorted by applying std::sort to it)
This file defines a number of helper functions for doing normal vector
arithmetic things with sparse vectors.
!*/
// ----------------------------------------------------------------------------------------
namespace sparse_vector
{
template <typename T, typename U>
typename T::value_type::second_type distance_squared (
const T& a,
const U& b
);
/*!
requires
- a is a sorted range of std::pair objects
- b is a sorted range of std::pair objects
ensures
- returns the squared distance between the vectors
a and b
!*/
// ----------------------------------------------------------------------------------------
template <typename T, typename U>
typename T::value_type::second_type dot_product (
const T& a,
const U& b
);
/*!
requires
- a is a sorted range of std::pair objects
- b is a sorted range of std::pair objects
ensures
- returns the dot product between the vectors a and b
!*/
// ----------------------------------------------------------------------------------------
template <typename T>
typename T::value_type::second_type length_squared (
const T& a
);
/*!
requires
- a is a sorted range of std::pair objects
- b is a sorted range of std::pair objects
ensures
- returns dot(a,a)
!*/
}
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_SVm_SPARSE_VECTOR_ABSTRACT_
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