Merge pull request #490 from mschoeler:master
This commit is contained in:
commit
9f888fdb97
BIN
modules/ml/doc/pics/SVM_Comparison.png
Normal file
BIN
modules/ml/doc/pics/SVM_Comparison.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 92 KiB |
@ -115,9 +115,13 @@ The constructors.
|
||||
|
||||
* **CvSVM::SIGMOID** Sigmoid kernel: :math:`K(x_i, x_j) = \tanh(\gamma x_i^T x_j + coef0)`.
|
||||
|
||||
* **CvSVM::CHI2** Exponential Chi2 kernel, similar to the RBF kernel: :math:`K(x_i, x_j) = e^{-\gamma \chi^2(x_i,x_j)}, \chi^2(x_i,x_j) = (x_i-x_j)^2/(x_i+x_j), \gamma > 0`.
|
||||
|
||||
* **CvSVM::INTER** Histogram intersection kernel. A fast kernel. :math:`K(x_i, x_j) = min(x_i,x_j)`.
|
||||
|
||||
:param degree: Parameter ``degree`` of a kernel function (POLY).
|
||||
|
||||
:param gamma: Parameter :math:`\gamma` of a kernel function (POLY / RBF / SIGMOID).
|
||||
:param gamma: Parameter :math:`\gamma` of a kernel function (POLY / RBF / SIGMOID / CHI2).
|
||||
|
||||
:param coef0: Parameter ``coef0`` of a kernel function (POLY / SIGMOID).
|
||||
|
||||
@ -142,6 +146,10 @@ The default constructor initialize the structure with following values:
|
||||
term_crit = cvTermCriteria( CV_TERMCRIT_ITER+CV_TERMCRIT_EPS, 1000, FLT_EPSILON );
|
||||
}
|
||||
|
||||
A comparison of different kernels on the following 2D test case with four classes. Four C_SVC SVMs have been trained (one against rest) with auto_train. Evaluation on three different kernels (CHI2, INTER, RBF). The color depicts the class with max score. Bright means max-score > 0, dark means max-score < 0.
|
||||
|
||||
.. image:: pics/SVM_Comparison.png
|
||||
|
||||
|
||||
|
||||
CvSVM
|
||||
|
@ -297,7 +297,7 @@ struct CV_EXPORTS_W_MAP CvSVMParams
|
||||
CV_PROP_RW int svm_type;
|
||||
CV_PROP_RW int kernel_type;
|
||||
CV_PROP_RW double degree; // for poly
|
||||
CV_PROP_RW double gamma; // for poly/rbf/sigmoid
|
||||
CV_PROP_RW double gamma; // for poly/rbf/sigmoid/chi2
|
||||
CV_PROP_RW double coef0; // for poly/sigmoid
|
||||
|
||||
CV_PROP_RW double C; // for CV_SVM_C_SVC, CV_SVM_EPS_SVR and CV_SVM_NU_SVR
|
||||
@ -326,7 +326,10 @@ struct CV_EXPORTS CvSVMKernel
|
||||
virtual void calc_non_rbf_base( int vec_count, int vec_size, const float** vecs,
|
||||
const float* another, float* results,
|
||||
double alpha, double beta );
|
||||
|
||||
virtual void calc_intersec( int vcount, int var_count, const float** vecs,
|
||||
const float* another, float* results );
|
||||
virtual void calc_chi2( int vec_count, int vec_size, const float** vecs,
|
||||
const float* another, float* results );
|
||||
virtual void calc_linear( int vec_count, int vec_size, const float** vecs,
|
||||
const float* another, float* results );
|
||||
virtual void calc_rbf( int vec_count, int vec_size, const float** vecs,
|
||||
@ -456,7 +459,7 @@ public:
|
||||
enum { C_SVC=100, NU_SVC=101, ONE_CLASS=102, EPS_SVR=103, NU_SVR=104 };
|
||||
|
||||
// SVM kernel type
|
||||
enum { LINEAR=0, POLY=1, RBF=2, SIGMOID=3 };
|
||||
enum { LINEAR=0, POLY=1, RBF=2, SIGMOID=3, CHI2=4, INTER=5 };
|
||||
|
||||
// SVM params type
|
||||
enum { C=0, GAMMA=1, P=2, NU=3, COEF=4, DEGREE=5 };
|
||||
|
@ -220,6 +220,8 @@ bool CvSVMKernel::create( const CvSVMParams* _params, Calc _calc_func )
|
||||
calc_func = params->kernel_type == CvSVM::RBF ? &CvSVMKernel::calc_rbf :
|
||||
params->kernel_type == CvSVM::POLY ? &CvSVMKernel::calc_poly :
|
||||
params->kernel_type == CvSVM::SIGMOID ? &CvSVMKernel::calc_sigmoid :
|
||||
params->kernel_type == CvSVM::CHI2 ? &CvSVMKernel::calc_chi2 :
|
||||
params->kernel_type == CvSVM::INTER ? &CvSVMKernel::calc_intersec :
|
||||
&CvSVMKernel::calc_linear;
|
||||
|
||||
return true;
|
||||
@ -318,6 +320,52 @@ void CvSVMKernel::calc_rbf( int vcount, int var_count, const float** vecs,
|
||||
cvExp( &R, &R );
|
||||
}
|
||||
|
||||
/// Histogram intersection kernel
|
||||
void CvSVMKernel::calc_intersec( int vcount, int var_count, const float** vecs,
|
||||
const float* another, Qfloat* results )
|
||||
{
|
||||
int j, k;
|
||||
for( j = 0; j < vcount; j++ )
|
||||
{
|
||||
const float* sample = vecs[j];
|
||||
double s = 0;
|
||||
for( k = 0; k <= var_count - 4; k += 4 )
|
||||
s += min(sample[k],another[k]) + min(sample[k+1],another[k+1]) +
|
||||
min(sample[k+2],another[k+2]) + min(sample[k+3],another[k+3]);
|
||||
for( ; k < var_count; k++ )
|
||||
s += min(sample[k],another[k]);
|
||||
results[j] = (Qfloat)(s);
|
||||
}
|
||||
}
|
||||
|
||||
/// Exponential chi2 kernel
|
||||
void CvSVMKernel::calc_chi2( int vcount, int var_count, const float** vecs,
|
||||
const float* another, Qfloat* results )
|
||||
{
|
||||
CvMat R = cvMat( 1, vcount, QFLOAT_TYPE, results );
|
||||
double gamma = -params->gamma;
|
||||
int j, k;
|
||||
for( j = 0; j < vcount; j++ )
|
||||
{
|
||||
const float* sample = vecs[j];
|
||||
double chi2 = 0;
|
||||
for(k = 0 ; k < var_count; k++ )
|
||||
{
|
||||
double d = sample[k]-another[k];
|
||||
double devisor = sample[k]+another[k];
|
||||
/// if devisor == 0, the Chi2 distance would be zero, but calculation would rise an error because of deviding by zero
|
||||
if (devisor != 0)
|
||||
{
|
||||
chi2 += d*d/devisor;
|
||||
}
|
||||
}
|
||||
results[j] = (Qfloat) (gamma*chi2);
|
||||
}
|
||||
if( vcount > 0 )
|
||||
cvExp( &R, &R );
|
||||
|
||||
|
||||
}
|
||||
|
||||
void CvSVMKernel::calc( int vcount, int var_count, const float** vecs,
|
||||
const float* another, Qfloat* results )
|
||||
@ -1214,7 +1262,8 @@ bool CvSVM::set_params( const CvSVMParams& _params )
|
||||
svm_type = params.svm_type;
|
||||
|
||||
if( kernel_type != LINEAR && kernel_type != POLY &&
|
||||
kernel_type != SIGMOID && kernel_type != RBF )
|
||||
kernel_type != SIGMOID && kernel_type != RBF &&
|
||||
kernel_type != INTER && kernel_type != CHI2)
|
||||
CV_ERROR( CV_StsBadArg, "Unknown/unsupported kernel type" );
|
||||
|
||||
if( kernel_type == LINEAR )
|
||||
|
Loading…
x
Reference in New Issue
Block a user