diff options
author | John <jl@hunch.net> | 2014-07-24 00:13:45 +0400 |
---|---|---|
committer | John <jl@hunch.net> | 2014-07-24 00:13:45 +0400 |
commit | 3c18847b1935f83608824e095385d042d1d77bb9 (patch) | |
tree | b4d4e10273485c8aee0d4a9ca286a00d8856e64b | |
parent | ef4954699ccfc6e4654bf7da2fbc44d37faa7b85 (diff) | |
parent | d39a775a09b558e1da6993bdb780f01811f3ea99 (diff) |
Merge pull request #347 from hal3/master
fixed bug that arises if you do not snapshot but still want auto-history...
-rw-r--r-- | test/train-sets/ref/argmax_data.stderr | 12 | ||||
-rw-r--r-- | vowpalwabbit/parser.cc | 7 | ||||
-rw-r--r-- | vowpalwabbit/searn.cc | 138 |
3 files changed, 89 insertions, 68 deletions
diff --git a/test/train-sets/ref/argmax_data.stderr b/test/train-sets/ref/argmax_data.stderr index 6357dbac..48d88bb6 100644 --- a/test/train-sets/ref/argmax_data.stderr +++ b/test/train-sets/ref/argmax_data.stderr @@ -12,17 +12,17 @@ average since sequence example current label cur loss last counter weight sequence prefix sequence prefix features pass pol made gener. 10.000000 10.000000 1 1.000000 [2 ] [1 ] 15 0 0 5 5 5.500000 1.000000 2 2.000000 [1 ] [2 ] 12 0 0 9 9 -5.250000 5.000000 4 4.000000 [2 ] [1 ] 9 0 0 15 15 -2.875000 0.500000 8 8.000000 [2 ] [2 ] 9 1 0 30 30 -1.687500 0.500000 16 16.000000 [2 ] [2 ] 9 3 0 60 60 -1.093750 0.500000 32 32.000000 [2 ] [2 ] 9 7 0 120 120 -0.796875 0.500000 64 64.000000 [2 ] [2 ] 9 15 0 240 240 +3.000000 0.500000 4 4.000000 [2 ] [2 ] 9 0 0 15 15 +1.750000 0.500000 8 8.000000 [2 ] [2 ] 9 1 0 30 30 +1.125000 0.500000 16 16.000000 [2 ] [2 ] 9 3 0 60 60 +0.812500 0.500000 32 32.000000 [2 ] [2 ] 9 7 0 120 120 +0.656250 0.500000 64 64.000000 [2 ] [2 ] 9 15 0 240 240 finished run number of examples per pass = 4 passes used = 20 weighted example sum = 80 weighted label sum = 0 -average loss = 0.7375 +average loss = 0.625 best constant = 0 total feature number = 900 diff --git a/vowpalwabbit/parser.cc b/vowpalwabbit/parser.cc index 5a58ef09..26a65432 100644 --- a/vowpalwabbit/parser.cc +++ b/vowpalwabbit/parser.cc @@ -140,11 +140,11 @@ void handle_sigterm (int) got_sigterm = true; } -bool is_test_only(uint32_t counter, uint32_t period, uint32_t after, bool holdout_off) +bool is_test_only(uint32_t counter, uint32_t period, uint32_t after, bool holdout_off, uint32_t target_modulus) // target should be 0 in the normal case, or period-1 in the case that emptylines separate examples { if(holdout_off) return false; if (after == 0) // hold out by period - return (counter % period == 0); + return (counter % period == target_modulus); else // hold out by position return (counter+1 >= after); } @@ -757,10 +757,11 @@ void setup_example(vw& all, example* ae) if ((!all.p->emptylines_separate_examples) || example_is_newline(*ae)) all.p->in_pass_counter++; - ae->test_only = is_test_only(all.p->in_pass_counter, all.holdout_period, all.holdout_after, all.holdout_set_off); + ae->test_only = is_test_only(all.p->in_pass_counter, all.holdout_period, all.holdout_after, all.holdout_set_off, all.p->emptylines_separate_examples ? (all.holdout_period-1) : 0); all.sd->t += all.p->lp.get_weight(ae->ld); ae->example_t = (float)all.sd->t; + if (all.ignore_some) { if (all.audit || all.hash_inv) diff --git a/vowpalwabbit/searn.cc b/vowpalwabbit/searn.cc index 2d01560e..4d283172 100644 --- a/vowpalwabbit/searn.cc +++ b/vowpalwabbit/searn.cc @@ -659,17 +659,23 @@ namespace Searn } void set_most_recent_snapshot_action(searn_private* priv, uint32_t action, float loss) { + if ((priv->state == GET_TRUTH_STRING) || + (priv->state == INIT_TEST)) + return; if (priv->most_recent_snapshot_end == (size_t)-1) return; bool on_training_path = priv->state == INIT_TRAIN || priv->state == BEAM_INIT; - cdbg << "set: " << priv->most_recent_snapshot_begin << "\t" << priv->most_recent_snapshot_end << "\t" << priv->most_recent_snapshot_hash << "\totp=" << on_training_path << endl; + cdbg << "set: " << priv->most_recent_snapshot_begin << "\t" << priv->most_recent_snapshot_end << "\t" << priv->most_recent_snapshot_hash << "\totp=" << on_training_path << "\tloss=" << loss << "\taction=" << action << endl; snapshot_item_ptr sip = { priv->most_recent_snapshot_begin, priv->most_recent_snapshot_end, priv->most_recent_snapshot_hash }; + cdbg << "sip: start=" << sip.start << " end=" << sip.end << " hash=" << sip.hash_value << endl; snapshot_item_result &res = priv->snapshot_map->get(sip, sip.hash_value); if (res.loss < 0.f) { // not found! snapshot_item_result me = { action, loss, on_training_path }; priv->snapshot_map->put_after_get(sip, sip.hash_value, me); + cdbg << "adding snapshot, new size = " << priv->snapshot_data.size() << endl; } else { + clog << "found: action=" << res.action << " loss=" << res.loss << " otp=" << res.on_training_path << endl; assert(false); } } @@ -1038,42 +1044,6 @@ namespace Searn } - uint32_t searn_predict(searn_private* priv, example* ecs, size_t num_ec, v_array<uint32_t> *yallowed, v_array<uint32_t> *ystar, bool ystar_is_uint32t) // num_ec == 0 means normal example, >0 means ldf, yallowed==NULL means all allowed, ystar==NULL means don't know; ystar_is_uint32t means that the ystar ref is really just a uint32_t - { - vw* all = priv->all; - learner* base = priv->base_learner; - searn* srn=(searn*)all->searnstr; - uint32_t a; - - //bool found_ss = get_most_recent_snapshot_action(priv, a); - - //if (!found_ss) a = (uint32_t)-1; - if (srn->priv->rollout_all_actions) - a = searn_predict_without_loss<COST_SENSITIVE::label>(*all, *base, ecs, num_ec, yallowed, ystar, ystar_is_uint32t); - else - a = searn_predict_without_loss<CB::label >(*all, *base, ecs, num_ec, yallowed, ystar, ystar_is_uint32t); - - //set_most_recent_snapshot_action(priv, a); - priv->snapshotted_since_predict = false; - - if (priv->auto_hamming_loss) { - float this_loss = 0.; - if (ystar) { - if (ystar_is_uint32t && // single allowed ystar - (*((uint32_t*)ystar) != (uint32_t)-1) && // not a test example - (*((uint32_t*)ystar) != a)) // wrong prediction - this_loss = 1.; - if ((!ystar_is_uint32t) && // many allowed ystar - (!v_array_contains(*ystar, a))) - this_loss = 1.; - } - searn_declare_loss(priv, 1, this_loss); - } - - return a; - } - - bool snapshot_binary_search_lt(v_array<snapshot_item> a, size_t desired_t, size_t tag, size_t &pos, size_t last_found_pos) { size_t hi = a.size(); if (hi == 0) return false; @@ -1139,10 +1109,13 @@ namespace Searn return false; } + void searn_snapshot_data(searn_private* priv, size_t index, size_t tag, void* data_ptr, size_t sizeof_data, bool used_for_prediction) { if ((priv->state == NONE) || (priv->state == INIT_TEST) || (priv->state == GET_TRUTH_STRING) || (priv->state == BEAM_PLAYOUT)) return; + priv->snapshotted_since_predict = true; + size_t i; if ((priv->state == LEARN) && (priv->t <= priv->learn_t) && snapshot_binary_search_lt(priv->snapshot_data, priv->learn_t, tag, i, priv->snapshot_last_found_pos)) { @@ -1159,7 +1132,6 @@ namespace Searn } if ((priv->state == INIT_TRAIN) || (priv->state == LEARN)) { - priv->snapshotted_since_predict = true; priv->most_recent_snapshot_end = priv->snapshot_data.size(); cdbg << "end = " << priv->most_recent_snapshot_end << endl; @@ -1182,7 +1154,7 @@ namespace Searn } snapshot_item item = { index, tag, new_data, sizeof_data, priv->t }; priv->snapshot_data.push_back(item); - //cerr << "priv->snapshot_data.push_back(item);" << endl; + cdbg << "priv->snapshot_data.push_back(item);" << endl; return; } @@ -1264,32 +1236,80 @@ namespace Searn } - void searn_snapshot(searn_private* priv, size_t index, size_t tag, void* data_ptr, size_t sizeof_data, bool used_for_prediction) { - if (! priv->do_snapshot) return; - if (tag == 1) { - priv->most_recent_snapshot_hash = 38429103; - priv->most_recent_snapshot_begin = priv->snapshot_data.size(); - priv->most_recent_snapshot_end = -1; - cdbg << "end = -1 ***" << endl; - priv->most_recent_snapshot_loss = 0.f; - if (priv->loss_declared) - switch (priv->state) { - case INIT_TEST : priv->most_recent_snapshot_loss = priv->test_loss; break; - case INIT_TRAIN: priv->most_recent_snapshot_loss = priv->train_loss; break; - case LEARN : priv->most_recent_snapshot_loss = priv->learn_loss; break; - default : break; - } + void searn_snapshot_initialize(searn_private* priv, size_t index) { + priv->most_recent_snapshot_hash = 38429103; + priv->most_recent_snapshot_begin = priv->snapshot_data.size(); + priv->most_recent_snapshot_end = -1; + cdbg << "end = -1 ***" << endl; + priv->most_recent_snapshot_loss = 0.f; + if (priv->loss_declared) + switch (priv->state) { + case INIT_TEST : priv->most_recent_snapshot_loss = priv->test_loss; break; + case INIT_TRAIN: priv->most_recent_snapshot_loss = priv->train_loss; break; + case LEARN : priv->most_recent_snapshot_loss = priv->learn_loss; break; + default : break; + } - if (priv->state == INIT_TRAIN) - priv->final_snapshot_begin = priv->most_recent_snapshot_begin; + if (priv->state == INIT_TRAIN) + priv->final_snapshot_begin = priv->most_recent_snapshot_begin; - if (priv->auto_history) { - size_t history_size = sizeof(uint32_t) * priv->hinfo.length; - searn_snapshot_data(priv, index, 0, priv->rollout_action.begin + priv->t, history_size, true); + if (priv->auto_history) { + size_t history_size = sizeof(uint32_t) * priv->hinfo.length; + searn_snapshot_data(priv, index, 0, priv->rollout_action.begin + priv->t, history_size, true); + } + } + + + uint32_t searn_predict(searn_private* priv, example* ecs, size_t num_ec, v_array<uint32_t> *yallowed, v_array<uint32_t> *ystar, bool ystar_is_uint32t) // num_ec == 0 means normal example, >0 means ldf, yallowed==NULL means all allowed, ystar==NULL means don't know; ystar_is_uint32t means that the ystar ref is really just a uint32_t + { + vw* all = priv->all; + learner* base = priv->base_learner; + searn* srn=(searn*)all->searnstr; + uint32_t a; + + // handle the case where you want auto-history but you're not snapshotting yourself + if ((!priv->snapshotted_since_predict) && priv->auto_history) { + searn_snapshot_initialize(priv, priv->t); + } + + //bool found_ss = get_most_recent_snapshot_action(priv, a); + + //if (!found_ss) a = (uint32_t)-1; + if (srn->priv->rollout_all_actions) + a = searn_predict_without_loss<COST_SENSITIVE::label>(*all, *base, ecs, num_ec, yallowed, ystar, ystar_is_uint32t); + else + a = searn_predict_without_loss<CB::label >(*all, *base, ecs, num_ec, yallowed, ystar, ystar_is_uint32t); + + //set_most_recent_snapshot_action(priv, a); + priv->snapshotted_since_predict = false; + + if (priv->auto_hamming_loss) { + float this_loss = 0.; + if (ystar) { + if (ystar_is_uint32t && // single allowed ystar + (*((uint32_t*)ystar) != (uint32_t)-1) && // not a test example + (*((uint32_t*)ystar) != a)) // wrong prediction + this_loss = 1.; + if ((!ystar_is_uint32t) && // many allowed ystar + (!v_array_contains(*ystar, a))) + this_loss = 1.; } + searn_declare_loss(priv, 1, this_loss); } + return a; + } + + void searn_snapshot(searn_private* priv, size_t index, size_t tag, void* data_ptr, size_t sizeof_data, bool used_for_prediction) { + if (! priv->do_snapshot) return; + if ((priv->state == GET_TRUTH_STRING) || + (priv->state == INIT_TEST)) + return; + + if (tag == 1) + searn_snapshot_initialize(priv, index); + searn_snapshot_data(priv, index, tag, data_ptr, sizeof_data, used_for_prediction); if (priv->state == INIT_TRAIN) priv->final_snapshot_end = priv->most_recent_snapshot_end; |