From 64e789a970759437e078e5cbdeedb685148e4ef2 Mon Sep 17 00:00:00 2001 From: iglesias Date: Mon, 3 Jun 2013 13:48:28 +0200 Subject: [PATCH] Several minor improvements in the SO framework and the HMSVM --- .../libshogun/so_hmsvm_mosek_simple.cpp | 10 +-- src/shogun/features/MatrixFeatures.cpp | 2 +- src/shogun/features/MatrixFeatures.h | 2 +- .../machine/LinearStructuredOutputMachine.cpp | 4 ++ .../machine/LinearStructuredOutputMachine.h | 6 ++ .../machine/StructuredOutputMachine.cpp | 6 ++ src/shogun/machine/StructuredOutputMachine.h | 6 ++ .../structure/DirectorStructuredModel.cpp | 17 ++++- .../structure/DirectorStructuredModel.h | 10 ++- src/shogun/structure/HMSVMModel.cpp | 69 +++++++++++-------- src/shogun/structure/HMSVMModel.h | 23 ++++++- src/shogun/structure/MulticlassModel.cpp | 3 +- src/shogun/structure/MulticlassModel.h | 1 + src/shogun/structure/PrimalMosekSOSVM.cpp | 23 +++++-- src/shogun/structure/PrimalMosekSOSVM.h | 9 +++ src/shogun/structure/SequenceLabels.cpp | 4 +- src/shogun/structure/SequenceLabels.h | 2 +- src/shogun/structure/StateModel.h | 24 +++++-- src/shogun/structure/StructuredModel.cpp | 1 + src/shogun/structure/StructuredModel.h | 1 + src/shogun/structure/TwoStateModel.cpp | 12 +++- src/shogun/structure/TwoStateModel.h | 24 +++++-- 22 files changed, 200 insertions(+), 59 deletions(-) diff --git a/examples/undocumented/libshogun/so_hmsvm_mosek_simple.cpp b/examples/undocumented/libshogun/so_hmsvm_mosek_simple.cpp index 4e7b575f86b..52f3a0da791 100644 --- a/examples/undocumented/libshogun/so_hmsvm_mosek_simple.cpp +++ b/examples/undocumented/libshogun/so_hmsvm_mosek_simple.cpp @@ -24,11 +24,11 @@ int main(int argc, char ** argv) // No need for ref_counting in SGVector since the data is allocated // during compilation time - labels->add_label(SGVector< int32_t >(lab1, 4, false)); - labels->add_label(SGVector< int32_t >(lab2, 4, false)); - labels->add_label(SGVector< int32_t >(lab3, 4, false)); - labels->add_label(SGVector< int32_t >(lab4, 4, false)); - labels->add_label(SGVector< int32_t >(lab5, 4, false)); + labels->add_vector_label(SGVector< int32_t >(lab1, 4, false)); + labels->add_vector_label(SGVector< int32_t >(lab2, 4, false)); + labels->add_vector_label(SGVector< int32_t >(lab3, 4, false)); + labels->add_vector_label(SGVector< int32_t >(lab4, 4, false)); + labels->add_vector_label(SGVector< int32_t >(lab5, 4, false)); // Create features CMatrixFeatures< float64_t >* features = new CMatrixFeatures< float64_t >(5, 3); diff --git a/src/shogun/features/MatrixFeatures.cpp b/src/shogun/features/MatrixFeatures.cpp index 33e98aaaff6..11cd49683b2 100644 --- a/src/shogun/features/MatrixFeatures.cpp +++ b/src/shogun/features/MatrixFeatures.cpp @@ -117,7 +117,7 @@ template< class ST > void CMatrixFeatures< ST >::get_feature_vector_col( } template< class ST > void CMatrixFeatures< ST >::set_feature_vector( - SGMatrix< ST > const & vec, + SGMatrix< ST > const vec, int32_t num) { if ( num < 0 || num >= get_num_vectors() ) diff --git a/src/shogun/features/MatrixFeatures.h b/src/shogun/features/MatrixFeatures.h index b88a0f213df..c6de2f49d9c 100644 --- a/src/shogun/features/MatrixFeatures.h +++ b/src/shogun/features/MatrixFeatures.h @@ -109,7 +109,7 @@ template< class ST > class CMatrixFeatures : public CFeatures * @param vec feature vector * @param num index of vector to set */ - void set_feature_vector(SGMatrix< ST > const & vec, int32_t num); + void set_feature_vector(SGMatrix< ST > const vec, int32_t num); /** get features * diff --git a/src/shogun/machine/LinearStructuredOutputMachine.cpp b/src/shogun/machine/LinearStructuredOutputMachine.cpp index 4571f619792..e46f975c464 100644 --- a/src/shogun/machine/LinearStructuredOutputMachine.cpp +++ b/src/shogun/machine/LinearStructuredOutputMachine.cpp @@ -84,3 +84,7 @@ void CLinearStructuredOutputMachine::register_parameters() { SG_ADD(&m_w, "m_w", "Weight vector", MS_NOT_AVAILABLE); } + +void CLinearStructuredOutputMachine::store_model_features() +{ +} diff --git a/src/shogun/machine/LinearStructuredOutputMachine.h b/src/shogun/machine/LinearStructuredOutputMachine.h index 66a7582abef..12348a2384f 100644 --- a/src/shogun/machine/LinearStructuredOutputMachine.h +++ b/src/shogun/machine/LinearStructuredOutputMachine.h @@ -69,6 +69,12 @@ class CLinearStructuredOutputMachine : public CStructuredOutputMachine */ virtual CStructuredLabels* apply_structured(CFeatures* data = NULL); + /** Stores feature data of underlying model. Does nothing because + * Linear machines store the normal vector of the separating hyperplane + * and therefore the model anyway + */ + virtual void store_model_features(); + /** @return object name */ virtual const char* get_name() const { diff --git a/src/shogun/machine/StructuredOutputMachine.cpp b/src/shogun/machine/StructuredOutputMachine.cpp index 34b556d3587..a9533ad350b 100644 --- a/src/shogun/machine/StructuredOutputMachine.cpp +++ b/src/shogun/machine/StructuredOutputMachine.cpp @@ -67,3 +67,9 @@ void CStructuredOutputMachine::register_parameters() SG_ADD((CSGObject**)&m_model, "m_model", "Structured model", MS_NOT_AVAILABLE); SG_ADD((CSGObject**)&m_loss, "m_loss", "Structured loss", MS_NOT_AVAILABLE); } + +void CStructuredOutputMachine::set_labels(CLabels* lab) +{ + CMachine::set_labels(lab); + m_model->set_labels(CLabelsFactory::to_structured(lab)); +} diff --git a/src/shogun/machine/StructuredOutputMachine.h b/src/shogun/machine/StructuredOutputMachine.h index 12abcb1c47a..f4a9a52d1c0 100644 --- a/src/shogun/machine/StructuredOutputMachine.h +++ b/src/shogun/machine/StructuredOutputMachine.h @@ -73,6 +73,12 @@ class CStructuredOutputMachine : public CMachine return "StructuredOutputMachine"; } + /** set labels + * + * @param lab labels + */ + virtual void set_labels(CLabels* lab); + private: /** register class members */ void register_parameters(); diff --git a/src/shogun/structure/DirectorStructuredModel.cpp b/src/shogun/structure/DirectorStructuredModel.cpp index f9aa67d36dc..0ef50ea8fd5 100644 --- a/src/shogun/structure/DirectorStructuredModel.cpp +++ b/src/shogun/structure/DirectorStructuredModel.cpp @@ -53,9 +53,22 @@ bool CDirectorStructuredModel::check_training_setup() const return false; } -void CDirectorStructuredModel::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, SGMatrix < float64_t > & C) +void CDirectorStructuredModel::init_opt( + float64_t regularization, + SGMatrix< float64_t > & A, + SGVector< float64_t > a, + SGMatrix< float64_t > B, + SGVector< float64_t > & b, + SGVector< float64_t > lb, + SGVector< float64_t > ub, + SGMatrix< float64_t > & C) { - SG_ERROR("Please implemement init_opt(A,a,B,b,lb,ub,C) in your target language before use\n") + SG_ERROR("Please implemement init_opt(regularization,A,a,B,b,lb,ub,C) in your target language before use\n") +} + +void CDirectorStructuredModel::init_training() +{ + SG_ERROR("Please implemement init_training() in your target language before use\n") } #endif /* USE_SWIG_DIRECTORS */ diff --git a/src/shogun/structure/DirectorStructuredModel.h b/src/shogun/structure/DirectorStructuredModel.h index 7988257d913..9d4c0f56dfb 100644 --- a/src/shogun/structure/DirectorStructuredModel.h +++ b/src/shogun/structure/DirectorStructuredModel.h @@ -98,7 +98,12 @@ IGNORE_IN_CLASSLIST class CDirectorStructuredModel : public CStructuredModel * @param ub * @param C */ - 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, SGMatrix < float64_t > & C); + virtual void init_opt( + float64_t regularization, + SGMatrix< float64_t > & A, SGVector< float64_t > a, + SGMatrix< float64_t > B, SGVector< float64_t > & b, + SGVector< float64_t > lb, SGVector< float64_t > ub, + SGMatrix < float64_t > & C); using CStructuredModel::director_risk; @@ -107,6 +112,9 @@ IGNORE_IN_CLASSLIST class CDirectorStructuredModel : public CStructuredModel /** @return name of SGSerializable */ virtual const char* get_name() const { return "DirectorStructuredModel"; } + /** initializes the part of the model that needs to be used during training. */ + virtual void init_training(); + }; /* class CDirectorStructuredModel */ } /* namespace shogun */ #endif /* USE_SWIG_DIRECTORS */ diff --git a/src/shogun/structure/HMSVMModel.cpp b/src/shogun/structure/HMSVMModel.cpp index e7bdb01e442..22d530f86cb 100644 --- a/src/shogun/structure/HMSVMModel.cpp +++ b/src/shogun/structure/HMSVMModel.cpp @@ -48,15 +48,15 @@ CHMSVMModel::~CHMSVMModel() int32_t CHMSVMModel::get_dim() const { - // Shorthands for the number of states, the matrix features and their dimension - int32_t S = m_state_model->get_num_states(); + // Shorthand for the number of free states + int32_t free_states = ((CSequenceLabels*) m_labels)->get_num_states(); CMatrixFeatures< float64_t >* mf = (CMatrixFeatures< float64_t >*) m_features; int32_t D = mf->get_num_features(); if ( m_use_plifs ) - return S*(S + D*m_num_plif_nodes); + return free_states*(free_states + D*m_num_plif_nodes); else - return S*(S + D*m_num_obs); + return free_states*(free_states + D*m_num_obs); } SGVector< float64_t > CHMSVMModel::get_joint_feature_vector( @@ -82,7 +82,9 @@ SGVector< float64_t > CHMSVMModel::get_joint_feature_vector( m_transmission_weights(state_seq[i],state_seq[i+1]) += 1; SGMatrix< float64_t > obs = mf->get_feature_vector(feat_idx); - ASSERT(obs.num_rows == D && obs.num_cols == state_seq.vlen) + REQUIRE(obs.num_rows == D && obs.num_cols == state_seq.vlen, + "obs.num_rows (%d) != D (%d) OR obs.num_cols (%d) != state_seq.vlen (%d)\n", + obs.num_rows, D, obs.num_cols, state_seq.vlen) m_emission_weights.zero(); index_t aux_idx, weight_idx; @@ -105,12 +107,6 @@ SGVector< float64_t > CHMSVMModel::get_joint_feature_vector( else // Use PLiFs { int32_t S = m_state_model->get_num_states(); - CPlif* plif; - float64_t* limits; - // The observation value - float64_t value; - // The number of supporting points smaller or equal than value - int32_t count; for ( int32_t f = 0 ; f < D ; ++f ) { @@ -118,10 +114,12 @@ SGVector< float64_t > CHMSVMModel::get_joint_feature_vector( for ( int32_t j = 0 ; j < state_seq.vlen ; ++j ) { - plif = (CPlif*) m_plif_matrix->get_element(S*f + state_seq[j]); - limits = plif->get_plif_limits(); - count = 0; - value = obs(f,j); + CPlif* plif = (CPlif*) m_plif_matrix->get_element(S*f + state_seq[j]); + float64_t* limits = plif->get_plif_limits(); + // The number of supporting points smaller or equal than value + int32_t count = 0; + // The observation value + float64_t value = obs(f,j); for ( int32_t i = 0 ; i < m_num_plif_nodes ; ++i ) { @@ -214,17 +212,16 @@ CResultSet* CHMSVMModel::argmax( { m_state_model->reshape_emission_params(m_plif_matrix, w, D, m_num_plif_nodes); - CPlif* plif; - for ( int32_t f = 0 ; f < D ; ++f ) + for ( int32_t i = 0 ; i < T ; ++i ) { - for ( int32_t s = 0 ; s < S ; ++s ) + for ( int32_t f = 0 ; f < D ; ++f ) { - plif = (CPlif*) m_plif_matrix->get_element(S*f + s); - - for ( int32_t i = 0 ; i < T ; ++i ) + for ( int32_t s = 0 ; s < S ; ++s ) + { + CPlif* plif = (CPlif*) m_plif_matrix->get_element(S*f + s); E(s,i) += plif->lookup( x(f,i) ); - - SG_UNREF(plif); + SG_UNREF(plif); + } } } } @@ -353,6 +350,7 @@ float64_t CHMSVMModel::delta_loss(CStructuredData* y1, CStructuredData* y2) } void CHMSVMModel::init_opt( + float64_t regularization, SGMatrix< float64_t > & A, SGVector< float64_t > a, SGMatrix< float64_t > B, @@ -361,8 +359,7 @@ void CHMSVMModel::init_opt( SGVector< float64_t > ub, SGMatrix< float64_t > & C) { - // Shorthand for the number of free states (i.e. states that have all their - // parameters learnt) + // Shorthand for the number of free states (i.e. states for which parameters are learnt) int32_t S = ((CSequenceLabels*) m_labels)->get_num_states(); // Shorthand for the number of features of the feature vector int32_t D = ((CMatrixFeatures< float64_t >*) m_features)->get_num_features(); @@ -370,10 +367,10 @@ void CHMSVMModel::init_opt( // Monotonicity constraints for feature scoring functions SGVector< int32_t > monotonicity = m_state_model->get_monotonicity(S,D); - // Quadratic regularizer + // Quadratic regularization - float64_t C_small = 5.0; - float64_t C_smooth = 10.0; + float64_t C_small = regularization; + float64_t C_smooth = 0.02*regularization; // TODO change the representation of C to sparse matrix C = SGMatrix< float64_t >(get_dim()+m_num_aux, get_dim()+m_num_aux); C.zero(); @@ -593,3 +590,19 @@ void CHMSVMModel::init_training() } } } + +SGMatrix< float64_t > CHMSVMModel::get_transmission_weights() const +{ + return m_transmission_weights; +} + +SGVector< float64_t > CHMSVMModel::get_emission_weights() const +{ + return m_emission_weights; +} + +CStateModel* CHMSVMModel::get_state_model() const +{ + SG_REF(m_state_model); + return m_state_model; +} diff --git a/src/shogun/structure/HMSVMModel.h b/src/shogun/structure/HMSVMModel.h index 51de6818fbb..f53dbd5d34f 100644 --- a/src/shogun/structure/HMSVMModel.h +++ b/src/shogun/structure/HMSVMModel.h @@ -100,6 +100,7 @@ class CHMSVMModel : public CStructuredModel * @param C */ virtual void init_opt( + float64_t regularization, SGMatrix< float64_t > & A, SGVector< float64_t > a, SGMatrix< float64_t > B, SGVector< float64_t > & b, SGVector< float64_t > lb, SGVector< float64_t > ub, @@ -117,7 +118,7 @@ class CHMSVMModel : public CStructuredModel * implement smoothness regularization between adjacent emission * scores via constraints. * - * return the number of auxiliary variables + * @return the number of auxiliary variables */ virtual int32_t get_num_aux() const; @@ -126,7 +127,7 @@ class CHMSVMModel : public CStructuredModel * optimization problem. These constraints are used to implement * smoothness regularization between adjacent emission scores. * - * return the number of auxiliary constraints + * @return the number of auxiliary constraints */ virtual int32_t get_num_aux_con() const; @@ -143,6 +144,24 @@ class CHMSVMModel : public CStructuredModel */ virtual void init_training(); + /** get transmission weights + * + * @return vector with the transmission weights + */ + SGMatrix< float64_t > get_transmission_weights() const; + + /** get emission weights + * + * @return vector with the emission weights + */ + SGVector< float64_t > get_emission_weights() const; + + /** get state model + * + * @return model with the description of the states + */ + CStateModel* get_state_model() const; + private: /* internal initialization */ void init(); diff --git a/src/shogun/structure/MulticlassModel.cpp b/src/shogun/structure/MulticlassModel.cpp index 3f800d105b3..b5eef9cef78 100644 --- a/src/shogun/structure/MulticlassModel.cpp +++ b/src/shogun/structure/MulticlassModel.cpp @@ -146,6 +146,7 @@ float64_t CMulticlassModel::delta_loss(float64_t y1, float64_t y2) } void CMulticlassModel::init_opt( + float64_t regularization, SGMatrix< float64_t > & A, SGVector< float64_t > a, SGMatrix< float64_t > B, @@ -154,7 +155,7 @@ void CMulticlassModel::init_opt( SGVector< float64_t > ub, SGMatrix< float64_t > & C) { - C = SGMatrix< float64_t >::create_identity_matrix(get_dim(), 1); + C = SGMatrix< float64_t >::create_identity_matrix(get_dim(), regularization); } void CMulticlassModel::init() diff --git a/src/shogun/structure/MulticlassModel.h b/src/shogun/structure/MulticlassModel.h index 745e0df0c69..f7739dfc0d0 100644 --- a/src/shogun/structure/MulticlassModel.h +++ b/src/shogun/structure/MulticlassModel.h @@ -93,6 +93,7 @@ class CMulticlassModel : public CStructuredModel * @param C */ virtual void init_opt( + float64_t regularization, SGMatrix< float64_t > & A, SGVector< float64_t > a, SGMatrix< float64_t > B, SGVector< float64_t > & b, SGVector< float64_t > lb, SGVector< float64_t > ub, diff --git a/src/shogun/structure/PrimalMosekSOSVM.cpp b/src/shogun/structure/PrimalMosekSOSVM.cpp index 4976dd014ca..361a3c71a1a 100644 --- a/src/shogun/structure/PrimalMosekSOSVM.cpp +++ b/src/shogun/structure/PrimalMosekSOSVM.cpp @@ -37,6 +37,10 @@ CPrimalMosekSOSVM::CPrimalMosekSOSVM( void CPrimalMosekSOSVM::init() { SG_ADD(&m_slacks, "m_slacks", "Slacks vector", MS_NOT_AVAILABLE); + //FIXME model selection available for SO machines + SG_ADD(&m_regularization, "m_regularization", "Regularization constant", MS_NOT_AVAILABLE); + + m_regularization = 1.0; } CPrimalMosekSOSVM::~CPrimalMosekSOSVM() @@ -81,7 +85,9 @@ bool CPrimalMosekSOSVM::train_machine(CFeatures* data) // Initialize the terms of the optimization problem SGMatrix< float64_t > A, B, C; SGVector< float64_t > a, b, lb, ub; - m_model->init_opt(A, a, B, b, lb, ub, C); + m_model->init_opt(m_regularization, A, a, B, b, lb, ub, C); + + SG_DEBUG("Regularization used in PrimalMosekSOSVM equal to %.2f.\n", m_regularization); // Input terms of the problem that do not change between iterations if ( mosek->init_sosvm(M, N, num_aux, num_aux_con, C, lb, ub, A, b) != MSK_RES_OK ) @@ -117,6 +123,7 @@ bool CPrimalMosekSOSVM::train_machine(CFeatures* data) CResultSet* cur_res = NULL; CList* cur_list = NULL; bool exception = false; + index_t iteration = 0; SGVector< float64_t > sol(M+num_aux+N); sol.zero(); @@ -125,7 +132,8 @@ bool CPrimalMosekSOSVM::train_machine(CFeatures* data) do { - SG_DEBUG("Cutting plane training with num_con=%d and old_num_con=%d.\n", num_con, old_num_con); + SG_DEBUG("Iteration #%d: Cutting plane training with num_con=%d and old_num_con=%d.\n", + iteration, num_con, old_num_con); old_num_con = num_con; @@ -134,7 +142,6 @@ bool CPrimalMosekSOSVM::train_machine(CFeatures* data) // Predict the result of the ith training example result = m_model->argmax(m_w, i); - SG_DEBUG("loss %f %f.\n", compute_loss_arg(result), m_loss->loss( compute_loss_arg(result)) ) // Compute the loss associated with the prediction slack = m_loss->loss( compute_loss_arg(result) ); cur_list = (CList*) results->get_element(i); @@ -188,7 +195,7 @@ bool CPrimalMosekSOSVM::train_machine(CFeatures* data) } // Solve the QP - SG_DEBUG("Entering mosek QP solver.\n"); + SG_DEBUG("Entering Mosek QP solver.\n"); mosek->optimize(sol); for ( int32_t i = 0 ; i < M+num_aux+N ; ++i ) @@ -201,6 +208,9 @@ bool CPrimalMosekSOSVM::train_machine(CFeatures* data) m_slacks[i-M-num_aux] = sol[i]; } + SG_DEBUG("QP solved. The primal objective value is %.4f.\n", mosek->get_primal_objective_value()); + ++iteration; + } while ( old_num_con != num_con && ! exception ); po_value = mosek->get_primal_objective_value(); @@ -262,4 +272,9 @@ EMachineType CPrimalMosekSOSVM::get_classifier_type() return CT_PRIMALMOSEKSOSVM; } +void CPrimalMosekSOSVM::set_regularization(float64_t C) +{ + m_regularization = C; +} + #endif /* USE_MOSEK */ diff --git a/src/shogun/structure/PrimalMosekSOSVM.h b/src/shogun/structure/PrimalMosekSOSVM.h index 081262d0135..37c55b3bd58 100644 --- a/src/shogun/structure/PrimalMosekSOSVM.h +++ b/src/shogun/structure/PrimalMosekSOSVM.h @@ -68,6 +68,12 @@ class CPrimalMosekSOSVM : public CLinearStructuredOutputMachine */ virtual EMachineType get_classifier_type(); + /** set regularization constant C + * + * @param C regularization constant + */ + void set_regularization(float64_t C); + protected: /** train primal SO-SVM * @@ -125,6 +131,9 @@ class CPrimalMosekSOSVM : public CLinearStructuredOutputMachine /** primal objective value */ float64_t po_value; + /** regularization constant */ + float64_t m_regularization; + }; /* class CPrimalMosekSOSVM */ } /* namespace shogun */ diff --git a/src/shogun/structure/SequenceLabels.cpp b/src/shogun/structure/SequenceLabels.cpp index e4c2c57887f..735e1240e4e 100644 --- a/src/shogun/structure/SequenceLabels.cpp +++ b/src/shogun/structure/SequenceLabels.cpp @@ -33,7 +33,7 @@ CSequenceLabels::CSequenceLabels(SGVector< int32_t > labels, int32_t label_lengt for ( int32_t i = 0 ; i < labels.vlen ; i += label_length ) { - add_label(SGVector< int32_t >( + add_vector_label(SGVector< int32_t >( SGVector< int32_t >::clone_vector(labels.vector+i, label_length), label_length)); } @@ -43,7 +43,7 @@ CSequenceLabels::~CSequenceLabels() { } -void CSequenceLabels::add_label(SGVector< int32_t > label) +void CSequenceLabels::add_vector_label(SGVector< int32_t > label) { CStructuredLabels::add_label( new CSequence(label) ); } diff --git a/src/shogun/structure/SequenceLabels.h b/src/shogun/structure/SequenceLabels.h index 3f506adba1b..d2e75d011c8 100644 --- a/src/shogun/structure/SequenceLabels.h +++ b/src/shogun/structure/SequenceLabels.h @@ -109,7 +109,7 @@ class CSequenceLabels : public CStructuredLabels * * @param label label to add */ - void add_label(SGVector< int32_t > label); + void add_vector_label(SGVector< int32_t > label); /** get the number of states * diff --git a/src/shogun/structure/StateModel.h b/src/shogun/structure/StateModel.h index 550521e5f79..0b70da05f7e 100644 --- a/src/shogun/structure/StateModel.h +++ b/src/shogun/structure/StateModel.h @@ -121,13 +121,12 @@ class CStateModel : public CSGObject /** * reshapes the transition and emission weights into a vector (the joint * feature vector so it will be possible to take the dot product with the - * weight vector) + * weight vector). Version with the joint feature vector as parameter by + * reference * * @param psi output vector - * @param transmission_weights counts of the state transitions for a state - * sequence - * @param emission_weights counts of the emission scores for a state - * sequence and a feature vector + * @param transmission_weights counts of the state transitions for a state sequence + * @param emission_weights counts of the emission scores for a state sequence and a feature vector * @param num_feats number of features * @param num_obs number of emission scores per feature and state */ @@ -136,6 +135,21 @@ class CStateModel : public CSGObject SGVector< float64_t > emission_weights, int32_t num_feats, int32_t num_obs) const = 0; + /** + * reshapes the transition and emission weights into a vector (the joint + * feature vector so it will be possible to take the dot product with the + * weight vector). Version returning the joint feature vector + * + * @param transmission_weights counts of the state transitions for a state sequence + * @param emission_weights counts of the emission scores for a state sequence and a feature vector + * @param num_feats number of features + * @param num_obs number of emission scores per feature and state + * + * @return psi output vector + */ + virtual SGVector< float64_t > weights_to_vector(SGMatrix< float64_t > transmission_weights, + SGVector< float64_t > emission_weights, int32_t num_feats, int32_t num_obs) const = 0; + /** * specify monotonicity constraints for feature scoring functions. The * elements of the vector returned can take one of three values: diff --git a/src/shogun/structure/StructuredModel.cpp b/src/shogun/structure/StructuredModel.cpp index 8a1fd444ce0..3ffce41deb0 100644 --- a/src/shogun/structure/StructuredModel.cpp +++ b/src/shogun/structure/StructuredModel.cpp @@ -58,6 +58,7 @@ CStructuredModel::~CStructuredModel() } void CStructuredModel::init_opt( + float64_t regularization, SGMatrix< float64_t > & A, SGVector< float64_t > a, SGMatrix< float64_t > B, diff --git a/src/shogun/structure/StructuredModel.h b/src/shogun/structure/StructuredModel.h index f9e63e1da52..626ff7beba8 100644 --- a/src/shogun/structure/StructuredModel.h +++ b/src/shogun/structure/StructuredModel.h @@ -109,6 +109,7 @@ class CStructuredModel : public CSGObject * @param C */ virtual void init_opt( + float64_t regularization, SGMatrix< float64_t > & A, SGVector< float64_t > a, SGMatrix< float64_t > B, SGVector< float64_t > & b, SGVector< float64_t > lb, SGVector< float64_t > ub, diff --git a/src/shogun/structure/TwoStateModel.cpp b/src/shogun/structure/TwoStateModel.cpp index b343c32d003..4af69ad31f6 100644 --- a/src/shogun/structure/TwoStateModel.cpp +++ b/src/shogun/structure/TwoStateModel.cpp @@ -221,6 +221,16 @@ void CTwoStateModel::weights_to_vector(SGVector< float64_t >& psi, } +SGVector< float64_t > CTwoStateModel::weights_to_vector(SGMatrix< float64_t > transmission_weights, + SGVector< float64_t > emission_weights, int32_t num_feats, int32_t num_obs) const +{ + int32_t num_free_states = 2; + SGVector< float64_t > vec(num_free_states*(num_free_states + num_feats*num_obs)); + vec.zero(); + weights_to_vector(vec, transmission_weights, emission_weights, num_feats, num_obs); + return vec; +} + SGVector< int32_t > CTwoStateModel::get_monotonicity(int32_t num_free_states, int32_t num_feats) const { @@ -280,7 +290,7 @@ CHMSVMModel* CTwoStateModel::simulate_data(int32_t num_exm, int32_t exm_len, } } - labels->add_label(lab); + labels->add_vector_label(lab); } // Generate features by diff --git a/src/shogun/structure/TwoStateModel.h b/src/shogun/structure/TwoStateModel.h index b33a626b222..8aaa4316830 100644 --- a/src/shogun/structure/TwoStateModel.h +++ b/src/shogun/structure/TwoStateModel.h @@ -112,13 +112,12 @@ class CTwoStateModel : public CStateModel /** * reshapes the transition and emission weights into a vector (the joint * feature vector so it will be possible to take the dot product with the - * weight vector) + * weight vector). Version with the joint feature vector as parameter by + * reference * * @param psi output vector - * @param transmission_weights counts of the state transitions for a state - * sequence - * @param emission_weights counts of the emission scores for a state - * sequence and a feature vector + * @param transmission_weights counts of the state transitions for a state sequence + * @param emission_weights counts of the emission scores for a state sequence and a feature vector * @param num_feats number of features * @param num_obs number of emission scores per feature and state */ @@ -127,6 +126,21 @@ class CTwoStateModel : public CStateModel SGVector< float64_t > emission_weights, int32_t num_feats, int32_t num_obs) const; + /** + * reshapes the transition and emission weights into a vector (the joint + * feature vector so it will be possible to take the dot product with the + * weight vector). Version returning the joint feature vector + * + * @param transmission_weights counts of the state transitions for a state sequence + * @param emission_weights counts of the emission scores for a state sequence and a feature vector + * @param num_feats number of features + * @param num_obs number of emission scores per feature and state + * + * @return psi output vector + */ + virtual SGVector< float64_t > weights_to_vector(SGMatrix< float64_t > transmission_weights, + SGVector< float64_t > emission_weights, int32_t num_feats, int32_t num_obs) const; + /** * specify monotonicity constraints for feature scoring functions. The * elements of the vector returned can take one of three values: