Skip to content

Commit

Permalink
FIX bug in averaging
Browse files Browse the repository at this point in the history
  • Loading branch information
jihelhere committed Jan 17, 2013
1 parent eecb9c2 commit 2c06662
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 75 deletions.
39 changes: 29 additions & 10 deletions src/Example.hh
Original file line number Diff line number Diff line change
Expand Up @@ -39,30 +39,49 @@ struct Example {
char * input = line;
char *token = NULL;


// fprintf(stderr, "%s", line);

//TODO: uncomment this
// char *comment = strchr(input, '#');
// if(comment != NULL) *comment = '\0'; // skip comments

token = strsep(&input, " \t"); // read loss
loss = strtod(token, NULL);
for(;(token = strsep(&input, " \t\n")) && *token != '\0' ;) {
char* value = strrchr(token, ':');
token = strsep(&input, " \t"); // read loss
loss = strtod(token, NULL);
// fprintf(stderr, "loss: %g\n", loss);
for(;(token = strsep(&input, " \t\n")) && *token != '\0' ;) {
// fprintf(stderr, "token: %s\n", token);
char* value = strrchr(token, ':');

*value = '\0';
double value_as_double = strtod(value + 1, NULL);
int feature_id = strtol(token, NULL, 10);
features.emplace_back(feature_id, value_as_double);

}

// fprintf(stderr, "line loaded\n");

*value = '\0';
double value_as_double = strtod(value + 1, NULL);
int feature_id = strtol(token, NULL, 10);
features.emplace_back(feature_id, value_as_double);

}
}

double compute_score(const std::vector<double>& weights) {
score = 0;

// fprintf(stderr, "weights.size is: %ld\n", weights.size());

// for (auto i = features.begin(); i != features.end(); ++i)
// {
// fprintf(stderr, "<%d,%g> ", i->id, i->value);
// }

for(auto i = features.begin(); i != features.end(); ++i) {
if(i->id < weights.size()) score += i->value * weights[i->id];
// fprintf(stderr, "id %i\n", i->id);
// if(i->id < weights.size())
// fprintf(stderr, "weight id %f\n", weights[i->id]);
// else
// fprintf(stderr, "weight id too big\n");
if(i->id < weights.size()) score += i->value * weights[i->id];
}
return score;
}
Expand Down
7 changes: 7 additions & 0 deletions src/ExampleMaker.hh
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,11 @@ namespace ranker {
lock.unlock();

Example * e = new Example(string);
// fprintf(stderr, "before compute_score\n");
e->compute_score(weights);
// fprintf(stderr, "after compute_score\n");

// fprintf(stderr, "before resize\n");

lock_type lock2(*mutex_examples);
if (examples.size() < lines.size())
Expand All @@ -73,6 +76,10 @@ namespace ranker {

delete lines[index];


// fprintf(stderr, "after resize\n");


}
}

