Skip to content

Commit

Permalink
port MKL examples to new API (#4271)
Browse files Browse the repository at this point in the history
-add various default ctors
-make CombinedKernel's has_property lazy evaluated and recursive
-register parameters by base class
-add binary_labels conversion to MKLClassification
-update integration test data
  • Loading branch information
karlnapf committed May 3, 2018
1 parent cfcf847 commit c461f9c
Show file tree
Hide file tree
Showing 10 changed files with 97 additions and 64 deletions.
2 changes: 1 addition & 1 deletion data
40 changes: 19 additions & 21 deletions examples/meta/src/binary/multiple_kernel_learning.sg
@@ -1,49 +1,47 @@
CSVFile f_feats_train("../../data/classifier_binary_2d_nonlinear_features_train.dat")
CSVFile f_feats_test("../../data/classifier_binary_2d_nonlinear_features_test.dat")
CSVFile f_labels_train("../../data/classifier_binary_2d_nonlinear_labels_train.dat")
CSVFile f_labels_test("../../data/classifier_binary_2d_nonlinear_labels_test.dat")
File f_feats_train = csv_file("../../data/classifier_binary_2d_nonlinear_features_train.dat")
File f_feats_test = csv_file("../../data/classifier_binary_2d_nonlinear_features_test.dat")
File f_labels_train = csv_file("../../data/classifier_binary_2d_nonlinear_labels_train.dat")
File f_labels_test = csv_file("../../data/classifier_binary_2d_nonlinear_labels_test.dat")

#![create_features]
Features features_train = features(f_feats_train)
Features features_test = features(f_feats_test)
BinaryLabels labels_train(f_labels_train)
BinaryLabels labels_test(f_labels_test)
Labels labels_train = labels(f_labels_train)
Labels labels_test = labels(f_labels_test)
#![create_features]

#![create_kernel]
PolyKernel poly_kernel(10,2)
GaussianKernel gauss_kernel_1(2.0)
GaussianKernel gauss_kernel_2(3.0)
Kernel poly_kernel = kernel("PolyKernel", degree=2)
Kernel gauss_kernel_1 = kernel("GaussianKernel", log_width=0.0)
Kernel gauss_kernel_2 = kernel("GaussianKernel", log_width=1.0)
#![create_kernel]

#![create_combined_train]
CombinedKernel combined_kernel()
combined_kernel.append_kernel(poly_kernel)
combined_kernel.append_kernel(gauss_kernel_1)
combined_kernel.append_kernel(gauss_kernel_2)
Kernel combined_kernel = kernel("CombinedKernel")
combined_kernel.add("kernel_array", poly_kernel)
combined_kernel.add("kernel_array", gauss_kernel_1)
combined_kernel.add("kernel_array", gauss_kernel_2)
combined_kernel.init(features_train, features_train)
#![create_combined_train]

#![train_mkl]
MKLClassification mkl()
mkl.set_kernel(combined_kernel)
mkl.set_labels(labels_train)
Machine mkl = machine("MKLClassification", kernel=combined_kernel, labels=labels_train)
mkl.train()
#![train_mkl]

#![extract_weights]
RealVector beta = combined_kernel.get_subkernel_weights()
RealVector alpha = mkl.get_alphas()
real bias = mkl.get_bias()
RealVector alpha = mkl.get_real_vector("m_alpha")
real bias = mkl.get_real("m_bias")
#![extract_weights]

#![create_combined_test]
combined_kernel.init(features_train, features_test)
#![create_combined_test]

#![mkl_apply]
mkl.set_kernel(combined_kernel)
BinaryLabels labels_predict = mkl.apply_binary()
mkl.put("kernel", combined_kernel)
Labels labels_predict = mkl.apply()
#![mkl_apply]

#![evaluate_accuracy]
Expand All @@ -52,4 +50,4 @@ real accuracy = eval.evaluate(labels_predict, labels_test)
#![evaluate_accuracy]

# additional integration testing variables
RealVector output = labels_predict.get_labels()
RealVector output = labels_predict.get_real_vector("labels")
42 changes: 20 additions & 22 deletions examples/meta/src/regression/multiple_kernel_learning.sg
@@ -1,51 +1,49 @@
CSVFile f_feats_train("../../data/regression_1d_sinc_features_train.dat")
CSVFile f_feats_test("../../data/regression_1d_sinc_features_test.dat")
CSVFile f_labels_train("../../data/regression_1d_sinc_labels_train.dat")
CSVFile f_labels_test("../../data/regression_1d_sinc_labels_test.dat")
File f_feats_train = csv_file("../../data/regression_1d_sinc_features_train.dat")
File f_feats_test = csv_file("../../data/regression_1d_sinc_features_test.dat")
File f_labels_train = csv_file("../../data/regression_1d_sinc_labels_train.dat")
File f_labels_test = csv_file("../../data/regression_1d_sinc_labels_test.dat")

#![create_features]
Features features_train = features(f_feats_train)
Features features_test = features(f_feats_test)
RegressionLabels labels_train(f_labels_train)
RegressionLabels labels_test(f_labels_test)
Labels labels_train = labels(f_labels_train)
Labels labels_test = labels(f_labels_test)
#![create_features]

#![create_kernel]
PolyKernel poly_kernel(10,2)
GaussianKernel gauss_kernel_1(2.0)
GaussianKernel gauss_kernel_2(3.0)
Kernel poly_kernel = kernel("PolyKernel", degree=2)
Kernel gauss_kernel_1 = kernel("GaussianKernel", log_width=0.0)
Kernel gauss_kernel_2 = kernel("GaussianKernel", log_width=1.0)
#![create_kernel]

#![create_combined_train]
CombinedKernel combined_kernel()
combined_kernel.append_kernel(poly_kernel)
combined_kernel.append_kernel(gauss_kernel_1)
combined_kernel.append_kernel(gauss_kernel_2)
Kernel combined_kernel = kernel("CombinedKernel")
combined_kernel.add("kernel_array", poly_kernel)
combined_kernel.add("kernel_array", gauss_kernel_1)
combined_kernel.add("kernel_array", gauss_kernel_2)
combined_kernel.init(features_train, features_train)
#![create_combined_train]

#![train_mkl]
SVRLight binary_svm_solver()
MKLRegression mkl(binary_svm_solver)
mkl.set_kernel(combined_kernel)
mkl.set_labels(labels_train)
Machine binary_svm_solver = machine("SVRLight")
Machine mkl = machine("MKLRegression", svm=binary_svm_solver, kernel=combined_kernel, labels=labels_train)
mkl.train()
#![train_mkl]

#![extract_weights]
RealVector beta = combined_kernel.get_subkernel_weights()
RealVector alpha = mkl.get_alphas()
RealVector alpha = mkl.get_real_vector("m_alpha")
#![extract_weights]

#![mkl_apply]
combined_kernel.init(features_train, features_test)
RegressionLabels labels_predict = mkl.apply_regression()
Labels labels_predict = mkl.apply()
#![mkl_apply]

#![evaluate_error]
MeanSquaredError error()
real mse = error.evaluate(labels_predict, labels_test)
Evaluation eval = evaluation("MeanSquaredError")
real mse = eval.evaluate(labels_predict, labels_test)
#![evaluate_error]

# additional integration testing variables
RealVector output = labels_predict.get_labels()
RealVector output = labels_predict.get_real_vector("labels")
2 changes: 1 addition & 1 deletion src/shogun/classifier/mkl/MKL.cpp
Expand Up @@ -271,7 +271,7 @@ void CMKL::register_params()
rho = 0;
lp_initialized = false;

SG_ADD((CSGObject**) &svm, "svm", "wrapper svm", MS_NOT_AVAILABLE);
SG_ADD((CMachine**)&svm, "svm", "wrapper svm", MS_NOT_AVAILABLE);
SG_ADD(&C_mkl, "C_mkl", "C mkl", MS_NOT_AVAILABLE);
SG_ADD(&mkl_norm, "mkl_norm", "norm used in mkl", MS_NOT_AVAILABLE);
SG_ADD(&ent_lambda, "ent_lambda", "elastic net sparsity trade-off parameter", MS_NOT_AVAILABLE);
Expand Down
3 changes: 1 addition & 2 deletions src/shogun/classifier/mkl/MKLClassification.cpp
Expand Up @@ -36,7 +36,6 @@ void CMKLClassification::init_training()
{
REQUIRE(m_labels, "Labels not set.\n");
REQUIRE(m_labels->get_num_labels(), "Number of labels is zero.\n");
REQUIRE(m_labels->get_label_type() == LT_BINARY, "Labels must be binary.\n");
}

CMKLClassification* CMKLClassification::obtain_from_generic(CMachine* machine)
Expand All @@ -50,4 +49,4 @@ CMKLClassification* CMKLClassification::obtain_from_generic(CMachine* machine)
CMKLClassification* casted = dynamic_cast<CMKLClassification*>(machine);
SG_REF(casted)
return casted;
}
}
4 changes: 2 additions & 2 deletions src/shogun/classifier/svm/SVMLight.cpp
Expand Up @@ -230,7 +230,6 @@ bool CSVMLight::train_machine(CFeatures* data)
SG_ERROR("SVM_light can not proceed without initialized kernel!\n")

ASSERT(m_labels && m_labels->get_num_labels())
ASSERT(m_labels->get_label_type() == LT_BINARY)
ASSERT(kernel->get_num_vec_lhs()==m_labels->get_num_labels())

// in case of LINADD enabled kernels cleanup!
Expand Down Expand Up @@ -310,7 +309,8 @@ void CSVMLight::svm_learn()
int32_t iterations;
int32_t trainpos=0, trainneg=0 ;
ASSERT(m_labels)
SGVector<int32_t> lab=((CBinaryLabels*) m_labels)->get_int_labels();

SGVector<int32_t> lab = binary_labels(m_labels)->get_int_labels();
int32_t totdoc=lab.vlen;
ASSERT(lab.vector && lab.vlen)
int32_t* label=SGVector<int32_t>::clone_vector(lab.vector, lab.vlen);
Expand Down
13 changes: 6 additions & 7 deletions src/shogun/kernel/CombinedKernel.cpp
Expand Up @@ -22,15 +22,15 @@
using namespace shogun;
using namespace Eigen;

CCombinedKernel::CCombinedKernel() : CKernel()
{
init();
}

CCombinedKernel::CCombinedKernel(int32_t size, bool asw)
: CKernel(size), append_subkernel_weights(asw)
{
init();

if (append_subkernel_weights)
SG_INFO("(subkernel weights are appended)\n")

SG_INFO("Combined kernel created (%p)\n", this)
}

CCombinedKernel::~CCombinedKernel()
Expand All @@ -40,8 +40,6 @@ CCombinedKernel::~CCombinedKernel()

cleanup();
SG_UNREF(kernel_array);

SG_INFO("Combined kernel deleted (%p).\n", this)
}

void CCombinedKernel::init_subkernel_weights()
Expand Down Expand Up @@ -736,6 +734,7 @@ void CCombinedKernel::init()
sv_weight=NULL;
subkernel_weights_buffer=NULL;
initialized=false;
append_subkernel_weights = false;

properties |= KP_LINADD | KP_KERNCOMBINATION | KP_BATCHEVALUATION;
kernel_array=new CDynamicObjectArray();
Expand Down
31 changes: 30 additions & 1 deletion src/shogun/kernel/CombinedKernel.h
Expand Up @@ -46,13 +46,16 @@ class CListElement;
class CCombinedKernel : public CKernel
{
public:
/** Default constructor */
CCombinedKernel();

/** constructor
*
* @param size cache size
* @param append_subkernel_weights if subkernel weights shall be
* appended
*/
CCombinedKernel(int32_t size=10, bool append_subkernel_weights=false);
CCombinedKernel(int32_t size, bool append_subkernel_weights);

virtual ~CCombinedKernel();

Expand Down Expand Up @@ -158,6 +161,32 @@ class CCombinedKernel : public CKernel
return kernel_array->insert_element(k, idx);
}

