Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/moses-smt/vowpal_wabbit.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJake Hofman <jhofman@gmail>2013-06-27 04:37:18 +0400
committerJake Hofman <jhofman@gmail>2013-06-27 04:37:18 +0400
commit8fec9447898c35262ca2d16f018b8ecdea2404ea (patch)
tree81d31de1a85be604b2fb9627b26bc28dfffb102b /vowpalwabbit/mf.cc
parentd962dee760f5fbe709ac47b336ac18d14607a877 (diff)
cleaned up mf.cc
Diffstat (limited to 'vowpalwabbit/mf.cc')
-rw-r--r--vowpalwabbit/mf.cc100
1 files changed, 46 insertions, 54 deletions
diff --git a/vowpalwabbit/mf.cc b/vowpalwabbit/mf.cc
index 99535d57..670fe6b4 100644
--- a/vowpalwabbit/mf.cc
+++ b/vowpalwabbit/mf.cc
@@ -35,9 +35,11 @@ struct mf {
vector<string> pairs;
uint32_t rank;
+
uint32_t increment;
// array to cache w*x, (l^k * x_l) and (r^k * x_r)
+ // [ w*(1,x_l,x_r) , l^1*x_l, r^1*x_r, l^2*x_l, r^2*x_2, ... ]
v_array<float> sub_predictions;
// array for temp storage of indices
@@ -50,67 +52,67 @@ struct mf {
};
void inline_predict(mf* data, vw* all, example* &ec) {
+ // store namespace indices
copy_array(data->indices, ec->indices);
float prediction = 0;
-
data->sub_predictions.erase();
- // modify label to indicate test example (predict only)
+ // set label to FLT_MAX to indicate test example (predict only)
float label = ((label_data*) ec->ld)->label;
((label_data*) ec->ld)->label = FLT_MAX;
- // prediction from linear terms
+ // predict from linear terms
data->base.learn(ec);
- // store constant + linear prediction
+ // store linear prediction
data->sub_predictions.push_back(ec->partial_prediction);
+ prediction += ec->partial_prediction;
- /*
- // prediction from interaction terms
+ // add interaction terms to prediction
for (vector<string>::iterator i = data->pairs.begin(); i != data->pairs.end(); i++) {
if (ec->atomics[(int) (*i)[0]].size() > 0 && ec->atomics[(int) (*i)[1]].size() > 0) {
for (size_t k = 1; k <= all->rank; k++) {
- // set to left namespace only
+ // set example to left namespace only
ec->indices.erase();
ec->indices.push_back((int) (*i)[0]);
- // compute l_k * x_l
+ // compute l^k * x_l using base learner
update_example_indicies(all->audit, ec, data->increment*k);
data->base.learn(ec);
float x_dot_l = ec->partial_prediction;
data->sub_predictions.push_back(ec->partial_prediction);
update_example_indicies(all->audit, ec, -data->increment*k);
- // set to right namespace only
+ // set example to right namespace only
ec->indices.erase();
ec->indices.push_back((int) (*i)[1]);
- // compute r_k * x_r
+ // compute r^k * x_r using base learner
update_example_indicies(all->audit, ec, data->increment*(k + data->rank));
data->base.learn(ec);
float x_dot_r = ec->partial_prediction;
data->sub_predictions.push_back(ec->partial_prediction);
update_example_indicies(all->audit, ec, -data->increment*(k + data->rank));
+ // accumulate prediction
prediction += (x_dot_l * x_dot_r);
}
}
}
- */
- copy_array(ec->indices, data->indices);
+ // restore namespace indices and label
+ copy_array(ec->indices, data->indices);
((label_data*) ec->ld)->label = label;
- ec->partial_prediction = data->sub_predictions[0] + prediction;
+
+ // finalize prediction
+ ec->partial_prediction = prediction;
ec->final_prediction = GD::finalize_prediction(*(data->all), ec->partial_prediction);
}
- float sgn(float x) {
- return 2*(x >= 0) - 1;
- }
-void learn_with_output(void* d, example* ec, bool shouldOutput) {
+void learn(void* d, example* ec) {
mf* data = (mf*) d;
vw* all = data->all;
@@ -119,73 +121,67 @@ void learn_with_output(void* d, example* ec, bool shouldOutput) {
return;
}
+ // store namespace indices
+ copy_array(data->indices, ec->indices);
+
+ // predict with current weights
inline_predict(data, all, ec);
- // update linear weights
+ // force base learner to use precomputed prediction
ec->precomputed_prediction = true;
- data->base.learn(ec);
- copy_array(data->indices, ec->indices);
+ // update linear weights
+ data->base.learn(ec);
- /*
- // update left and right terms
+ // update interaction terms
+ // looping over all pairs of non-empty namespaces
for (vector<string>::iterator i = data->pairs.begin(); i != data->pairs.end(); i++) {
if (ec->atomics[(int) (*i)[0]].size() > 0 && ec->atomics[(int) (*i)[1]].size() > 0) {
for (size_t k = 1; k <= all->rank; k++) {
- // set to left namespace only
+ // set example to left namespace only
ec->indices.erase();
ec->indices.push_back((int) (*i)[0]);
+ // store feature values for left namespace
copy_array(data->temp_features, ec->atomics[(int) (*i)[0]]);
- // modify features
- // multiple features in left namespace by r^k * x_r
+ // multiply features in left namespace by r^k * x_r
for (feature* f = ec->atomics[(int) (*i)[0]].begin; f != ec->atomics[(int) (*i)[0]].end; f++)
f->x *= data->sub_predictions[2*k];
- // update l^k
+ // update l^k using base learner
update_example_indicies(all->audit, ec, data->increment*k);
data->base.learn(ec);
update_example_indicies(all->audit, ec, -data->increment*k);
- // restore features
+ // restore left namespace features
copy_array(ec->atomics[(int) (*i)[0]], data->temp_features);
- // for (feature* f = ec->atomics[(int) (*i)[0]].begin; f != ec->atomics[(int) (*i)[0]].end; f++)
- // f->x /= data->sub_predictions[2*k];
- // set to right namespace only
+ // set example to right namespace only
ec->indices.erase();
ec->indices.push_back((int) (*i)[1]);
+ // store feature values for right namespace
copy_array(data->temp_features, ec->atomics[(int) (*i)[1]]);
- // modify features
- // multiple features in right namespace by l^k * x_l
+ // multiply features in right namespace by l^k * x_l
for (feature* f = ec->atomics[(int) (*i)[1]].begin; f != ec->atomics[(int) (*i)[1]].end; f++)
f->x *= data->sub_predictions[2*k-1];
- // update r^k
+ // update r^k using base learner
update_example_indicies(all->audit, ec, data->increment*(k + data->rank));
data->base.learn(ec);
update_example_indicies(all->audit, ec, -data->increment*(k + data->rank));
- // restore features
+ // restore right namespace features
copy_array(ec->atomics[(int) (*i)[1]], data->temp_features);
- // for (feature* f = ec->atomics[(int) (*i)[1]].begin; f != ec->atomics[(int) (*i)[1]].end; f++)
- // f->x /= data->sub_predictions[2*k-1];
-
}
}
}
- */
-
+
+ // restore namespace indices and unset precomputed prediction
copy_array(ec->indices, data->indices);
ec->precomputed_prediction = false;
-
-}
-
-void learn(void* d, example* ec) {
- learn_with_output(d, ec, false);
}
void finish(void* data) {
@@ -194,9 +190,7 @@ void finish(void* data) {
o->all->pairs = o->pairs;
o->base.finish();
- //cout << "constant " << o->all->reg.weight_vector[(constant * o->all->reg.stride)&o->all->reg.weight_mask] << endl;
-
- // clean up local arrays
+ // clean up local v_arrays
o->indices.delete_v();
o->sub_predictions.delete_v();
delete o;
@@ -204,7 +198,7 @@ void finish(void* data) {
void drive(vw* all, void* d) {
example* ec = NULL;
-
+
while (true) {
if ((ec = VW::get_example(all->p)) != NULL) //blocking operation.
{
@@ -218,19 +212,19 @@ void drive(vw* all, void* d) {
}
learner setup(vw& all, po::variables_map& vm) {
- //mf* data = (mf*) calloc(1, sizeof(mf));
mf* data = new mf;
+ // copy global data locally
data->base = all.l;
data->all = &all;
data->rank = all.rank;
- // clear global pairs for eventual calls to base learner
- // store pairs in local data structure
+ // store global pairs in local data structure and clear global pairs
+ // for eventual calls to base learner
data->pairs = all.pairs;
all.pairs.clear();
- // set increment
+ // set index increment between weights
data->increment = all.reg.stride * all.weights_per_problem;
all.weights_per_problem *= data->rank;
@@ -241,8 +235,6 @@ learner setup(vw& all, po::variables_map& vm) {
all.reg.weight_vector[j*all.reg.stride] = (float) (0.1 * frand48());
}
- //cout << "constant " << data->all->reg.weight_vector[(constant * data->all->reg.stride)&data->all->reg.weight_mask] << endl;
-
learner ret(data, drive,learn, finish, all.l.sl);
return ret;
}