Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
BMRM training exception fixed + several warning fixes
  • Loading branch information
uricamic committed Aug 16, 2012
1 parent 3ce4fd2 commit 4f930ca
Show file tree
Hide file tree
Showing 12 changed files with 100 additions and 86 deletions.
17 changes: 7 additions & 10 deletions examples/undocumented/python_modular/so_multiclass_BMRM.py
Expand Up @@ -4,7 +4,8 @@

from shogun.Features import RealFeatures
from shogun.Loss import HingeLoss
from shogun.Structure import MulticlassModel, MulticlassSOLabels, RealNumber, DualLibQPBMSOSVM, BMRM, PPBMRM, P3BMRM, MulticlassRiskFunction, MulticlassRiskData
from shogun.Structure import MulticlassModel, MulticlassSOLabels, RealNumber, DualLibQPBMSOSVM
from shogun.Structure import BMRM, PPBMRM, P3BMRM

def gen_data():
np.random.seed(0)
Expand All @@ -20,7 +21,7 @@ def gen_data():
# Number of classes
M = 3
# Number of samples of each class
N = 50
N = 1000
# Dimension of the data
dim = 2

Expand All @@ -32,12 +33,8 @@ def gen_data():
model = MulticlassModel(features, labels)
loss = HingeLoss()

risk = MulticlassRiskFunction()

risk_data = MulticlassRiskData(features, labels, model.get_dim(), features.get_num_vectors())

lambda_ = 1e3
sosvm = DualLibQPBMSOSVM(model, loss, labels, features, lambda_, risk, risk_data)
lambda_ = 1e1
sosvm = DualLibQPBMSOSVM(model, loss, labels, features, lambda_)

sosvm.set_cleanAfter(10) # number of iterations that cutting plane has to be inactive for to be removed
sosvm.set_cleanICP(True) # enables inactive cutting plane removal feature
Expand All @@ -51,11 +48,11 @@ def gen_data():
sosvm.train()

out = sosvm.apply()
count = 0
count = 0.0
for i in xrange(out.get_num_labels()):
yi_pred = RealNumber.obtain_from_generic(out.get_label(i))
if yi_pred.value == y[i]:
count = count + 1
count += 1.0

print "Correct classification rate: %0.2f" % ( 100.0*count/out.get_num_labels() )