/** check if all sub-kernels have given property
*
* @param p kernel property
* @return if kernel has given property
*/
virtual bool has_property(EKernelProperty p) override

This comment has been minimized.

Copy link
@vigsterkr

vigsterkr May 4, 2018

Member

@karlnapf when you add to an old class a function that overrides a virtual method with override then the compiler will complain - warning - that other virtual methods are not declared with override, see:

../src/shogun/kernel/CombinedKernel.h:313:21: warning: 'compute_optimized' overrides a member function but is not marked 'override' [-Winconsistent-missing-override]
                virtual float64_t compute_optimized(int32_t idx);
                                  ^
../src/shogun/kernel/Kernel.h:784:21: note: overridden virtual function is here
                virtual float64_t compute_optimized(int32_t vector_idx);
                                  ^

so when patching an old class either declare virtual functions everywhere with override or use the old construct of virtual.... but plz dont mix it

{
if (p != KP_LINADD)
return CKernel::has_property(p);

if (!kernel_array || !kernel_array->get_num_elements())
return false;

bool all_linadd = true;
for (auto i : range(kernel_array->get_num_elements()))
{
auto cur = kernel_array->get_element(i);
all_linadd &= ((CKernel*)cur)->has_property(p);
SG_UNREF(cur);
if (!all_linadd)
break;
}

return all_linadd;
}

/** append kernel to the end of the array
*
* @param k kernel
Expand Down
5 changes: 4 additions & 1 deletion src/shogun/kernel/Kernel.h
Expand Up @@ -718,7 +718,10 @@ class CKernel : public CSGObject
* @param p kernel property
* @return if kernel has given property
*/
inline bool has_property(EKernelProperty p) { return (properties & p) != 0; }
inline virtual bool has_property(EKernelProperty p)

This comment has been minimized.

Copy link
@vigsterkr

vigsterkr May 4, 2018

Member

SG_FORCED_INLINE macro plz

{
return (properties & p) != 0;
}

/** for optimizable kernels, i.e. kernels where the weight
* vector can be computed explicitly (if it fits into memory)
Expand Down
19 changes: 13 additions & 6 deletions src/shogun/kernel/PolyKernel.cpp
Expand Up @@ -13,24 +13,28 @@

using namespace shogun;

CPolyKernel::CPolyKernel()
: CDotKernel(0), degree(0), inhomogene(false)
CPolyKernel::CPolyKernel() : CDotKernel(0)
{
init();

}

CPolyKernel::CPolyKernel(int32_t size, int32_t d, bool i)
: CDotKernel(size), degree(d), inhomogene(i)
CPolyKernel::CPolyKernel(int32_t size, int32_t d, bool i) : CDotKernel(size)
{
init();
degree = d;
inhomogene = i;
}

CPolyKernel::CPolyKernel(
CDotFeatures* l, CDotFeatures* r, int32_t d, bool i, int32_t size)
: CDotKernel(size), degree(d), inhomogene(i)
CDotFeatures* l, CDotFeatures* r, int32_t d, bool i, int32_t size)
: CDotKernel(size)
{
init();

degree = d;
inhomogene = i;

init(l,r);
}

Expand Down Expand Up @@ -62,6 +66,9 @@ float64_t CPolyKernel::compute(int32_t idx_a, int32_t idx_b)

void CPolyKernel::init()
{
degree = 0;
inhomogene = false;

set_normalizer(new CSqrtDiagKernelNormalizer());
SG_ADD(&degree, "degree", "Degree of polynomial kernel", MS_AVAILABLE);
SG_ADD(&inhomogene, "inhomogene", "If kernel is inhomogeneous.",
Expand Down

0 comments on commit c461f9c

Please sign in to comment.