20 #include <tr1/unordered_map> 21 #include <tr1/unordered_set> 22 #include <boost/math/constants/constants.hpp> 23 #include <boost/random/mersenne_twister.hpp> 39 virtual const pair<PARAMS, double> operator() (
PARAMS&) = 0;
41 virtual void Init (
int) = 0;
45 virtual void LoadRefData (std::vector<std::string>) = 0;
47 virtual void InitTuneSet (
bool) = 0;
58 boost::random::mt19937 rand_gen;
64 PARAMS GenerateDirection();
68 template<
typename Algo,
typename ErrorSurface>
81 sid (sid), lambda (lambda), direction (direction), lats (lats), surface (
87 tracer <<
"lattice line optimization: sentence s=" << sid <<
'\n';
91 std::cerr <<
"ERROR: invalid vector lattice for sentence s=" << sid
96 const typename Algo::Lines lines = Algo::ComputeLatticeEnvelope (fst,
105 double prevScore = 0.0;
106 double prevExpScore = 0.0;
107 for (
typename Algo::Lines::const_iterator line = lines.begin();
108 line != lines.end(); ++line) {
111 line->t.size() < 2 ? offset = 0 : offset = 1;
112 Sentence h (line->t.begin() + offset,
113 line->t.end() - offset);
115 if (line == lines.begin() ) {
116 expScore = ( (++lines.begin() )->x - 1) * line->m + line->y;
117 surface->
CreateInitial (sid, line->x, h, line->score, expScore);
119 expScore = line->x * line->m + line->y;
120 surface->
CreateInterval (sid, line->x, h, line->score - prevScore,
121 expScore - prevExpScore);
123 prevScore = line->score;
124 prevExpScore = expScore;
135 template<
class Algo,
class ErrorSurface>
141 tasks.begin(); it != tasks.end(); ++it) {
148 template<
class Algo,
class ErrorSurface>
153 typedef typename ErrorStats::Error
Error;
157 const PARAMS& direction,
const OptimizationResult& prev) {
168 ErrorSurface& surface,
const std::vector<Sid>& lattices) {
169 std::vector<OptimizeTask<Algo, ErrorSurface> > tasks;
170 for (std::vector<Sid>::const_iterator sit = lattices.begin();
171 sit != lattices.end(); ++sit) {
173 & (this->lats), &surface);
174 tasks.push_back (task);
180 const std::vector<OptimizationResult>& results) {
183 for (
unsigned int k = 0; k < results.size(); ++k) {
184 double bleu = results[k].get_tunedScore().GetError()
185 - results[k].get_startScore().GetError();
195 const OptimizationResult& tuned,
const PARAMS& direction,
196 const double gamma) {
197 Error startError = start.second;
198 Error tunedError = tuned.second;
200 const PARAMS& startPoint = start.first;
201 const PARAMS& tunedPoint = tuned.first;
203 << startPoint <<
" " << std::setprecision (6) << startError
205 tracer <<
" direction: " << std::fixed
208 << tunedPoint << std::setprecision (6) <<
" " << tunedError
210 tracer <<
" gamma: " << std::fixed << std::setprecision (8) << gamma <<
'\n';
213 static unsigned int counter = 0;
214 static const unsigned int dim = direction.size();
215 static const unsigned int percent = dim < 1000 ? 1 : dim / 1000;
216 counter = (counter + 1) % dim;
217 if (counter % percent == 0) {
218 tracer <<
"gamma: " << gamma <<
" error: " << tunedError
230 refData.LoadRefData (refs);
241 return Score (this->refData, this->lats, lambda);
259 const PARAMS& Get (
const unsigned int);
261 void Set (
const unsigned int,
PARAMS);
263 void Set (std::vector<PARAMS>,
TuneSet&);
267 void Resize (
unsigned int,
TuneSet& lats);
269 const std::vector<Sid> FilteredLattices (
unsigned int,
const std::vector<Sid>&);
271 bool ContainsAxis (
unsigned int);
275 bool ContainsAxis (
Sid,
unsigned int);
277 unordered_map<unsigned int, PARAMS> directions;
286 unordered_map<Sid, unordered_set<unsigned int> > feature_filter;
292 template<
typename Algo,
typename ErrorSurface>
300 unsigned int directions;
305 virtual void Init (
int);
309 virtual const pair<PARAMS, double> operator() (
PARAMS& startPoint) {
310 Error startError =
ComputeError (this->refData, this->lats, startPoint);
311 OptimizationResult start = make_pair (startPoint, startError);
312 OptimizationResult prev = start;
314 OptimizationResult best = prev;
315 std::vector<PARAMS> generatedDirs;
317 for (
int i = 0; i < dim; ++i) {
319 for (
int j = 0; j < dim; ++j) {
323 generatedDirs.push_back (dir);
326 for (
int i = 0; i < directions; ++i) {
329 for (std::vector<PARAMS>::const_iterator direction =
330 generatedDirs.begin(); direction != generatedDirs.end();
332 ErrorSurface surface (this->lats.ids.size(), & (this->refData) );
333 this->LineOptimize (prev.first, *direction, surface, this->lats.ids);
334 OptimizationResult current = this->MakeOptimizationResult (surface,
336 this->LogLineOptimization (prev, current, *direction,
341 " parameters not updated: no interval boundaries\n";
352 " parameters not updated: change in gamma < " 357 if (current.second > best.second) {
362 tracer <<
"full random iteration completed with error: " 363 << best.second <<
'\n';
367 if (best.second.GetError() - prev.second.GetError()
370 "no direction gives sufficient improvement: delta bleu < " 376 return make_pair (prev.first, prev.second.GetError() );
380 template<
typename Algo,
typename ErrorSurface>
391 unsigned int bestDirection,
Directions& directions) {
392 PARAMS extrapolated_d =
final.first -
394 PARAMS extrapolated_p =
final.first +
396 double dbm = bestChange;
397 double dbt =
final.second.GetError() -
398 start.second.GetError();
400 ComputeError (this->refData, this->lats, extrapolated_p).GetError()
401 - start.second.GetError();
403 && 2 * (2 * dbt - dbe) * powf (dbt - dbm, 2.0)
404 < powf (dbe, 2.0) * dbm) {
406 tracer <<
"replacing direction[" << bestDirection <<
"]" << std::fixed
413 virtual void Init (
int);
415 virtual const pair<PARAMS, double> operator() (
PARAMS& startPoint) {
416 ErrorSurface surface (this->lats.ids.size(), & (this->refData) );
417 Error startError =
ComputeError (this->refData, this->lats, startPoint);
422 double bestDeltaBleu = 0.0;
423 unsigned int bestDirection = 0;
424 for (
unsigned int d = 0; d < directions.
Size(); ++d) {
432 this->LineOptimize (prev.first, directions.
Get (d), testSurface, filtered);
437 Error debugError =
ComputeError (this->refData, this->lats, current.first);
438 if (debugError.GetError() != current.second.GetError() ) {
439 tracer <<
"Direction: " << d
440 <<
" Incorrect Error Surface: " 447 this->LogLineOptimization (prev, current, directions.
Get (d),
449 double deltaBleu = current.second.GetError()
450 - prev.second.GetError();
451 if (deltaBleu > bestDeltaBleu) {
452 bestDeltaBleu = deltaBleu;
461 " parameters not updated: no interval boundaries\n";
467 tracer <<
" parameters not updated: delta bleu < " 475 " parameters not updated: change in gamma < " 484 surface = testSurface;
487 if (prev.second.GetError() - start.second.GetError()
490 "no direction gives sufficient improvement: delta bleu < " 494 UpdateDirection (start, prev, bestDeltaBleu, bestDirection,
498 tracer <<
"full powell iteration compleated with error: " 499 << prev.second <<
'\n';
504 return make_pair (prev.first, prev.second.GetError() );
const PARAMS & Get(const unsigned int)
RefData::ErrorStats::Error ComputeError(RefData &refData, const TuneSet &lats, const PARAMS &lambda)
PARAMS GenerateDirection()
void CreateInterval(Sid sid, const double gamma, const Sentence h, const double modelScore, const double expScore)
TupleArcFst * GetVectorLattice(const Sid s, const bool use_cache) const
OptimizationResult MakeOptimizationResult(ErrorSurface &surface, const PARAMS &direction, const OptimizationResult &prev)
void CreateInitial(Sid sid, const double gamma, const Sentence h, const double modelScore, const double expScore)
void Initialize(const bool use_cache)
void Set(const unsigned int, PARAMS)
ErrorSurface::RefData refData
PARAMS GenerateRandDir(const unsigned int noOfAxes)
virtual void InitTuneSet(bool useCache)
Trivial implementation of a threadpool based on boost::asio methods When initiated, creates a threadpool of n threads (n <= number of cpus). Jobs should be submitted with the templated operator(). When the object is deleted it will wait for all threads to finish.
void LineOptimize(const PARAMS &lambda, const PARAMS &direction, ErrorSurface &surface, const std::vector< Sid > &lattices)
bool check_in_range(const unsigned int k, const double gamma) const
OptimizerImpl< Algo, ErrorSurface >::OptimizationResult OptimizationResult
std::vector< Wid > Sentence
virtual ~RandomOptimizer()
virtual void LoadRefData(std::vector< std::string > refs)
PARAMS ComputeFinalPoint(const PARAMS &, const PARAMS &, const double)
std::vector< IntervalBoundary > boundaries
RefData::ErrorStats ErrorStats
OptimizerImpl< Algo, ErrorSurface >::Error Error
PARAMS VectorScale(const PARAMS &, const unsigned int k=0)
bool ContainsAxis(unsigned int)
const std::vector< Sid > FilteredLattices(unsigned int, const std::vector< Sid > &)
void execute_with_threadpool(std::vector< OptimizeTask< Algo, ErrorSurface > > tasks)
Implements trivial threadpool using boost::asio library.
unsigned int GetBestOptimizationDirection(const std::vector< OptimizationResult > &results)
std::string Score(RefData &refData, const TuneSet &lats, const PARAMS &lambda)
OptimizeTask(const Sid sid, PARAMS const *lambda, PARAMS const *direction, TuneSet const *lats, ErrorSurface *surface)
pair< PARAMS, Error > OptimizationResult
virtual std::string ComputeError(const PARAMS &lambda)
void WriteErrorSurface(const std::string &filename) const
virtual ~PowellOptimizer()
hifst-specific classes and methods included in this namespace.
void LogLineOptimization(const OptimizationResult &start, const OptimizationResult &tuned, const PARAMS &direction, const double gamma)
ErrorSurface::ErrorStats ErrorStats
All included standard headers, boost headers,...
Static variable for custom_assert. Include only once from main file.