Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Added DomainAdaptationMulticlassLibLinear
  • Loading branch information
lisitsyn committed May 18, 2012
1 parent 88f1152 commit 33fc1e4
Show file tree
Hide file tree
Showing 10 changed files with 276 additions and 20 deletions.
2 changes: 2 additions & 0 deletions src/interfaces/modular/Transfer.i
Expand Up @@ -21,6 +21,7 @@
%rename(DomainAdaptationSVM) CDomainAdaptationSVM;
#endif //USE_SVMLIGHT
%rename(DomainAdaptationSVMLinear) CDomainAdaptationSVMLinear;
%rename(DomainAdaptationMulticlassLibLinear) CDomainAdaptationMulticlassLibLinear;

/* Multitask includes */
%include <shogun/transfer/multitask/MultitaskKernelNormalizer.h>
Expand All @@ -35,3 +36,4 @@
%include <shogun/transfer/domain_adaptation/DomainAdaptationSVM.h>
#endif // USE_SVMLIGHT
%include <shogun/transfer/domain_adaptation/DomainAdaptationSVMLinear.h>
%include <shogun/transfer/domain_adaptation/DomainAdaptationMulticlassLibLinear.h>
1 change: 1 addition & 0 deletions src/interfaces/modular/Transfer_includes.i
Expand Up @@ -10,4 +10,5 @@
#include <shogun/transfer/domain_adaptation/DomainAdaptationSVM.h>
#endif /* USE_SVMLIGHT */
#include <shogun/transfer/domain_adaptation/DomainAdaptationSVMLinear.h>
#include <shogun/transfer/domain_adaptation/DomainAdaptationMulticlassLibLinear.h>
%}
20 changes: 16 additions & 4 deletions src/shogun/lib/external/shogun_liblinear.cpp
Expand Up @@ -342,8 +342,8 @@ void l2r_l2_svc_fun::subXTv(double *v, double *XTv)
// To support weights for instances, use GETI(i) (i)

Solver_MCSVM_CS::Solver_MCSVM_CS(const problem *p, int n_class,
double *weighted_C, double epsilon,
int max_it, double max_time,
double *weighted_C, double *w0,
double epsilon, int max_it, double max_time,
mcsvm_state* given_state)
{
this->w_size = p->n;
Expand All @@ -353,6 +353,7 @@ Solver_MCSVM_CS::Solver_MCSVM_CS(const problem *p, int n_class,
this->max_iter = max_it;
this->prob = p;
this->C = weighted_C;
this->w0 = w0;
this->max_train_time = max_time;
this->state = given_state;
}
Expand Down Expand Up @@ -505,9 +506,18 @@ void Solver_MCSVM_CS::solve()
if (prob->use_bias)
{
double *w_i = &w[(w_size-1)*nr_class];
for(m=0;m<active_size_i[i];m++)
for(m=0; m<active_size_i[i]; m++)
G[m] += w_i[alpha_index_i[m]];
}
if (w0)
{
for (k=0; k<dim; k++)
{
double *w0_i = &w0[k*nr_class];
for(m=0; m<active_size_i[i]; m++)
G[m] += w0_i[alpha_index_i[m]];
}
}
// ***

double minG = CMath::INFTY;
Expand Down Expand Up @@ -600,10 +610,12 @@ void Solver_MCSVM_CS::solve()
}

iter++;
/*
if(iter % 10 == 0)
{
SG_SINFO(".");
}
*/

if(stopping < eps_shrink)
{
Expand All @@ -614,7 +626,7 @@ void Solver_MCSVM_CS::solve()
active_size = l;
for(i=0;i<l;i++)
active_size_i[i] = nr_class;
SG_SINFO("*");
//SG_SINFO("*");
eps_shrink = CMath::max(eps_shrink/2, eps);
start_from_all = true;
}
Expand Down
3 changes: 2 additions & 1 deletion src/shogun/lib/external/shogun_liblinear.h
Expand Up @@ -285,7 +285,7 @@ class Solver_MCSVM_CS
{
public:
Solver_MCSVM_CS(const problem *prob, int nr_class, double *C,
double eps, int max_iter,
double *w0, double eps, int max_iter,
double train_time, mcsvm_state* given_state);
~Solver_MCSVM_CS();
void solve();
Expand All @@ -298,6 +298,7 @@ class Solver_MCSVM_CS
int max_iter;
double eps;
double max_train_time;
double* w0;
const problem *prob;
mcsvm_state* state;
};
Expand Down
33 changes: 21 additions & 12 deletions src/shogun/machine/MulticlassMachine.cpp
Expand Up @@ -73,6 +73,23 @@ CLabels* CMulticlassMachine::apply(CFeatures* features)
return apply();
}

CLabels* CMulticlassMachine::get_submachine_outputs(int32_t i)
{
CMachine *machine = (CMachine*)m_machines->get_element(i);
ASSERT(machine);
CLabels* output = machine->apply();
SG_UNREF(machine);
return output;
}

float64_t CMulticlassMachine::get_submachine_output(int32_t i, int32_t num)
{
CMachine *machine = get_machine(i);
float64_t output = machine->apply(num);
SG_UNREF(machine);
return output;
}

CLabels* CMulticlassMachine::apply()
{
/** Ensure that m_machines have the features set */
Expand All @@ -89,12 +106,7 @@ CLabels* CMulticlassMachine::apply()
CLabels** outputs=SG_MALLOC(CLabels*, num_machines);

for (int32_t i=0; i < num_machines; ++i)
{
CMachine *machine = (CMachine*)m_machines->get_element(i);
ASSERT(machine);
outputs[i]=machine->apply();
SG_UNREF(machine);
}
outputs[i] = get_submachine_outputs(i);

SGVector<float64_t> output_for_i(num_machines);
for (int32_t i=0; i<num_vectors; i++)
Expand All @@ -114,6 +126,7 @@ CLabels* CMulticlassMachine::apply()
}
else
{
SG_ERROR("Not ready");
return NULL;
}
}
Expand Down Expand Up @@ -165,12 +178,8 @@ float64_t CMulticlassMachine::apply(int32_t num)
ASSERT(m_machines->get_num_elements()>0);
SGVector<float64_t> outputs(m_machines->get_num_elements());

for (int32_t i=0; i < m_machines->get_num_elements(); ++i)
{
CMachine *machine = get_machine(i);
outputs[i]=machine->apply(num);
SG_UNREF(machine);
}
for (int32_t i=0; i < m_machines->get_num_elements(); i++)
outputs[i] = get_submachine_output(i, num);

float64_t result=m_multiclass_strategy->decide_label(outputs);

Expand Down
13 changes: 13 additions & 0 deletions src/shogun/machine/MulticlassMachine.h
Expand Up @@ -80,6 +80,19 @@ class CMulticlassMachine : public CMachine
return m_machines->get_num_elements();
}

/** get outputs of i-th submachine
* @param i number of submachine
* @return outputs
*/
virtual CLabels* get_submachine_outputs(int32_t i);

/** get output of i-th submachine for num-th vector
* @param i number of submachine
* @param num number of feature vector
* @return output
*/
virtual float64_t get_submachine_output(int32_t i, int32_t num);

/** classify all examples
*
* @return resulting labels
Expand Down
13 changes: 10 additions & 3 deletions src/shogun/multiclass/MulticlassLibLinear.cpp
Expand Up @@ -81,6 +81,11 @@ SGVector<int32_t> CMulticlassLibLinear::get_support_vectors() const
return SGVector<int32_t>(nz_idxs.begin,num_nz);
}

SGMatrix<float64_t> CMulticlassLibLinear::obtain_regularizer_matrix() const
{
return SGMatrix<float64_t>();
}

bool CMulticlassLibLinear::train_machine(CFeatures* data)
{
if (data)
Expand All @@ -104,27 +109,29 @@ bool CMulticlassLibLinear::train_machine(CFeatures* data)
mc_problem.x = m_features;
mc_problem.use_bias = m_use_bias;

SGMatrix<float64_t> w0 = obtain_regularizer_matrix();

if (!m_train_state)
m_train_state = new mcsvm_state();

float64_t* C = SG_MALLOC(float64_t, num_vectors);
for (int32_t i=0; i<num_vectors; i++)
C[i] = m_C;

Solver_MCSVM_CS solver(&mc_problem,num_classes,C,m_epsilon,
Solver_MCSVM_CS solver(&mc_problem,num_classes,C,w0.matrix,m_epsilon,
m_max_iter,m_max_train_time,m_train_state);
solver.solve();

m_machines->reset_array();
for (int32_t i=0; i<num_classes; i++)
{
CLinearMachine* machine = new CLinearMachine();
float64_t* cw = SG_MALLOC(float64_t, mc_problem.n);
SGVector<float64_t> cw(mc_problem.n);

for (int32_t j=0; j<mc_problem.n-bias_n; j++)
cw[j] = m_train_state->w[j*num_classes+i];

machine->set_w(SGVector<float64_t>(cw,mc_problem.n-bias_n));
machine->set_w(cw);

if (m_use_bias)
machine->set_bias(m_train_state->w[(mc_problem.n-bias_n)*num_classes+i]);
Expand Down
3 changes: 3 additions & 0 deletions src/shogun/multiclass/MulticlassLibLinear.h
Expand Up @@ -145,6 +145,9 @@ class CMulticlassLibLinear : public CLinearMulticlassMachine
/** train machine */
virtual bool train_machine(CFeatures* data = NULL);

/** obtain regularizer (w0) matrix */
virtual SGMatrix<float64_t> obtain_regularizer_matrix() const;

private:

/** init defaults */
Expand Down
@@ -0,0 +1,122 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* Written (W) 2012 Sergey Lisitsyn
* Copyright (C) 2012 Sergey Lisitsyn
*/

#include <shogun/lib/config.h>
#ifdef HAVE_LAPACK
#include <shogun/transfer/domain_adaptation/DomainAdaptationMulticlassLibLinear.h>

using namespace shogun;

CDomainAdaptationMulticlassLibLinear::CDomainAdaptationMulticlassLibLinear() :
CMulticlassLibLinear()
{
init_defaults();
}

CDomainAdaptationMulticlassLibLinear::CDomainAdaptationMulticlassLibLinear(
float64_t target_C, CDotFeatures* target_features, CLabels* target_labels,
CLinearMulticlassMachine* source_machine) :
CMulticlassLibLinear(target_C,target_features,target_labels)
{
init_defaults();

set_source_machine(source_machine);
}

void CDomainAdaptationMulticlassLibLinear::init_defaults()
{
m_train_factor = 1.0;
m_source_bias = 0.5;
m_source_machine = NULL;

register_parameters();
}

float64_t CDomainAdaptationMulticlassLibLinear::get_source_bias() const
{
return m_source_bias;
}

void CDomainAdaptationMulticlassLibLinear::set_source_bias(float64_t source_bias)
{
m_source_bias = source_bias;
}

float64_t CDomainAdaptationMulticlassLibLinear::get_train_factor() const
{
return m_train_factor;
}

void CDomainAdaptationMulticlassLibLinear::set_train_factor(float64_t train_factor)
{
m_train_factor = train_factor;
}

CLinearMulticlassMachine* CDomainAdaptationMulticlassLibLinear::get_source_machine() const
{
SG_REF(m_source_machine);
return m_source_machine;
}

void CDomainAdaptationMulticlassLibLinear::set_source_machine(
CLinearMulticlassMachine* source_machine)
{
SG_UNREF(m_source_machine);
SG_REF(source_machine);
m_source_machine = source_machine;
}

void CDomainAdaptationMulticlassLibLinear::register_parameters()
{
SG_ADD((CSGObject**)&m_source_machine, "source_machine", "source domain machine",
MS_NOT_AVAILABLE);
SG_ADD(&m_train_factor, "train_factor", "factor of target domain regularization",
MS_AVAILABLE);
SG_ADD(&m_source_bias, "source_bias", "bias to source domain",
MS_AVAILABLE);
}

CDomainAdaptationMulticlassLibLinear::~CDomainAdaptationMulticlassLibLinear()
{
}

SGMatrix<float64_t> CDomainAdaptationMulticlassLibLinear::obtain_regularizer_matrix() const
{
ASSERT(get_use_bias()==false);
int32_t n_classes = m_source_machine->get_labels()->get_num_classes();
int32_t n_features = ((CDotFeatures*)m_source_machine->get_features())->get_dim_feature_space();
SGMatrix<float64_t> w0(n_classes,n_features);

for (int32_t i=0; i<n_classes; i++)
{
SGVector<float64_t> w = ((CLinearMachine*)m_source_machine->get_machine(i))->get_w();
for (int32_t j=0; j<n_features; j++)
w0(j,i) = m_train_factor*w[j];
}

return w0;
}

CLabels* CDomainAdaptationMulticlassLibLinear::get_submachine_outputs(int32_t i)
{
CLabels* target_outputs = CMulticlassMachine::get_submachine_outputs(i);
CLabels* source_outputs = m_source_machine->get_submachine_outputs(i);
int32_t n_target_outputs = target_outputs->get_num_labels();
ASSERT(n_target_outputs==source_outputs->get_num_labels());
SGVector<float64_t> result(n_target_outputs);
for (int32_t j=0; j<result.vlen; j++)
result[j] = (1-m_source_bias)*target_outputs->get_label(j) + m_source_bias*source_outputs->get_label(j);

SG_UNREF(target_outputs);
SG_UNREF(source_outputs);

return new CLabels(result);
}
#endif /* HAVE_LAPACK */

0 comments on commit 33fc1e4

Please sign in to comment.