Expand Down
48 changes: 28 additions & 20 deletions src/MiraOperator.hh
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace ranker {
struct MiraOperator
{
int loop;
int iteration;
int iteration;
int num_examples;

double clip;
Expand All @@ -24,10 +24,10 @@ namespace ranker {

MiraOperator(int loop_, int iteration_, int num_examples_, double clip_,
std::vector<double> &weights_, std::vector<double> &avgWeights_)
:
:
loop(loop_), iteration(iteration_), num_examples(num_examples_),
clip(clip_),
weights(weights_), avgWeights(avgWeights_),
weights(weights_), avgWeights(avgWeights_),
num(0), oracle(NULL)
{};

Expand All @@ -39,24 +39,24 @@ namespace ranker {
}

inline
bool incorrect_rank(const Example * example)
bool incorrect_rank(const Example * example)
{
return example->score > oracle->score || (example->score == oracle->score && example->loss > oracle->loss);
}


void operator()(Example * example)
{
// fprintf(stderr, "example: %g score: %g\n", example->score, example->loss);
// fprintf(stderr, "example: %g score: %g\n", example->score, example->loss);

// skip the oracle -> useless update
if(example == oracle) return;
//fprintf(stderr, "mira: os: %g ol: %g es: %g el: %g\n", oracle->score, oracle->loss, example->score, example->loss);


//sort(example->features.begin(), example->features.end());
sort(oracle->features.begin(), oracle->features.end());
sort(example->features.begin(), example->features.end());
if(incorrect_rank(example)) {

//copy
auto i = oracle->features.begin(), j = example->features.begin();
double norm = 0;
Expand All @@ -81,32 +81,37 @@ namespace ranker {

double alpha = 0.0;
double delta = example->loss - oracle->loss - (oracle->score - example->score);

delta /= norm;
alpha += delta;

if(alpha < 0) alpha = 0;
if(alpha > clip) alpha = clip;


double avgUpdate(double(loop * num_examples - (num_examples * ((iteration + 1) - 1) + (num )) + 1));

double avgalpha = alpha * avgUpdate;
// fprintf(stderr, "norm: %g alpha: %g\n", norm, alpha);

//update weight vectors


//fprintf(stderr, "%lu %lu\n", oracle->features.size(), example->features.size());


sort(oracle->features.begin(), oracle->features.end());
sort(example->features.begin(), example->features.end());
unsigned s = oracle->features.back().id > example->features.back().id ?
oracle->features.back().id : example->features.back().id ;


// fprintf(stderr, "before resizing to %d\n", s);

// fprintf(stderr, "before resizing to %d\n", s);
if(weights.size() <= s) {
weights.resize(s+1, 0);
avgWeights.resize(s+1, 0);
}
// fprintf(stderr, "after resizing\n");
// fprintf(stderr, "after resizing\n");

i = oracle->features.begin();
j = example->features.begin();

Expand All @@ -119,7 +124,7 @@ namespace ranker {
weights[j->id] -= alpha * j->value;
avgWeights[j->id] -= avgalpha * j->value;
++j;

} else {
assert(i->id == j->id);
double difference = i->value - j->value;
Expand All @@ -129,20 +134,23 @@ namespace ranker {
++j;
}
}
while(i != oracle->features.end()) {
while(i != oracle->features.end()) {
weights[i->id] += alpha * i->value;
avgWeights[i->id] += avgalpha * i->value;
++i;
}
while(j != example->features.end()) {
while(j != example->features.end()) {
// fprintf(stderr, "size weights: %lu\n", weights.size());
weights[j->id] -= alpha * j->value;
// fprintf(stderr, "size avgWeights: %lu\n", avgWeights.size());
// fprintf(stderr, "j->id: %lu\n", j->id);
avgWeights[j->id] -= avgalpha * j->value;
++j;
}
}
}
};

}

#endif
51 changes: 25 additions & 26 deletions src/filter_and_map.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,25 @@
#include "utils.h"


#include <algorithm>

#define MAX_FEATURE 10000


using namespace std;

typedef struct feature {
struct feature_t {
int id;
char* name;
char* value;
} feature_t;

int feature_id_comparator(const void* a, const void* b) {
if(((feature_t*)a)->id > ((feature_t*)b)->id) return 1;
return -1;
}
bool operator<(const feature_t& other) const
{
return id < other.id;
}

bool dictionary_comparator(const pair<string, int> &a, const pair<string, int> &b) {
return a.first < b.first;
}
} ;

struct eqstr
{
bool operator()(const char* s1, const char* s2) const
{
return (s1 == s2) || (s1 && s2 && strcmp(s1, s2) == 0);
}
};

int main(int argc, char** argv) {
if(argc != 3) {
Expand Down Expand Up @@ -63,7 +58,7 @@ int main(int argc, char** argv) {
}
fprintf(stderr, "\rloading %d\n", num);
fclose(fp);
feature_t features[100000];
feature_t features[MAX_FEATURE];
int num_features = 0;
while(0 < (length = read_line(&buffer, &buffer_size, stdin))) {
buffer[length - 1] = '\0'; // chop
Expand All @@ -80,20 +75,24 @@ int main(int argc, char** argv) {
*end = '\0';
auto id = dictionary.find(string(token));
if(id != dictionary.end()) {
if(num_features >= 100000) {
fprintf(stderr, "ERROR: example has more than 100k features\n");
if(num_features >= MAX_FEATURE) {
fprintf(stderr, "ERROR: example has more than %d features\n", MAX_FEATURE);
exit(1);
}
features[num_features].id = id->second;
features[num_features].value = end + 1;
features[num_features].name = token;
num_features++;

feature_t& current = features[num_features];

current.id = id->second;
current.value = end + 1;
current.name = token;
++num_features;
}
}
}
qsort(features, num_features, sizeof(feature_t), feature_id_comparator);
int i;
for(i = 0; i < num_features; i++) {

std::sort(features, features+num_features);

for(int i = 0; i < num_features; i++) {
fprintf(stdout, " %d:%s", features[i].id, features[i].value);
}
fprintf(stdout, "\n");
Expand Down
16 changes: 9 additions & 7 deletions src/ranker-learn.cc
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ int main(int argc, char** argv) {
{"test", required_argument, 0, 't'},
{"clip", required_argument, 0, 'c'},
{"iterations", required_argument, 0, 'i'},
{"threads", required_argument, 0, 'j'},
{"threads", required_argument, 0, 'j'},
{"examples", required_argument, 0, 'e'},
{0, 0, 0, 0}
};
Expand Down Expand Up @@ -385,7 +385,7 @@ int main(int argc, char** argv) {
std::vector<double> weights;
std::vector<double> avgWeights;
std::vector<double> saveweights;

std::vector<double> predWeights;
double dev_loss = -1;


Expand All @@ -396,25 +396,27 @@ int main(int argc, char** argv) {
ranker::MiraOperator mira(loop, iteration, num_examples, clip, weights, avgWeights);
(void) process(trainset, filter, weights, true, num_threads, mira);
// averaging for next iteration

predWeights.resize(avgWeights.size());
for(unsigned int i = 0; i < avgWeights.size(); ++i) {
if(avgWeights[i] != 0.0)
weights[i] = avgWeights[i] / (num_examples * loop);
predWeights[i] = avgWeights[i] / (num_examples * loop);
}

if(devset) {
double d = process(devset, filter, weights, false, num_threads, mira);
double d = process(devset, filter, predWeights, false, num_threads, mira);
if(dev_loss < 0 || d < dev_loss) {
dev_loss = d;
saveweights = weights;
saveweights = predWeights;
}
}

if(testset)
(void) process(testset, filter, weights, false, num_threads, mira);
(void) process(testset, filter, predWeights, false, num_threads, mira);
}


if(dev_loss < 0) { saveweights = weights;}
if(dev_loss < 0) { saveweights = predWeights;}

for(unsigned int i = 0; i < saveweights.size(); ++i) {
if(saveweights[i] != 0) {
Expand Down
Loading

0 comments on commit 2c06662

Please sign in to comment.