diff options
author | Tetsuo Kiso <tetsuo-s@is.naist.jp> | 2012-02-01 10:21:49 +0400 |
---|---|---|
committer | Tetsuo Kiso <tetsuo-s@is.naist.jp> | 2012-02-01 10:21:49 +0400 |
commit | c1c9c1c8bbbf44496d4e6c5703ddd86711fe3975 (patch) | |
tree | 438c71ac416b2e1ee4f4a11ffb848de49ae4d73e /mert | |
parent | 616b014554ec989afc387815e8b6672d80e1bab0 (diff) |
Create a struct for command line options in mert.
Diffstat (limited to 'mert')
-rwxr-xr-x | mert/mert.cpp | 272 |
1 files changed, 151 insertions, 121 deletions
diff --git a/mert/mert.cpp b/mert/mert.cpp index 10f710bd2..f79607b40 100755 --- a/mert/mert.cpp +++ b/mert/mert.cpp @@ -46,7 +46,7 @@ class OptimizationTask : public Moses::Task { } } - bool DeleteAfterExecution() const { + bool DeleteAfterExecution() { return false; } @@ -116,94 +116,96 @@ static struct option long_options[] = { {"help",no_argument,0,'h'}, {0, 0, 0, 0} }; -int option_index; -} // anonymous namespace - -int main (int argc, char **argv) -{ - ResetUserTime(); +struct ProgramOption { + string to_optimize_str; + int pdim; + int ntry; + int nrandom; + int seed; + bool has_seed; + string optimize_type; + string scorer_type; + string scorer_config; + string scorer_file; + string feature_file; + string init_file; + size_t num_threads; + float shard_size; + size_t shard_count; + + ProgramOption() + : to_optimize_str(""), + pdim(-1), + ntry(1), + nrandom(0), + seed(0), + has_seed(false), + optimize_type("powell"), + scorer_type("BLEU"), + scorer_config(""), + scorer_file("statscore.data"), + feature_file("features.data"), + init_file("init.opt"), + num_threads(1), + shard_size(0), + shard_count(0) { } +}; - /* - Timer timer; - timer.start("Starting..."); - */ - - int c,pdim; - pdim=-1; - int ntry=1; - int nrandom=0; - int seed=0; - bool hasSeed = false; -#ifdef WITH_THREADS - size_t threads=1; -#endif - float shard_size = 0; - size_t shard_count = 0; - string type("powell"); - string scorertype("BLEU"); - string scorerconfig(""); - string scorerfile("statscore.data"); - string featurefile("features.data"); - string initfile("init.opt"); - - string tooptimizestr(""); - vector<unsigned> tooptimize; - vector<vector<parameter_t> > start_list; - vector<parameter_t> min; - vector<parameter_t> max; - // NOTE: those mins and max are the bound for the starting points of the algorithm, not strict bound on the result! +void ParseCommandOptions(int argc, char** argv, ProgramOption* opt) { + int c; + int option_index; - while ((c=getopt_long (argc, argv, "o:r:d:n:m:t:s:S:F:v:p:", long_options, &option_index)) != -1) { + while ((c = getopt_long(argc, argv, "o:r:d:n:m:t:s:S:F:v:p:", long_options, &option_index)) != -1) { switch (c) { case 'o': - tooptimizestr = string(optarg); + opt->to_optimize_str = string(optarg); break; case 'd': - pdim = strtol(optarg, NULL, 10); + opt->pdim = strtol(optarg, NULL, 10); break; case 'n': - ntry=strtol(optarg, NULL, 10); + opt->ntry = strtol(optarg, NULL, 10); break; case 'm': - nrandom=strtol(optarg, NULL, 10); + opt->nrandom = strtol(optarg, NULL, 10); break; case 'r': - seed=strtol(optarg, NULL, 10); - hasSeed = true; + opt->seed = strtol(optarg, NULL, 10); + opt->has_seed = true; break; case 't': - type=string(optarg); + opt->optimize_type = string(optarg); break; case's': - scorertype=string(optarg); + opt->scorer_type = string(optarg); break; case 'c': - scorerconfig = string(optarg); + opt->scorer_config = string(optarg); break; case 'S': - scorerfile=string(optarg); + opt->scorer_file = string(optarg); break; case 'F': - featurefile=string(optarg); + opt->feature_file = string(optarg); break; case 'i': - initfile=string(optarg); + opt->init_file = string(optarg); break; case 'v': - setverboselevel(strtol(optarg,NULL,10)); + setverboselevel(strtol(optarg, NULL, 10)); break; #ifdef WITH_THREADS case 'T': - threads = strtol(optarg, NULL, 10); - if (threads < 1) threads = 1; + opt->num_threads = strtol(optarg, NULL, 10); + if (opt->num_threads < 1) opt->num_threads = 1; break; #endif case 'a': - shard_count = strtof(optarg,NULL); + opt->shard_count = strtof(optarg, NULL); break; case 'b': - shard_size = strtof(optarg,NULL); + opt->shard_size = strtof(optarg, NULL); break; case 'h': usage(0); @@ -212,62 +214,82 @@ int main (int argc, char **argv) usage(1); } } - if (pdim < 0) +} + +} // anonymous namespace + +int main(int argc, char **argv) +{ + ResetUserTime(); + + ProgramOption option; + ParseCommandOptions(argc, argv, &option); + + vector<unsigned> to_optimize; + vector<vector<parameter_t> > start_list; + vector<parameter_t> min; + vector<parameter_t> max; + // NOTE: those mins and max are the bound for the starting points of the algorithm, not strict bound on the result! + + if (option.pdim < 0) usage(1); - cerr << "shard_size = " << shard_size << " shard_count = " << shard_count << endl; - if (shard_size && !shard_count) { + cerr << "shard_size = " << option.shard_size << " shard_count = " << option.shard_count << endl; + if (option.shard_size && !option.shard_count) { cerr << "Error: shard-size provided without shard-count" << endl; exit(1); } - if (shard_size > 1 || shard_size < 0) { + if (option.shard_size > 1 || option.shard_size < 0) { cerr << "Error: shard-size should be between 0 and 1" << endl; exit(1); } - if (hasSeed) { - cerr << "Seeding random numbers with " << seed << endl; - srandom(seed); + if (option.has_seed) { + cerr << "Seeding random numbers with " << option.seed << endl; + srandom(option.seed); } else { cerr << "Seeding random numbers with system clock " << endl; srandom(time(NULL)); } // read in starting points - std::string onefile; - while (!initfile.empty()) { - getNextPound(initfile, onefile, ","); + string onefile; + while (!option.init_file.empty()) { + getNextPound(option.init_file, onefile, ","); vector<parameter_t> start; ifstream opt(onefile.c_str()); - if(opt.fail()) { - cerr<<"could not open initfile: " << initfile << endl; + if (opt.fail()) { + cerr << "could not open initfile: " << option.init_file << endl; exit(3); } - start.resize(pdim);//to do:read from file + start.resize(option.pdim);//to do:read from file int j; - for( j=0; j<pdim&&!opt.fail(); j++) - opt>>start[j]; - if(j<pdim) { - cerr<<initfile<<":Too few starting weights." << endl; + for (j = 0; j < option.pdim && !opt.fail(); j++) { + opt >> start[j]; + } + if (j < option.pdim) { + cerr << option.init_file << ":Too few starting weights." << endl; exit(3); } start_list.push_back(start); // for the first time, also read in the min/max values for scores if (start_list.size() == 1) { - min.resize(pdim); - for( j=0; j<pdim&&!opt.fail(); j++) - opt>>min[j]; - if(j<pdim) { - cerr<<initfile<<":Too few minimum weights." << endl; - cerr<<"error could not initialize start point with " << initfile << endl; - std::cerr << "j: " << j << ", pdim: " << pdim << std::endl; + min.resize(option.pdim); + for (j = 0; j < option.pdim && !opt.fail(); j++) { + opt >> min[j]; + } + if (j < option.pdim) { + cerr << option.init_file << ":Too few minimum weights." << endl; + cerr << "error could not initialize start point with " << option.init_file << endl; + cerr << "j: " << j << ", pdim: " << option.pdim << endl; exit(3); } - max.resize(pdim); - for( j=0; j<pdim&&!opt.fail(); j++) - opt>>max[j]; - if(j<pdim) { - cerr<<initfile<<":Too few maximum weights." << endl; + max.resize(option.pdim); + for (j = 0; j < option.pdim && !opt.fail(); j++) { + opt >> max[j]; + } + if (j < option.pdim) { + cerr << option.init_file << ":Too few maximum weights." << endl; exit(3); } } @@ -275,13 +297,13 @@ int main (int argc, char **argv) } vector<string> ScoreDataFiles; - if (scorerfile.length() > 0) { - Tokenize(scorerfile.c_str(), ',', &ScoreDataFiles); + if (option.scorer_file.length() > 0) { + Tokenize(option.scorer_file.c_str(), ',', &ScoreDataFiles); } vector<string> FeatureDataFiles; - if (featurefile.length() > 0) { - Tokenize(featurefile.c_str(), ',', &FeatureDataFiles); + if (option.feature_file.length() > 0) { + Tokenize(option.feature_file.c_str(), ',', &FeatureDataFiles); } if (ScoreDataFiles.size() != FeatureDataFiles.size()) { @@ -289,11 +311,12 @@ int main (int argc, char **argv) } // it make sense to know what parameter set were used to generate the nbest - Scorer *TheScorer = ScorerFactory::getScorer(scorertype,scorerconfig); + Scorer *TheScorer = ScorerFactory::getScorer(option.scorer_type, option.scorer_config); //load data Data D(*TheScorer); - for (size_t i=0; i < ScoreDataFiles.size(); i++) { + + for (size_t i = 0; i < ScoreDataFiles.size(); i++) { cerr<<"Loading Data from: "<< ScoreDataFiles.at(i) << " and " << FeatureDataFiles.at(i) << endl; D.load(FeatureDataFiles.at(i), ScoreDataFiles.at(i)); } @@ -310,28 +333,28 @@ int main (int argc, char **argv) //currently sparse weights are not even loaded //statscore_t score = TheScorer->score(bests); - if (tooptimizestr.length() > 0) { - cerr << "Weights to optimize: " << tooptimizestr << endl; + if (option.to_optimize_str.length() > 0) { + cerr << "Weights to optimize: " << option.to_optimize_str << endl; // Parse string to get weights to optimize, and set them as active - std::string substring; + string substring; int index; - while (!tooptimizestr.empty()) { - getNextPound(tooptimizestr, substring, ","); + while (!option.to_optimize_str.empty()) { + getNextPound(option.to_optimize_str, substring, ","); index = D.getFeatureIndex(substring); cerr << "FeatNameIndex:" << index << " to insert" << endl; //index = strtol(substring.c_str(), NULL, 10); - if (index >= 0 && index < pdim) { - tooptimize.push_back(index); + if (index >= 0 && index < option.pdim) { + to_optimize.push_back(index); } else { - cerr << "Index " << index << " is out of bounds. Allowed indexes are [0," << (pdim-1) << "]." << endl; + cerr << "Index " << index << " is out of bounds. Allowed indexes are [0," << option.pdim - 1 << "]." << endl; } } } else { //set all weights as active - tooptimize.resize(pdim);//We'll optimize on everything - for(int i=0; i<pdim; i++) { - tooptimize[i]=1; + to_optimize.resize(option.pdim);//We'll optimize on everything + for (int i = 0; i < option.pdim; i++) { + to_optimize[i] = 1; } } @@ -342,12 +365,12 @@ int main (int argc, char **argv) #ifdef WITH_THREADS - cerr << "Creating a pool of " << threads << " threads" << endl; - Moses::ThreadPool pool(threads); + cerr << "Creating a pool of " << option.num_threads << " threads" << endl; + Moses::ThreadPool pool(option.num_threads); #endif - Point::setpdim(pdim); - Point::setdim(tooptimize.size()); + Point::setpdim(option.pdim); + Point::setdim(to_optimize.size()); //starting points consist of specified points and random restarts vector<Point> startingPoints; @@ -355,27 +378,29 @@ int main (int argc, char **argv) for (size_t i = 0; i < start_list.size(); ++i) { startingPoints.push_back(Point(start_list[i],min,max)); } - for (int i = 0; i < ntry; ++i) { + + for (int i = 0; i < option.ntry; ++i) { startingPoints.push_back(Point(start_list[0],min,max)); startingPoints.back().Randomize(); } - vector<vector<OptimizationTask*> > allTasks(1); //optional sharding vector<Data> shards; - if (shard_count) { - D.createShards(shard_count, shard_size, scorerconfig, shards); - allTasks.resize(shard_count); + if (option.shard_count) { + D.createShards(option.shard_count, option.shard_size, option.scorer_config, shards); + allTasks.resize(option.shard_count); } // launch tasks for (size_t i = 0 ; i < allTasks.size(); ++i) { Data& data = D; - if (shard_count) data = shards[i]; //use the sharded data if it exists + if (option.shard_count) + data = shards[i]; //use the sharded data if it exists + vector<OptimizationTask*>& tasks = allTasks[i]; - Optimizer *O = OptimizerFactory::BuildOptimizer(pdim,tooptimize,start_list[0],type,nrandom); + Optimizer *O = OptimizerFactory::BuildOptimizer(option.pdim, to_optimize, start_list[0], option.optimize_type, option.nrandom); O->SetScorer(data.getScorer()); O->SetFData(data.getFeatureData()); //A task for each start point @@ -400,27 +425,29 @@ int main (int argc, char **argv) // collect results for (size_t i = 0; i < allTasks.size(); ++i) { - statscore_t best=0, mean=0, var=0; + statscore_t best = 0, mean = 0, var = 0; Point bestP; for (size_t j = 0; j < allTasks[i].size(); ++j) { statscore_t score = allTasks[i][j]->getScore(); mean += score; - var += score*score; + var += score * score; if (score > best) { bestP = allTasks[i][j]->getPoint(); best = score; } } - mean/=(float)ntry; - var/=(float)ntry; - var=sqrt(abs(var-mean*mean)); - if (verboselevel()>1) - cerr<<"shard " << i << " best score: "<< best << " variance of the score (for "<<ntry<<" try): "<<var<<endl; + mean /= (float)option.ntry; + var /= (float)option.ntry; + var = sqrt(abs(var - mean * mean)); + + if (verboselevel() > 1) { + cerr << "shard " << i << " best score: " << best << " variance of the score (for " << option.ntry << " try): " << var << endl; + } totalP += bestP; total += best; - if (verboselevel()>1) + if (verboselevel() > 1) cerr << "bestP " << bestP << endl; } @@ -432,12 +459,13 @@ int main (int argc, char **argv) cerr << "bestP: " << finalP << endl; // L1-Normalization of the best Point - if ((int)tooptimize.size() == pdim) + if ((int)to_optimize.size() == option.pdim) { finalP.NormalizeL1(); + } cerr << "Best point: " << finalP << " => " << final << endl; ofstream res("weights.txt"); - res<<finalP<<endl; + res << finalP << endl; for (size_t i = 0; i < allTasks.size(); ++i) { allTasks[i][0]->resetOptimizer(); @@ -448,4 +476,6 @@ int main (int argc, char **argv) delete TheScorer; PrintUserTime("Stopping..."); + + return 0; } |