SHOGUN  v2.0.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MulticlassModel.cpp
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 3 of the License, or
5  * (at your option) any later version.
6  *
7  * Written (W) 2012 Fernando José Iglesias García
8  * Copyright (C) 2012 Fernando José Iglesias García
9  */
10 
15 
16 using namespace shogun;
17 
20 {
21  init();
22 }
23 
25 : CStructuredModel(features, labels)
26 {
27  init();
28 }
29 
31 {
32 }
33 
35 {
36  // TODO make the casts safe!
37  int32_t num_classes = ((CMulticlassSOLabels*) m_labels)->get_num_classes();
38  int32_t feats_dim = ((CDotFeatures*) m_features)->get_dim_feature_space();
39 
40  return feats_dim*num_classes;
41 }
42 
44 {
46  psi.zero();
47 
49  get_computed_dot_feature_vector(feat_idx);
51  ASSERT(r != NULL)
52  float64_t label_value = r->value;
53 
54  for ( index_t i = 0, j = label_value*x.vlen ; i < x.vlen ; ++i, ++j )
55  psi[j] = x[i];
56 
57  return psi;
58 }
59 
62  int32_t feat_idx,
63  bool const training)
64 {
66  int32_t feats_dim = df->get_dim_feature_space();
67 
68  if ( training )
69  {
71  m_num_classes = ml->get_num_classes();
72  }
73  else
74  {
75  REQUIRE(m_num_classes > 0, "The model needs to be trained before "
76  "using it for prediction\n");
77  }
78 
79  int32_t dim = get_dim();
80  ASSERT(dim == w.vlen);
81 
82  // Find the class that gives the maximum score
83 
84  float64_t score = 0, ypred = 0;
85  float64_t max_score = -CMath::INFTY;
86 
87  for ( int32_t c = 0 ; c < m_num_classes ; ++c )
88  {
89  score = df->dense_dot(feat_idx, w.vector+c*feats_dim, feats_dim);
90  if ( training )
91  score += delta_loss(feat_idx, c);
92 
93  if ( score > max_score )
94  {
95  max_score = score;
96  ypred = c;
97  }
98  }
99 
100  // Build the CResultSet object to return
101  CResultSet* ret = new CResultSet();
102  CRealNumber* y = new CRealNumber(ypred);
103  SG_REF(y);
104 
105  ret->psi_pred = get_joint_feature_vector(feat_idx, y);
106  ret->score = max_score;
107  ret->argmax = y;
108  if ( training )
109  {
110  ret->delta = CStructuredModel::delta_loss(feat_idx, y);
112  feat_idx, feat_idx);
114  ret->psi_truth.vector, dim);
115  }
116 
117  return ret;
118 }
119 
121 {
124  ASSERT(rn1 != NULL);
125  ASSERT(rn2 != NULL);
126 
127  return delta_loss(rn1->value, rn2->value);
128 }
129 
131 {
132  REQUIRE(y1_idx >= 0 || y1_idx < m_labels->get_num_labels(),
133  "The label index must be inside [0, num_labels-1]\n");
134 
136  float64_t ret = delta_loss(rn1->value, y2);
137  SG_UNREF(rn1);
138 
139  return ret;
140 }
141 
143 {
144  return (y1 == y2) ? 0 : 1;
145 }
146 
155 {
157 }
158 
159 void CMulticlassModel::init()
160 {
161  SG_ADD(&m_num_classes, "m_num_classes", "The number of classes",
163 
164  m_num_classes = 0;
165 }
166 
168 {
171  m_num_classes = y->get_num_classes();
172  uint32_t from, to;
173 
174  if (info)
175  {
176  from=info->_from;
177  to=(info->N == 0) ? X->get_num_vectors() : from+info->N;
178  } else {
179  from=0;
180  to=X->get_num_vectors();
181  }
182 
183  uint32_t num_classes=y->get_num_classes();
184  uint32_t feats_dim=X->get_dim_feature_space();
185  const uint32_t w_dim=get_dim();
186 
187  float64_t R=0.0;
188  for (uint32_t i=0; i<w_dim; i++)
189  subgrad[i] = 0;
190 
191  float64_t Rtmp=0.0;
192  float64_t Rmax=0.0;
193  float64_t loss=0.0;
194  uint32_t yhat=0;
195  uint32_t GT=0;
196  CRealNumber* GT_rn=NULL;
197 
198  /* loop through examples */
199  for(uint32_t i=from; i<to; ++i)
200  {
201  Rmax=-CMath::INFTY;
203  GT=(uint32_t)GT_rn->value;
204 
205  for (uint32_t c = 0; c < num_classes; ++c)
206  {
207  loss=(c == GT) ? 0.0 : 1.0;
208  Rtmp=loss+X->dense_dot(i, W+c*feats_dim, feats_dim)
209  -X->dense_dot(i, W+GT*feats_dim, feats_dim);
210 
211  if (Rtmp > Rmax)
212  {
213  Rmax=Rtmp;
214  yhat=c;
215  }
216  }
217  R += Rmax;
218 
219  X->add_to_dense_vec(1.0, i, subgrad+yhat*feats_dim, feats_dim);
220  X->add_to_dense_vec(-1.0, i, subgrad+GT*feats_dim, feats_dim);
221 
222  SG_UNREF(GT_rn);
223  }
224 
225  return R;
226 }
227 

SHOGUN Machine Learning Toolbox - Documentation