📄 bfgs.h
字号:
//////////////////////////////////////////////////////////////////////////// Copyright (c) 2000, Yusuke Miyao/// You may distribute under the terms of the Artistic License.////// <id>$Id: BFGS.h,v 1.11 2003/05/16 10:00:08 yusuke Exp $</id>/// <collection>Maximum Entropy Estimator</collection>/// <name>BFGS.h</name>/// <overview>Maximum entropy model estimator by BFGS method</overview>/////////////////////////////////////////////////////////////////////////#ifndef Amis_BFGS_h_#define Amis_BFGS_h_#include <amis/configure.h>#include <amis/Estimator.h>#include <amis/BFGSSolver.h>#include <amis/EventSpaceInst.h>#include <amis/ModelExpect.h>#include <amis/FeatureFreqArray.h>#include <amis/EmpiricalExpect.h>AMIS_NAMESPACE_BEGIN///////////////////////////////////////////////////////////////////////// <classdef>/// <name>BFGSBase</name>/// <overview>Base class for ME estimator by limited-memory BFGS method</overview>/// <desc>/// A maximum entropy estimator based on the limited-memory BFGS method./// </desc>/// <body>template < class Model, class EventSpace, class ModelExpect = ModelExpect< FeatureFreqValue, Model, EventSpace >, class EmpiricalExpect = EmpiricalExpect< Model, EventSpace > >class BFGSBase : public Estimator {public: static const int DEFAULT_MEMORY_SIZE = 5;protected: Model* model; /// Maximum entropy model EventSpace* event_space; /// Event space, i.e., Set of events ModelExpect model_expectation; /// Model expectation of features EmpiricalExpect empirical_expectation; /// Empirical expectation of features int memory_size; /// Number of vectors to memorize BFGSSolver< BFGSBase< Model, EventSpace, ModelExpect, EmpiricalExpect > >* solver; /// Optimizer based on limited-memory BFGS int num_threads; /// Number of threads //////////////////////////////////////////////////////////////////////public: BFGSBase( int m = DEFAULT_MEMORY_SIZE ) : Estimator() { model = NULL; event_space = NULL; memory_size = m; solver = NULL; num_threads = 1; } /// Constructor BFGSBase( Model& init_model, EventSpace& init_event, int m = DEFAULT_MEMORY_SIZE ) : Estimator() { model = &init_model; event_space = &init_event; memory_size = m; solver = NULL; num_threads = 1; } /// Constructor virtual ~BFGSBase() { if ( solver != NULL ) delete solver; } /// Destructor //////////////////////////////////////////////////////////////////////public: void setModel( ModelBase& m ) { model = dynamic_cast< Model* >( &m ); } /// Set the model const Model& getModel() const { return *model; } /// Get the model void setEventSpace( EventSpaceBase& e ) { event_space = dynamic_cast< EventSpace* >( &e ); } /// Set the event space const EventSpace& getEventSpace() const { return *event_space; } /// Get the event space virtual int getNumThreads() { return num_threads; } /// Get the number of threads virtual void setNumThreads( int n ) { num_threads = n; } /// Set the number of threads virtual int getMemorySize() { return memory_size; } /// Get the size of memory virtual void setMemorySize( int m ) { memory_size = m; } /// Set the size of memory //////////////////////////////////////////////////////////////////////public: void initialize() { AMIS_DEBUG_MESSAGE( 3, "Set internal data...\n" ); model_expectation.initialize( *model, *event_space, num_threads ); //std::vector< Real > val_sums; //std::vector< Real > vval_sums; //std::vector< Real > emp_cnts; empirical_expectation.initialize( *model, *event_space ); empirical_expectation.setEmpiricalExpectation(); AMIS_DEBUG_MESSAGE( 3, "Make a BFGS solver...\n" ); if ( solver != NULL ) delete solver; //std::cerr << "machine_epsilon = " << machineEpsilon() << std::endl; solver = new BFGSSolver< BFGSBase< Model, EventSpace, ModelExpect, EmpiricalExpect > >( this, model->numFeatures(), memory_size, machineEpsilon() ); solver->initialize(); } /// Initialize model/empirical expectations, and BFGS solver void finalize() { if ( solver != NULL ) delete solver; solver = NULL; } /// Delete the BFGS solver bool isConverged() { return solver->isConverged(); } /// Check whether the model is converged void iteration() { //if ( isReportIteration() ) { // log_likelihood = -solver->functionValue() * event_space->sumEventCount(); //} solver->iteration(); } /// An iteration of estimation - invoked by class Estimator const EmpiricalExpect& getEmpiricalExpectation() { return empirical_expectation; } //////////////////////////////////////////////////////////////////////public: virtual Real computeFunctionDerivative( std::valarray< Real >& grad ) { Real ret = model_expectation.setModelExpectation( true ); // now model_expectation does "* event_empirical_expectation" setLogLikelihood( ret, event_space->sumEventCount() ); setObjectiveFunctionValue( ret ); for ( int i = 0; i < model->numFeatures(); ++i ) { //grad[ i ] = event_space->sumEventCount() * ( model_expectation[ i ] - empirical_expectation[ i ] ); grad[ i ] = model_expectation[ i ] - empirical_expectation[ i ]; } return -ret; } /// Compute the function value and the derivative - accessed by BFGSSolver void updateVector( const std::valarray< Real >& direction, Real a ) { initMinMaxUpdate(); AMIS_DEBUG_MESSAGE( 5, "\t\t------------------------------\n" ); for ( int i = 0; i < model->numFeatures(); ++i ) { if ( empirical_expectation[ i ] != 0.0 ) { Real lambda_update = a * direction[ i ]; setMinMaxUpdate( lambda_update ); model->addLambda( i, lambda_update ); AMIS_DEBUG_MESSAGE( 5, "\t\t" << i << " " << model->getLambda( i ) << std::endl ); } } AMIS_DEBUG_MESSAGE( 5, "\t\t------------------------------\n" ); } /// Update the vector - accessed by BFGSSolver};/// </body>/// </classdef>///////////////////////////////////////////////////////////////////////// <classdef>/// <name>BFGS</name>/// <overview>ME estimator by limited-memory BFGS method</overview>/// <desc>/// A maximum entropy estimator based on the limited-memory BFGS method./// </desc>/// <body>template < class Feature >class BFGS : public BFGSBase< ModelBase, EventSpaceInst< Feature > > {public: BFGS( int m = DEFAULT_MEMORY_SIZE ) : BFGSBase< ModelBase, EventSpaceInst< Feature > >( m ) {} /// Constructor BFGS( ModelBase& init_model, EventSpaceInst< Feature >& init_event, int m = DEFAULT_MEMORY_SIZE ) : BFGSBase< ModelBase, EventSpaceInst< Feature > >( init_model, init_event, m ) {} /// Constructor virtual ~BFGS() {} /// Destructor const std::string estimatorName() const { return "BFGS<" + Feature::featureTypeName() + ">"; } /// Get the name of this class};/// </body>/// </classdef>///////////////////////////////////////////////////////////////////////// <classdef>/// <name>BFGSJoint</name>/// <overview>ME estimator by limited-memory BFGS method</overview>/// <desc>/// A maximum entropy estimator based on the limited-memory BFGS method/// for joint probability models/// </desc>/// <body>template < class Feature >class BFGSJoint : public BFGSBase< ModelBase, EventSpaceInst< Feature >, ModelExpect< FeatureFreqValue, ModelBase, EventSpaceInst< Feature >, true >, EmpiricalExpect< ModelBase, EventSpaceInst< Feature >, true > > {public: BFGSJoint( int m = DEFAULT_MEMORY_SIZE ) : BFGSBase< ModelBase, EventSpaceInst< Feature >, ModelExpect< FeatureFreqValue, ModelBase, EventSpaceInst< Feature >, true >, EmpiricalExpect< ModelBase, EventSpaceInst< Feature >, true > >( m ) {} /// Constructor BFGSJoint( ModelBase& init_model, EventSpaceInst< Feature >& init_event, int m = DEFAULT_MEMORY_SIZE ) : BFGSBase< ModelBase, EventSpaceInst< Feature >, ModelExpect< FeatureFreqValue, ModelBase, EventSpaceInst< Feature >, true >, EmpiricalExpect< ModelBase, EventSpaceInst< Feature >, true > >( init_model, init_event, m ) {} /// Constructor virtual ~BFGSJoint() {} /// Destructor const std::string estimatorName() const { return "BFGSJoint<" + Feature::featureTypeName() + ">"; } /// Get the name of this class};/// </body>/// </classdef>AMIS_NAMESPACE_END#endif // BFGS_h_// end of BFGS.h
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -