implementation of optimization on a subset of the parameters + debug mode in the makefile

git-svn-id: https://mosesdecoder.svn.sourceforge.net/svnroot/mosesdecoder/trunk@1695 1f5c12ca-751b-0410-a591-d2e778427230
This commit is contained in:
jfouet 2008-05-15 10:57:20 +00:00
parent c2c30717e0
commit bfe3661110
6 changed files with 167 additions and 48 deletions

View File

@ -43,6 +43,7 @@ public:
inline void clear() { array_.clear(); }
inline FeatureStatsType get(int i){ return array_.at(i); }
inline FeatureStatsType get(int i)const{ return array_.at(i); }
void set(std::string &theString);
@ -80,6 +81,6 @@ public:
};
#endif

View File

@ -3,9 +3,15 @@ ScoreStats.o ScoreArray.o ScoreData.o \
FeatureStats.o FeatureArray.o FeatureData.o \
Data.o \
BleuScorer.o \
Point.o
Point.o \
Optimizer.o
ifndef DEBUG
CFLAGS=-O3 -DTRACE_ENABLE
else
CFLAGS=-DTRACE_ENABLE -g
endif
GCC=g++
LDFLAGS=
LDLIBS=-lm

View File

@ -10,6 +10,8 @@ using namespace std;
static const float MINFLOAT=numeric_limits<float>::min();
static const float MAXFLOAT=numeric_limits<float>::max();
void Optimizer::SetScorer(Scorer *S){
if(scorer)
delete scorer;
@ -22,15 +24,49 @@ void Optimizer::SetFData(FeatureData *F){
FData=F;
};
Optimizer::Optimizer(unsigned Pd,vector<unsigned> i2O,vector<lambda> start):scorer(NULL),FData(NULL){
//warning: the init vector is a full set of parameters, of dimension pdim!
Point::pdim=Pd;
assert(start.size()==Pd);
Point::dim=i2O.size();
Point::optindices=i2O;
if(Point::pdim<Point::dim){
for(int i=0;i<Point::pdim;i++){
int j;
for(j=0;j<Point::dim;j++)
if(i==i2O[j])
break;
if(j==Point::dim)//the index i wasnt found on optindices, it is a fixed index, we use the valu of hte start vector
Point::fixedweights[i]=start[i];
else
init[j]=start[i];//the starting point of the algorithm
}
}else{
init=start;
}
assert(init.GetAllWeights()==start);
};
Optimizer::~Optimizer(){
delete scorer;
delete FData;
}
statscore Optimizer::GetStatScore(const Point& param)const{
vector<unsigned> bests;
Get1bests(param,bests);
return GetStatScore(bests);
};
/**compute the intersection of 2 lines*/
float intersect (float m1, float b1,float m2,float b2){
if(m1==m2)
return MAXFLOAT;//parrallel lines
return((b2-b1)/(m1-m2));
}
statscore Optimizer::LineOptimize(const Point& origin,Point direction,Point& bestpoint){
statscore Optimizer::LineOptimize(const Point& origin,const Point& direction,Point& bestpoint)const{
direction.normalize();//we pass by value so changing is ok
// we are looking for the best Point on the line y=Origin+x*direction
float min_int=0.00001;
typedef pair<float,vector<unsigned> > threshold;
@ -167,8 +203,28 @@ statscore Optimizer::LineOptimize(const Point& origin,Point direction,Point& bes
return bestscore;
};
void Optimizer::Get1bests(const Point& P,vector<unsigned>& bests)const{
assert(FData);
bests.clear();
bests.resize(size());
for(unsigned i=0;i<size();i++){
float bestfs=MINFLOAT;
unsigned idx=0;
unsigned j;
for(j=0;j<FData->get(i).size();j++){
float curfs=P*FData->get(i,j);
if(curfs>bestfs){
bestfs=curfs;
idx=j;
}
}
bests[i]=idx;
}
}
Point Optimizer::Run(const Point& init){
Point Optimizer::Run()const{
if(!FData){
cerr<<"error trying to optimize without Feature loaded"<<endl;
exit(2);
@ -177,18 +233,17 @@ Point Optimizer::Run(const Point& init){
cerr<<"error trying to optimize without a Scorer loaded"<<endl;
exit(2);
}
return TrueRun(init);
return TrueRun();
}
Point SimpleOptimizer::TrueRun(const Point& init){
assert(dimension==init.size());
Point SimpleOptimizer::TrueRun()const{
Point cur=init;
statscore prevscore=FLT_MAX;
statscore bestscore=FLT_MAX;
statscore prevscore=MAXFLOAT;
statscore bestscore=MAXFLOAT;
do{
Point best(dimension);
Point linebest(dimension);
for(int d=0;d<dimension;d++){
Point direction(dimension);
Point best;
Point linebest;
for(int d=0;d<Point::getdim();d++){
Point direction;
direction[d]=1.0;
statscore curscore=LineOptimize(cur,direction,linebest);//find the minimum on the line
if(curscore>bestscore){

View File

@ -13,43 +13,42 @@ typedef float featurescore;
using namespace std;
/**virtual class*/
class Optimizer{
protected:
Scorer * scorer; //no accessor for them only child can use them
FeatureData * FData;//no accessor for them only child can use them
Point init;
public:
Scorer * scorer;
FeatureData * FData;
/**number of lambda parameters*/
const unsigned dimension;
Optimizer(unsigned d):dimension(d),scorer(NULL),FData(NULL){};
Optimizer(unsigned Pd,vector<unsigned> i2O,vector<lambda> start);
void SetScorer(Scorer *S);
void SetFData(FeatureData *F);
~Optimizer(){
delete scorer;
delete FData;
}
unsigned size(){return (FData?FData->size():0);}
virtual ~Optimizer();
unsigned size()const{return (FData?FData->size():0);}
/**Generic wrapper around TrueRun to check a few things. Non virtual*/
Point Run(const Point& init);
Point Run()const;
/**main function that perform an optimization*/
virtual Point TrueRun(const Point& init);
virtual Point TrueRun()const=0;
/**given a set of lambdas, get the nbest for each sentence*/
vector<unsigned> Get1bests(const Point& param);
void Get1bests(const Point& param,vector<unsigned>& bests)const;
/**given a set of nbests, get the Statistical score*/
statscore GetStatScore(vector<unsigned> nbests){scorer->score(nbests);};
statscore GetStatScore(const vector<unsigned>& nbests)const{scorer->score(nbests);};
/**given a set of lambdas, get the total statistical score*/
statscore GetStatScore(const Point& param){return GetStatScore(Get1bests(param));};
statscore LineOptimize(const Point& start,Point direction,Point& best);//Get the optimal Lambda and the best score in a particular direction from a given Point
statscore GetStatScore(const Point& param)const;
vector<statscore> GetIncStatScore(vector<unsigned> ref,vector<vector <pair<unsigned,unsigned> > >)const;
statscore LineOptimize(const Point& start,const Point& direction,Point& best)const;//Get the optimal Lambda and the best score in a particular direction from a given Point
};
using namespace std;
/**default basic optimizer*/
class SimpleOptimizer: public Optimizer{
private: float eps;
public:
SimpleOptimizer(unsigned dim,float _eps):Optimizer(dim),eps(_eps){};
virtual Point TrueRun(const Point& init);
SimpleOptimizer(unsigned dim,vector<unsigned> i2O,vector<lambda> start,float _eps):Optimizer(dim,i2O,start),eps(_eps){};
virtual Point TrueRun()const;
};
#endif

View File

@ -2,12 +2,23 @@
#include<cmath>
#include <cassert>
using namespace std;
void Point::randomize(const vector<lambda>& min,const vector<lambda>& max){
vector<unsigned> Point::optindices;
unsigned Point::dim=0;
map<unsigned,lambda> Point::fixedweights;
unsigned Point::pdim=0;
void Point::Randomize(const vector<lambda>& min,const vector<lambda>& max){
for (int i=0; i<size(); i++)
operator[](i)= min[i] + (float)random()/RAND_MAX * (max[i]-min[i]);
}
void Point::normalize(){
void Point::Normalize(){
lambda norm=0.0;
for (int i=0; i<size(); i++)
norm+= operator[](i)*operator[](i);
@ -18,12 +29,19 @@ void Point::normalize(){
}
}
double Point::operator*(FeatureStats& F)const{
double Point::operator*(const FeatureStats& F)const{
double prod=0.0;
for (int i=0; i<size(); i++)
prod+= operator[](i)*F.get(i);
if(OptimizeAll())
for (unsigned i=0; i<size(); i++)
prod+= operator[](i)*F.get(i);
else{
for (unsigned i=0; i<size(); i++)
prod+= operator[](i)*F.get(optindices[i]);
for(map<unsigned,float >::iterator it=fixedweights.begin();it!=fixedweights.end();it++)
prod+=it->second*F.get(it->first);
}
return prod;
}
Point Point::operator+(const Point& p2)const{
assert(p2.size()==size());
Point Res(*this);
@ -33,10 +51,28 @@ Point Point::operator+(const Point& p2)const{
return Res;
};
Point Point::operator*(float& l)const{
Point Point::operator*(float l)const{
Point Res(*this);
for(unsigned i=0;i<size();i++)
Res[i]*=l;
Res.score=numeric_limits<statscore>::max();
return Res;
};
vector<lambda> Point::GetAllWeights()const{
vector<lambda> w;
if(OptimizeAll()){
w=*this;
}else{
w.resize(pdim);
for (int i=0; i<size(); i++)
w[optindices[i]]=operator[](i);
for(map<unsigned,float >::iterator it=fixedweights.begin();it!=fixedweights.end();it++)
w[it->first]=it->second;
}
return w;
};

View File

@ -2,18 +2,40 @@
#define POINT_H
#include <vector>
#include "FeatureStats.h"
#include <cassert>
typedef float lambda,statscore;
class Point: public std::vector<lambda>{
class Optimizer;
/**class that handle the subset of the Feature weight on which we run the optimization*/
class Point:public vector<lambda>{
friend class Optimizer;
private:
/**The indices over which we optimize*/
static vector<unsigned> optindices;
/**dimension of optindices and of the parent vector*/
static unsigned dim;
/**fixed weights in case of partial optimzation*/
static map<unsigned,lambda> fixedweights;
/**total size of the parameter space; we have pdim=FixedWeight.size()+optinidices.size()*/
static unsigned pdim;
public:
static unsigned getdim(){return dim;}
static unsigned getpdim(){return pdim;}
static bool OptimizeAll(){return fixedweights.empty();};
statscore score;
Point(unsigned s):std::vector<lambda>(s,0.0){};
Point(vector<lambda> init):vector<lambda>(init),score(numeric_limits<statscore>::max()){};
void randomize(const std::vector<lambda>&min,const std::vector<lambda>& max);
double operator*(FeatureStats&)const;//compute the feature function
Point():vector<lambda>(dim){};
Point(vector<lambda> init):vector<lambda>(init){assert(init.size()==dim);};
void Randomize(const std::vector<lambda>&min,const std::vector<lambda>& max);
double operator*(const FeatureStats&)const;//compute the feature function
Point operator+(const Point&)const;
Point operator*(float&)const;//compute the feature function
void normalize();
Point operator*(float)const;
void Normalize();
/**return a vector of size pdim where all weights have been put*/
vector<lambda> GetAllWeights()const;
};
#endif