6 changes: 3 additions & 3 deletions src/shogun/structure/DualLibQPBMSOSVM.cpp
Expand Up @@ -24,14 +24,14 @@ CDualLibQPBMSOSVM::CDualLibQPBMSOSVM(
CLossFunction* loss,
CStructuredLabels* labs,
CDotFeatures* features,
float64_t lambda,
float64_t _lambda,
SGVector< float64_t > W)
:CLinearStructuredOutputMachine(model, loss, labs, features)
{
set_TolRel(0.001);
set_TolAbs(0.0);
set_BufSize(1000);
set_lambda(lambda);
set_lambda(_lambda);
set_cleanICP(true);
set_cleanAfter(10);
set_K(0.4);
Expand All @@ -52,7 +52,7 @@ CDualLibQPBMSOSVM::CDualLibQPBMSOSVM(
}
else
{
m_w=W;
set_w(W);
}

init();
Expand Down
17 changes: 14 additions & 3 deletions src/shogun/structure/DualLibQPBMSOSVM.h
Expand Up @@ -55,15 +55,15 @@ class CDualLibQPBMSOSVM : public CLinearStructuredOutputMachine
* @param loss Loss function
* @param labs Structured labels
* @param features Feature vectors
* @param lambda Regularization constant
* @param _lambda Regularization constant
* @param W initial solution of weight vector
*/
CDualLibQPBMSOSVM(
CStructuredModel* model,
CLossFunction* loss,
CStructuredLabels* labs,
CDotFeatures* features,
float64_t lambda,
float64_t _lambda,
SGVector< float64_t > W=0);

/** destructor */
Expand All @@ -76,7 +76,7 @@ class CDualLibQPBMSOSVM : public CLinearStructuredOutputMachine
*
* @param lambda Regularization constant
*/
inline void set_lambda(float64_t lambda) { m_lambda=lambda; }
inline void set_lambda(float64_t _lambda) { m_lambda=_lambda; }

/** get lambda
*
Expand Down Expand Up @@ -214,6 +214,17 @@ class CDualLibQPBMSOSVM : public CLinearStructuredOutputMachine
*/
inline void set_solver(ESolver solver) { m_solver=solver; }

/** set initial value of weight vector w
*
* @param W initial weight vector
*/
inline void set_w(SGVector< float64_t > W)
{
REQUIRE(W.vlen == m_model->get_dim(), "Dimension of the initial "
"solution must match the model's dimension!\n");
m_w=W;
}

protected:
/** train dual SO-SVM
*
Expand Down
15 changes: 9 additions & 6 deletions src/shogun/structure/MulticlassModel.cpp
Expand Up @@ -21,7 +21,7 @@ CMulticlassModel::CMulticlassModel()
init();
}

CMulticlassModel::CMulticlassModel(CFeatures* features, CStructuredLabels* labels)
CMulticlassModel::CMulticlassModel(CFeatures* features, CStructuredLabels* labels)
: CStructuredModel(features, labels)
{
init();
Expand All @@ -46,7 +46,7 @@ SGVector< float64_t > CMulticlassModel::get_joint_feature_vector(int32_t feat_id
psi.zero();

SGVector< float64_t > x = ((CDotFeatures*) m_features)->
get_computed_dot_feature_vector(feat_idx);
get_computed_dot_feature_vector(feat_idx);
/* TODO add checks for the casting!! */
float64_t label_value = CRealNumber::obtain_from_generic(y)->value;

Expand All @@ -72,7 +72,7 @@ CResultSet* CMulticlassModel::argmax(
else
{
REQUIRE(m_num_classes > 0, "The model needs to be trained before "
"using it for prediction\n");
"using it for prediction\n");
}

ASSERT(feats_dim*m_num_classes == w.vlen);
Expand All @@ -81,7 +81,7 @@ CResultSet* CMulticlassModel::argmax(

float64_t score = 0, ypred = 0;
float64_t max_score = df->dense_dot(feat_idx, w.vector, feats_dim);

for ( int32_t c = 1 ; c < m_num_classes ; ++c )
{
score = df->dense_dot(feat_idx, w.vector+c*feats_dim, feats_dim);
Expand Down Expand Up @@ -142,16 +142,19 @@ void CMulticlassModel::init()
float64_t CMulticlassModel::risk(float64_t* subgrad, float64_t* W, TMultipleCPinfo* info)
{
CDotFeatures* X=(CDotFeatures*)m_features;
CMulticlassSOLabels* y=(CMulticlassSOLabels*)m_features;
CMulticlassSOLabels* y=(CMulticlassSOLabels*)m_labels;
m_num_classes = y->get_num_classes();
uint32_t from, to;

if (info)
{
from=info->from;
from=info->_from;
to=(info->N == 0) ? X->get_num_vectors() : from+info->N;
} else {
from=0;
to=X->get_num_vectors();
}

uint32_t num_classes=y->get_num_classes();
uint32_t feats_dim=X->get_dim_feature_space();
const uint32_t w_dim=get_dim();
Expand Down
13 changes: 7 additions & 6 deletions src/shogun/structure/StructuredModel.cpp
Expand Up @@ -76,7 +76,7 @@ CFeatures* CStructuredModel::get_features()
}

SGVector< float64_t > CStructuredModel::get_joint_feature_vector(
int32_t feat_idx,
int32_t feat_idx,
int32_t lab_idx)
{
CStructuredData* label = m_labels->get_label(lab_idx);
Expand All @@ -87,11 +87,11 @@ SGVector< float64_t > CStructuredModel::get_joint_feature_vector(
}

SGVector< float64_t > CStructuredModel::get_joint_feature_vector(
int32_t feat_idx,
int32_t feat_idx,
CStructuredData* y)
{
SG_ERROR("compute_joint_feature(int32_t, CStructuredData*) is not "
"implemented for %s!\n", get_name());
"implemented for %s!\n", get_name());

return SGVector< float64_t >();
}
Expand All @@ -111,16 +111,16 @@ float64_t CStructuredModel::delta_loss(int32_t ytrue_idx, CStructuredData* ypred
float64_t CStructuredModel::delta_loss(CStructuredData* y1, CStructuredData* y2)
{
SG_ERROR("delta_loss(CStructuredData*, CStructuredData*) is not "
"implemented for %s!\n", get_name());
"implemented for %s!\n", get_name());

return 0.0;
}

void CStructuredModel::init()
{
SG_ADD((CSGObject**) &m_labels, "m_labels", "Structured labels",
SG_ADD((CSGObject**) &m_labels, "m_labels", "Structured labels",
MS_NOT_AVAILABLE);
SG_ADD((CSGObject**) &m_features, "m_features", "Feature vectors",
SG_ADD((CSGObject**) &m_features, "m_features", "Feature vectors",
MS_NOT_AVAILABLE);

m_features = NULL;
Expand All @@ -146,4 +146,5 @@ int32_t CStructuredModel::get_num_aux_con() const
float64_t CStructuredModel::risk(float64_t* subgrad, float64_t* W, TMultipleCPinfo* info)
{
SG_NOTIMPLEMENTED;
return -1.0;
}
24 changes: 12 additions & 12 deletions src/shogun/structure/StructuredModel.h
Expand Up @@ -28,7 +28,7 @@ namespace shogun
*/
IGNORE_IN_CLASSLIST struct TMultipleCPinfo {
/** where this portion of data starts */
uint32_t from;
uint32_t _from;
/** how many examples belong to this portion of data */
uint32_t N;
};
Expand All @@ -39,7 +39,7 @@ class CStructuredModel;
struct CResultSet : public CSGObject
{
/** destructor */
~CResultSet() { SG_UNREF(argmax) };
~CResultSet() { SG_UNREF(argmax) }

/** argmax */
CStructuredData* argmax;
Expand All @@ -60,13 +60,13 @@ struct CResultSet : public CSGObject
virtual const char* get_name() const { return "ResultSet"; }
};

/**
* @brief Class CStructuredModel that represents the application specific model
* and contains most of the application dependent logic to solve structured
/**
* @brief Class CStructuredModel that represents the application specific model
* and contains most of the application dependent logic to solve structured
* output (SO) problems. The idea of this class is to be instantiated giving
* pointers to the functions that are dependent on the application, i.e. the
* pointers to the functions that are dependent on the application, i.e. the
* combined feature representation \f$\Psi(\bold{x},\bold{y})\f$ and the argmax
* function \f$ {\arg\max} _{\bold{y} \neq \bold{y}_i} \left \langle { \bold{w},
* function \f$ {\arg\max} _{\bold{y} \neq \bold{y}_i} \left \langle { \bold{w},
* \Psi(\bold{x}_i,\bold{y}) } \right \rangle \f$. See: MulticlassModel.h and
* .cpp for an example of these functions implemented.
*/
Expand Down Expand Up @@ -99,11 +99,11 @@ class CStructuredModel : public CSGObject
virtual void init_opt(
SGMatrix< float64_t > & A, SGVector< float64_t > a,
SGMatrix< float64_t > B, SGVector< float64_t > & b,
SGVector< float64_t > lb, SGVector< float64_t > ub,
SGVector< float64_t > lb, SGVector< float64_t > ub,
SGMatrix < float64_t > & C);

/**
* return the dimensionality of the joint feature space, i.e.
* return the dimensionality of the joint feature space, i.e.
* the dimension of the weight vector \f$w\f$
*/
virtual int32_t get_dim() const = 0;
Expand Down Expand Up @@ -132,8 +132,8 @@ class CStructuredModel : public CSGObject
*/
CFeatures* get_features();

/**
* gets joint feature vector
/**
* gets joint feature vector
*
* \f[
* \vec{\Psi}(\bf{x}_\text{feat\_idx}, \bf{y}_\text{lab\_idx})
Expand Down Expand Up @@ -193,7 +193,7 @@ class CStructuredModel : public CSGObject

/** @return name of SGSerializable */
virtual const char* get_name() const { return "StructuredModel"; }

/**
* method to be called from a SO machine before training
* to ensure that the training data is valid (e.g. check that
Expand Down
16 changes: 9 additions & 7 deletions src/shogun/structure/libbmrm.cpp
Expand Up @@ -102,7 +102,7 @@ bmrm_return_value_T svm_bmrm_solver(
float64_t* W,
float64_t TolRel,
float64_t TolAbs,
float64_t lambda,
float64_t _lambda,
uint32_t _BufSize,
bool cleanICP,
uint32_t cleanAfter,
Expand Down Expand Up @@ -255,7 +255,7 @@ bmrm_return_value_T svm_bmrm_solver(
}

/* Iinitial solution */
R = model->risk(subgrad, W);
R=model->risk(subgrad, W);

bmrm.nCP=0;
bmrm.nIter=0;
Expand All @@ -264,6 +264,7 @@ bmrm_return_value_T svm_bmrm_solver(
b[0]=-R;

/* Cutting plane auxiliary double linked list */

LIBBMRM_MEMCPY(A, subgrad, nDim*sizeof(float64_t));
map[0]=false;
cp_list->address=&A[0];
Expand All @@ -274,8 +275,9 @@ bmrm_return_value_T svm_bmrm_solver(
CPList_tail=cp_list;

/* Compute initial value of Fp, Fd, assuming that W is zero vector */

sq_norm_W=0;
bmrm.Fp=R+0.5*lambda*sq_norm_W;
bmrm.Fp=R+0.5*_lambda*sq_norm_W;
bmrm.Fd=-LIBBMRM_PLUS_INF;

tstop=ttime.cur_time_diff(false);
Expand Down Expand Up @@ -311,7 +313,7 @@ bmrm_return_value_T svm_bmrm_solver(
rsum+=A_1[j]*A_2[j];
}

H[LIBBMRM_INDEX(i, bmrm.nCP, BufSize)]=rsum/lambda;
H[LIBBMRM_INDEX(i, bmrm.nCP, BufSize)]=rsum/_lambda;
}

for (uint32_t i=0; i<bmrm.nCP; ++i)
Expand All @@ -327,7 +329,7 @@ bmrm_return_value_T svm_bmrm_solver(
for (uint32_t i=0; i<nDim; ++i)
rsum+=A_2[i]*A_2[i];

H[LIBBMRM_INDEX(bmrm.nCP, bmrm.nCP, BufSize)]=rsum/lambda;
H[LIBBMRM_INDEX(bmrm.nCP, bmrm.nCP, BufSize)]=rsum/_lambda;

diag_H[bmrm.nCP]=H[LIBBMRM_INDEX(bmrm.nCP, bmrm.nCP, BufSize)];
I[bmrm.nCP]=1;
Expand Down Expand Up @@ -371,7 +373,7 @@ bmrm_return_value_T svm_bmrm_solver(
rsum+=A_1[i]*beta[j];
}

W[i]=-rsum/lambda;
W[i]=-rsum/_lambda;
}

/* risk and subgradient computation */
Expand All @@ -388,7 +390,7 @@ bmrm_return_value_T svm_bmrm_solver(
sq_norm_W+=W[j]*W[j];
}

bmrm.Fp=R+0.5*lambda*sq_norm_W;
bmrm.Fp=R+0.5*_lambda*sq_norm_W;
bmrm.Fd=-qp_exitflag.QP;

/* Stopping conditions */
Expand Down
4 changes: 2 additions & 2 deletions src/shogun/structure/libbmrm.h
Expand Up @@ -116,7 +116,7 @@ inline uint32_t find_free_idx(bool *map, uint32_t size)
* @param W Weight vector
* @param TolRel Relative tolerance
* @param TolAbs Absolute tolerance
* @param lambda Regularization constant
* @param _lambda Regularization constant
* @param _BufSize Size of the CP buffer (i.e. maximal number of
* iterations)
* @param cleanICP Flag that enables/disables inactive cutting plane
Expand All @@ -133,7 +133,7 @@ bmrm_return_value_T svm_bmrm_solver(
float64_t *W,
float64_t TolRel,
float64_t TolAbs,
float64_t lambda,
float64_t _lambda,
uint32_t _BufSize,
bool cleanICP,
uint32_t cleanAfter,
Expand Down

0 comments on commit 4f930ca

Please sign in to comment.