mirror of
https://github.com/opencv/opencv.git
synced 2025-06-16 14:50:52 +08:00
ml: fix SimulatedAnnealingSolver interface
This commit is contained in:
parent
0a439570a0
commit
aef3019152
@ -1528,6 +1528,9 @@ public:
|
|||||||
/** @copybrief getAnnealItePerStep @see getAnnealItePerStep */
|
/** @copybrief getAnnealItePerStep @see getAnnealItePerStep */
|
||||||
CV_WRAP void setAnnealItePerStep(int val);
|
CV_WRAP void setAnnealItePerStep(int val);
|
||||||
|
|
||||||
|
/** @brief Set/initialize anneal RNG */
|
||||||
|
void setAnnealEnergyRNG(const RNG& rng);
|
||||||
|
|
||||||
/** possible activation functions */
|
/** possible activation functions */
|
||||||
enum ActivationFunctions {
|
enum ActivationFunctions {
|
||||||
/** Identity function: \f$f(x)=x\f$ */
|
/** Identity function: \f$f(x)=x\f$ */
|
||||||
@ -1875,86 +1878,104 @@ class CV_EXPORTS_W ANN_MLP_ANNEAL : public ANN_MLP
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/** @see setAnnealInitialT */
|
/** @see setAnnealInitialT */
|
||||||
CV_WRAP virtual double getAnnealInitialT() const;
|
CV_WRAP virtual double getAnnealInitialT() const = 0;
|
||||||
/** @copybrief getAnnealInitialT @see getAnnealInitialT */
|
/** @copybrief getAnnealInitialT @see getAnnealInitialT */
|
||||||
CV_WRAP virtual void setAnnealInitialT(double val);
|
CV_WRAP virtual void setAnnealInitialT(double val) = 0;
|
||||||
|
|
||||||
/** ANNEAL: Update final temperature.
|
/** ANNEAL: Update final temperature.
|
||||||
It must be \>=0 and less than initialT. Default value is 0.1.*/
|
It must be \>=0 and less than initialT. Default value is 0.1.*/
|
||||||
/** @see setAnnealFinalT */
|
/** @see setAnnealFinalT */
|
||||||
CV_WRAP virtual double getAnnealFinalT() const;
|
CV_WRAP virtual double getAnnealFinalT() const = 0;
|
||||||
/** @copybrief getAnnealFinalT @see getAnnealFinalT */
|
/** @copybrief getAnnealFinalT @see getAnnealFinalT */
|
||||||
CV_WRAP virtual void setAnnealFinalT(double val);
|
CV_WRAP virtual void setAnnealFinalT(double val) = 0;
|
||||||
|
|
||||||
/** ANNEAL: Update cooling ratio.
|
/** ANNEAL: Update cooling ratio.
|
||||||
It must be \>0 and less than 1. Default value is 0.95.*/
|
It must be \>0 and less than 1. Default value is 0.95.*/
|
||||||
/** @see setAnnealCoolingRatio */
|
/** @see setAnnealCoolingRatio */
|
||||||
CV_WRAP virtual double getAnnealCoolingRatio() const;
|
CV_WRAP virtual double getAnnealCoolingRatio() const = 0;
|
||||||
/** @copybrief getAnnealCoolingRatio @see getAnnealCoolingRatio */
|
/** @copybrief getAnnealCoolingRatio @see getAnnealCoolingRatio */
|
||||||
CV_WRAP virtual void setAnnealCoolingRatio(double val);
|
CV_WRAP virtual void setAnnealCoolingRatio(double val) = 0;
|
||||||
|
|
||||||
/** ANNEAL: Update iteration per step.
|
/** ANNEAL: Update iteration per step.
|
||||||
It must be \>0 . Default value is 10.*/
|
It must be \>0 . Default value is 10.*/
|
||||||
/** @see setAnnealItePerStep */
|
/** @see setAnnealItePerStep */
|
||||||
CV_WRAP virtual int getAnnealItePerStep() const;
|
CV_WRAP virtual int getAnnealItePerStep() const = 0;
|
||||||
/** @copybrief getAnnealItePerStep @see getAnnealItePerStep */
|
/** @copybrief getAnnealItePerStep @see getAnnealItePerStep */
|
||||||
CV_WRAP virtual void setAnnealItePerStep(int val);
|
CV_WRAP virtual void setAnnealItePerStep(int val) = 0;
|
||||||
|
|
||||||
|
|
||||||
/** @brief Creates empty model
|
|
||||||
|
|
||||||
Use StatModel::train to train the model, Algorithm::load\<ANN_MLP\>(filename) to load the pre-trained model.
|
|
||||||
Note that the train method has optional flags: ANN_MLP::TrainFlags.
|
|
||||||
*/
|
|
||||||
// CV_WRAP static Ptr<ANN_MLP> create();
|
|
||||||
|
|
||||||
|
/** @brief Set/initialize anneal RNG */
|
||||||
|
virtual void setAnnealEnergyRNG(const RNG& rng) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************************\
|
/****************************************************************************************\
|
||||||
* Simulated annealing solver *
|
* Simulated annealing solver *
|
||||||
\****************************************************************************************/
|
\****************************************************************************************/
|
||||||
|
|
||||||
|
/** @brief The class defines interface for system state used in simulated annealing optimization algorithm.
|
||||||
|
|
||||||
|
@cite Kirkpatrick83 for details
|
||||||
|
*/
|
||||||
|
class CV_EXPORTS SimulatedAnnealingSolverSystem
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
inline SimulatedAnnealingSolverSystem() {}
|
||||||
|
public:
|
||||||
|
virtual ~SimulatedAnnealingSolverSystem() {}
|
||||||
|
|
||||||
|
/** Give energy value for a state of system.*/
|
||||||
|
virtual double energy() const = 0;
|
||||||
|
/** Function which change the state of system (random pertubation).*/
|
||||||
|
virtual void changeState() = 0;
|
||||||
|
/** Function to reverse to the previous state. Can be called once only after changeState(). */
|
||||||
|
virtual void reverseState() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
/** @brief The class implements simulated annealing for optimization.
|
/** @brief The class implements simulated annealing for optimization.
|
||||||
|
*
|
||||||
@cite Kirkpatrick83 for details
|
@cite Kirkpatrick83 for details
|
||||||
*/
|
*/
|
||||||
class CV_EXPORTS SimulatedAnnealingSolver : public Algorithm
|
class CV_EXPORTS SimulatedAnnealingSolver : public Algorithm
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SimulatedAnnealingSolver() { init(); }
|
SimulatedAnnealingSolver(const Ptr<SimulatedAnnealingSolverSystem>& system);
|
||||||
~SimulatedAnnealingSolver();
|
inline ~SimulatedAnnealingSolver() { release(); }
|
||||||
/** Give energy value for a state of system.*/
|
|
||||||
virtual double energy() =0;
|
|
||||||
/** Function which change the state of system (random pertubation).*/
|
|
||||||
virtual void changedState() = 0;
|
|
||||||
/** Function to reverse to the previous state.*/
|
|
||||||
virtual void reverseChangedState() = 0;
|
|
||||||
/** Simulated annealing procedure. */
|
/** Simulated annealing procedure. */
|
||||||
int run();
|
int run();
|
||||||
/** Set intial temperature of simulated annealing procedure.
|
/** Set/initialize RNG (energy).
|
||||||
*@param x new initial temperature. x\>0
|
@param rng new RNG
|
||||||
|
*/
|
||||||
|
void setEnergyRNG(const RNG& rng);
|
||||||
|
/** Set initial temperature of simulated annealing procedure.
|
||||||
|
@param x new initial temperature. x\>0
|
||||||
*/
|
*/
|
||||||
void setInitialTemperature(double x);
|
void setInitialTemperature(double x);
|
||||||
/** Set final temperature of simulated annealing procedure.
|
/** Set final temperature of simulated annealing procedure.
|
||||||
*@param x new final temperature value. 0\<x\<initial temperature
|
@param x new final temperature value. 0\<x\<initial temperature
|
||||||
*/
|
*/
|
||||||
void setFinalTemperature(double x);
|
void setFinalTemperature(double x);
|
||||||
|
/** Get final temperature of simulated annealing procedure. */
|
||||||
double getFinalTemperature();
|
double getFinalTemperature();
|
||||||
/** Set setCoolingRatio of simulated annealing procedure : T(t) = coolingRatio * T(t-1).
|
/** Set setCoolingRatio of simulated annealing procedure : T(t) = coolingRatio * T(t-1).
|
||||||
* @param x new cooling ratio value. 0\<x\<1
|
@param x new cooling ratio value. 0\<x\<1
|
||||||
*/
|
*/
|
||||||
void setCoolingRatio(double x);
|
void setCoolingRatio(double x);
|
||||||
/** Set number iteration per temperature step.
|
/** Set number iteration per temperature step.
|
||||||
* @param ite number of iteration per temperature step ite \> 0
|
@param ite number of iteration per temperature step ite \> 0
|
||||||
*/
|
*/
|
||||||
void setIterPerStep(int ite);
|
void setIterPerStep(int ite);
|
||||||
|
|
||||||
protected:
|
void release();
|
||||||
void init();
|
SimulatedAnnealingSolver(const SimulatedAnnealingSolver&);
|
||||||
|
SimulatedAnnealingSolver& operator=(const SimulatedAnnealingSolver&);
|
||||||
|
|
||||||
private:
|
struct Impl; friend struct Impl;
|
||||||
struct Impl;
|
protected:
|
||||||
Impl* impl;
|
Impl* impl;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//! @} ml
|
//! @} ml
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -44,21 +44,37 @@ namespace cv { namespace ml {
|
|||||||
|
|
||||||
struct SimulatedAnnealingSolver::Impl
|
struct SimulatedAnnealingSolver::Impl
|
||||||
{
|
{
|
||||||
|
int refcount;
|
||||||
|
|
||||||
|
const Ptr<SimulatedAnnealingSolverSystem> systemPtr;
|
||||||
|
SimulatedAnnealingSolverSystem& system;
|
||||||
RNG rEnergy;
|
RNG rEnergy;
|
||||||
double coolingRatio;
|
double coolingRatio;
|
||||||
double initialT;
|
double initialT;
|
||||||
double finalT;
|
double finalT;
|
||||||
int iterPerStep;
|
int iterPerStep;
|
||||||
Impl()
|
|
||||||
|
Impl(const Ptr<SimulatedAnnealingSolverSystem>& s) :
|
||||||
|
refcount(1),
|
||||||
|
systemPtr(s),
|
||||||
|
system(*(s.get())),
|
||||||
|
rEnergy(12345)
|
||||||
{
|
{
|
||||||
|
CV_Assert(!systemPtr.empty());
|
||||||
initialT = 2;
|
initialT = 2;
|
||||||
finalT = 0.1;
|
finalT = 0.1;
|
||||||
coolingRatio = 0.95;
|
coolingRatio = 0.95;
|
||||||
iterPerStep = 100;
|
iterPerStep = 100;
|
||||||
refcount = 1;
|
|
||||||
}
|
}
|
||||||
int refcount;
|
|
||||||
~Impl() { refcount--;CV_Assert(refcount==0); }
|
inline double energy() { return system.energy(); }
|
||||||
|
inline void changeState() { system.changeState(); }
|
||||||
|
inline void reverseState() { system.reverseState(); }
|
||||||
|
|
||||||
|
void addref() { CV_XADD(&refcount, 1); }
|
||||||
|
void release() { if (CV_XADD(&refcount, -1) == 1) delete this; }
|
||||||
|
protected:
|
||||||
|
virtual ~Impl() { CV_Assert(refcount==0); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AnnParams
|
struct AnnParams
|
||||||
@ -71,7 +87,7 @@ struct AnnParams
|
|||||||
rpDW0 = 0.1; rpDWPlus = 1.2; rpDWMinus = 0.5;
|
rpDW0 = 0.1; rpDWPlus = 1.2; rpDWMinus = 0.5;
|
||||||
rpDWMin = FLT_EPSILON; rpDWMax = 50.;
|
rpDWMin = FLT_EPSILON; rpDWMax = 50.;
|
||||||
initialT=10;finalT=0.1,coolingRatio=0.95;itePerStep=10;
|
initialT=10;finalT=0.1,coolingRatio=0.95;itePerStep=10;
|
||||||
|
rEnergy = cv::RNG(12345);
|
||||||
}
|
}
|
||||||
|
|
||||||
TermCriteria termCrit;
|
TermCriteria termCrit;
|
||||||
@ -90,6 +106,7 @@ struct AnnParams
|
|||||||
double finalT;
|
double finalT;
|
||||||
double coolingRatio;
|
double coolingRatio;
|
||||||
int itePerStep;
|
int itePerStep;
|
||||||
|
RNG rEnergy;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -98,48 +115,60 @@ inline T inBounds(T val, T min_val, T max_val)
|
|||||||
return std::min(std::max(val, min_val), max_val);
|
return std::min(std::max(val, min_val), max_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
SimulatedAnnealingSolver::~SimulatedAnnealingSolver()
|
SimulatedAnnealingSolver::SimulatedAnnealingSolver(const Ptr<SimulatedAnnealingSolverSystem>& system)
|
||||||
{
|
{
|
||||||
if (impl) delete impl;
|
impl = new Impl(system);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimulatedAnnealingSolver::init()
|
SimulatedAnnealingSolver::SimulatedAnnealingSolver(const SimulatedAnnealingSolver& b)
|
||||||
{
|
{
|
||||||
impl = new SimulatedAnnealingSolver::Impl();
|
if (b.impl) b.impl->addref();
|
||||||
|
release();
|
||||||
|
impl = b.impl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SimulatedAnnealingSolver::release()
|
||||||
|
{
|
||||||
|
if (impl) { impl->release(); impl = NULL; }
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimulatedAnnealingSolver::setIterPerStep(int ite)
|
void SimulatedAnnealingSolver::setIterPerStep(int ite)
|
||||||
{
|
{
|
||||||
|
CV_Assert(impl);
|
||||||
CV_Assert(ite>0);
|
CV_Assert(ite>0);
|
||||||
impl->iterPerStep = ite;
|
impl->iterPerStep = ite;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SimulatedAnnealingSolver::run()
|
int SimulatedAnnealingSolver::run()
|
||||||
{
|
{
|
||||||
|
CV_Assert(impl);
|
||||||
CV_Assert(impl->initialT>impl->finalT);
|
CV_Assert(impl->initialT>impl->finalT);
|
||||||
double Ti = impl->initialT;
|
double Ti = impl->initialT;
|
||||||
double previousEnergy = energy();
|
double previousEnergy = impl->energy();
|
||||||
int exchange = 0;
|
int exchange = 0;
|
||||||
while (Ti > impl->finalT)
|
while (Ti > impl->finalT)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < impl->iterPerStep; i++)
|
for (int i = 0; i < impl->iterPerStep; i++)
|
||||||
{
|
{
|
||||||
changedState();
|
impl->changeState();
|
||||||
double newEnergy = energy();
|
double newEnergy = impl->energy();
|
||||||
if (newEnergy < previousEnergy)
|
if (newEnergy < previousEnergy)
|
||||||
{
|
{
|
||||||
previousEnergy = newEnergy;
|
previousEnergy = newEnergy;
|
||||||
|
//??? exchange++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
double r = impl->rEnergy.uniform(double(0.0), double(1.0));
|
double r = impl->rEnergy.uniform(0.0, 1.0);
|
||||||
if (r < exp(-(newEnergy - previousEnergy) / Ti))
|
if (r < std::exp(-(newEnergy - previousEnergy) / Ti))
|
||||||
{
|
{
|
||||||
previousEnergy = newEnergy;
|
previousEnergy = newEnergy;
|
||||||
exchange++;
|
exchange++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
reverseChangedState();
|
{
|
||||||
|
impl->reverseState();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -149,33 +178,43 @@ int SimulatedAnnealingSolver::run()
|
|||||||
return exchange;
|
return exchange;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SimulatedAnnealingSolver::setEnergyRNG(const RNG& rng)
|
||||||
|
{
|
||||||
|
CV_Assert(impl);
|
||||||
|
impl->rEnergy = rng;
|
||||||
|
}
|
||||||
|
|
||||||
void SimulatedAnnealingSolver::setInitialTemperature(double x)
|
void SimulatedAnnealingSolver::setInitialTemperature(double x)
|
||||||
{
|
{
|
||||||
|
CV_Assert(impl);
|
||||||
CV_Assert(x>0);
|
CV_Assert(x>0);
|
||||||
impl->initialT = x;
|
impl->initialT = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimulatedAnnealingSolver::setFinalTemperature(double x)
|
void SimulatedAnnealingSolver::setFinalTemperature(double x)
|
||||||
{
|
{
|
||||||
|
CV_Assert(impl);
|
||||||
CV_Assert(x>0);
|
CV_Assert(x>0);
|
||||||
impl->finalT = x;
|
impl->finalT = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
double SimulatedAnnealingSolver::getFinalTemperature()
|
double SimulatedAnnealingSolver::getFinalTemperature()
|
||||||
{
|
{
|
||||||
|
CV_Assert(impl);
|
||||||
return impl->finalT;
|
return impl->finalT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimulatedAnnealingSolver::setCoolingRatio(double x)
|
void SimulatedAnnealingSolver::setCoolingRatio(double x)
|
||||||
{
|
{
|
||||||
|
CV_Assert(impl);
|
||||||
CV_Assert(x>0 && x<1);
|
CV_Assert(x>0 && x<1);
|
||||||
impl->coolingRatio = x;
|
impl->coolingRatio = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
class SimulatedAnnealingANN_MLP : public ml::SimulatedAnnealingSolver
|
class SimulatedAnnealingANN_MLP : public SimulatedAnnealingSolverSystem
|
||||||
{
|
{
|
||||||
public:
|
protected:
|
||||||
ml::ANN_MLP *nn;
|
ml::ANN_MLP& nn;
|
||||||
Ptr<ml::TrainData> data;
|
Ptr<ml::TrainData> data;
|
||||||
int nbVariables;
|
int nbVariables;
|
||||||
vector<double*> adrVariables;
|
vector<double*> adrVariables;
|
||||||
@ -183,13 +222,14 @@ public:
|
|||||||
RNG rIndex;
|
RNG rIndex;
|
||||||
double varTmp;
|
double varTmp;
|
||||||
int index;
|
int index;
|
||||||
|
public:
|
||||||
SimulatedAnnealingANN_MLP(ml::ANN_MLP *x, Ptr<ml::TrainData> d) : nn(x), data(d)
|
SimulatedAnnealingANN_MLP(ml::ANN_MLP& x, const Ptr<ml::TrainData>& d) : nn(x), data(d)
|
||||||
{
|
{
|
||||||
initVarMap();
|
initVarMap();
|
||||||
}
|
}
|
||||||
|
~SimulatedAnnealingANN_MLP() {}
|
||||||
void changedState()
|
protected:
|
||||||
|
void changeState()
|
||||||
{
|
{
|
||||||
index = rIndex.uniform(0, nbVariables);
|
index = rIndex.uniform(0, nbVariables);
|
||||||
double dv = rVar.uniform(-1.0, 1.0);
|
double dv = rVar.uniform(-1.0, 1.0);
|
||||||
@ -197,22 +237,22 @@ public:
|
|||||||
*adrVariables[index] = dv;
|
*adrVariables[index] = dv;
|
||||||
}
|
}
|
||||||
|
|
||||||
void reverseChangedState()
|
void reverseState()
|
||||||
{
|
{
|
||||||
*adrVariables[index] = varTmp;
|
*adrVariables[index] = varTmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
double energy() { return nn->calcError(data, false, noArray()); }
|
double energy() const { return nn.calcError(data, false, noArray()); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void initVarMap()
|
void initVarMap()
|
||||||
{
|
{
|
||||||
Mat l = nn->getLayerSizes();
|
Mat l = nn.getLayerSizes();
|
||||||
nbVariables = 0;
|
nbVariables = 0;
|
||||||
adrVariables.clear();
|
adrVariables.clear();
|
||||||
for (int i = 1; i < l.rows-1; i++)
|
for (int i = 1; i < l.rows-1; i++)
|
||||||
{
|
{
|
||||||
Mat w = nn->getWeights(i);
|
Mat w = nn.getWeights(i);
|
||||||
for (int j = 0; j < w.rows; j++)
|
for (int j = 0; j < w.rows; j++)
|
||||||
{
|
{
|
||||||
for (int k = 0; k < w.cols; k++, nbVariables++)
|
for (int k = 0; k < w.cols; k++, nbVariables++)
|
||||||
@ -296,6 +336,13 @@ void ANN_MLP::setAnnealItePerStep(int val)
|
|||||||
this_->setAnnealItePerStep(val);
|
this_->setAnnealItePerStep(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ANN_MLP::setAnnealEnergyRNG(const RNG& rng)
|
||||||
|
{
|
||||||
|
ANN_MLP_ANNEAL* this_ = dynamic_cast<ANN_MLP_ANNEAL*>(this);
|
||||||
|
if (!this_)
|
||||||
|
CV_Error(Error::StsNotImplemented, "the class is not ANN_MLP_ANNEAL");
|
||||||
|
this_->setAnnealEnergyRNG(rng);
|
||||||
|
}
|
||||||
|
|
||||||
class ANN_MLPImpl : public ANN_MLP_ANNEAL
|
class ANN_MLPImpl : public ANN_MLP_ANNEAL
|
||||||
{
|
{
|
||||||
@ -323,6 +370,9 @@ public:
|
|||||||
CV_IMPL_PROPERTY(double, AnnealCoolingRatio, params.coolingRatio)
|
CV_IMPL_PROPERTY(double, AnnealCoolingRatio, params.coolingRatio)
|
||||||
CV_IMPL_PROPERTY(int, AnnealItePerStep, params.itePerStep)
|
CV_IMPL_PROPERTY(int, AnnealItePerStep, params.itePerStep)
|
||||||
|
|
||||||
|
//CV_IMPL_PROPERTY(RNG, AnnealEnergyRNG, params.rEnergy)
|
||||||
|
inline void setAnnealEnergyRNG(const RNG& val) { params.rEnergy = val; }
|
||||||
|
|
||||||
void clear()
|
void clear()
|
||||||
{
|
{
|
||||||
min_val = max_val = min_val1 = max_val1 = 0.;
|
min_val = max_val = min_val1 = max_val1 = 0.;
|
||||||
@ -1040,7 +1090,8 @@ public:
|
|||||||
}
|
}
|
||||||
int train_anneal(const Ptr<TrainData>& trainData)
|
int train_anneal(const Ptr<TrainData>& trainData)
|
||||||
{
|
{
|
||||||
SimulatedAnnealingANN_MLP t(this, trainData);
|
SimulatedAnnealingSolver t(Ptr<SimulatedAnnealingANN_MLP>(new SimulatedAnnealingANN_MLP(*this, trainData)));
|
||||||
|
t.setEnergyRNG(params.rEnergy);
|
||||||
t.setFinalTemperature(params.finalT);
|
t.setFinalTemperature(params.finalT);
|
||||||
t.setInitialTemperature(params.initialT);
|
t.setInitialTemperature(params.initialT);
|
||||||
t.setCoolingRatio(params.coolingRatio);
|
t.setCoolingRatio(params.coolingRatio);
|
||||||
@ -1687,70 +1738,6 @@ Ptr<ANN_MLP> ANN_MLP::load(const String& filepath)
|
|||||||
return ann;
|
return ann;
|
||||||
}
|
}
|
||||||
|
|
||||||
double ANN_MLP_ANNEAL::getAnnealInitialT() const
|
|
||||||
{
|
|
||||||
const ANN_MLPImpl* this_ = dynamic_cast<const ANN_MLPImpl*>(this);
|
|
||||||
if (!this_)
|
|
||||||
CV_Error(Error::StsNotImplemented, "the class is not ANN_MLP_ANNEAL");
|
|
||||||
return this_->getAnnealInitialT();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ANN_MLP_ANNEAL::setAnnealInitialT(double val)
|
|
||||||
{
|
|
||||||
ANN_MLPImpl* this_ = dynamic_cast< ANN_MLPImpl*>(this);
|
|
||||||
if (!this_)
|
|
||||||
CV_Error(Error::StsNotImplemented, "the class is not ANN_MLP_ANNEAL");
|
|
||||||
this_->setAnnealInitialT(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
double ANN_MLP_ANNEAL::getAnnealFinalT() const
|
|
||||||
{
|
|
||||||
const ANN_MLPImpl* this_ = dynamic_cast<const ANN_MLPImpl*>(this);
|
|
||||||
if (!this_)
|
|
||||||
CV_Error(Error::StsNotImplemented, "the class is not ANN_MLP_ANNEAL");
|
|
||||||
return this_->getAnnealFinalT();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ANN_MLP_ANNEAL::setAnnealFinalT(double val)
|
|
||||||
{
|
|
||||||
ANN_MLPImpl* this_ = dynamic_cast<ANN_MLPImpl*>(this);
|
|
||||||
if (!this_)
|
|
||||||
CV_Error(Error::StsNotImplemented, "the class is not ANN_MLP_ANNEAL");
|
|
||||||
this_->setAnnealFinalT(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
double ANN_MLP_ANNEAL::getAnnealCoolingRatio() const
|
|
||||||
{
|
|
||||||
const ANN_MLPImpl* this_ = dynamic_cast<const ANN_MLPImpl*>(this);
|
|
||||||
if (!this_)
|
|
||||||
CV_Error(Error::StsNotImplemented, "the class is not ANN_MLP_ANNEAL");
|
|
||||||
return this_->getAnnealCoolingRatio();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ANN_MLP_ANNEAL::setAnnealCoolingRatio(double val)
|
|
||||||
{
|
|
||||||
ANN_MLPImpl* this_ = dynamic_cast< ANN_MLPImpl*>(this);
|
|
||||||
if (!this_)
|
|
||||||
CV_Error(Error::StsNotImplemented, "the class is not ANN_MLP_ANNEAL");
|
|
||||||
this_->setAnnealInitialT(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
int ANN_MLP_ANNEAL::getAnnealItePerStep() const
|
|
||||||
{
|
|
||||||
const ANN_MLPImpl* this_ = dynamic_cast<const ANN_MLPImpl*>(this);
|
|
||||||
if (!this_)
|
|
||||||
CV_Error(Error::StsNotImplemented, "the class is not ANN_MLP_ANNEAL");
|
|
||||||
return this_->getAnnealItePerStep();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ANN_MLP_ANNEAL::setAnnealItePerStep(int val)
|
|
||||||
{
|
|
||||||
ANN_MLPImpl* this_ = dynamic_cast<ANN_MLPImpl*>(this);
|
|
||||||
if (!this_)
|
|
||||||
CV_Error(Error::StsNotImplemented, "the class is not ANN_MLP_ANNEAL");
|
|
||||||
this_->setAnnealInitialT(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
/* End of file. */
|
/* End of file. */
|
||||||
|
@ -41,6 +41,8 @@
|
|||||||
|
|
||||||
#include "test_precomp.hpp"
|
#include "test_precomp.hpp"
|
||||||
|
|
||||||
|
//#define GENERATE_TESTDATA
|
||||||
|
|
||||||
using namespace cv;
|
using namespace cv;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@ -248,7 +250,7 @@ TEST(ML_ANN, ActivationFunction)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//#define GENERATE_TESTDATA
|
|
||||||
TEST(ML_ANN, Method)
|
TEST(ML_ANN, Method)
|
||||||
{
|
{
|
||||||
String folder = string(cvtest::TS::ptr()->get_data_path());
|
String folder = string(cvtest::TS::ptr()->get_data_path());
|
||||||
@ -275,6 +277,7 @@ TEST(ML_ANN, Method)
|
|||||||
methodName.push_back("_anneal");
|
methodName.push_back("_anneal");
|
||||||
// methodName.push_back("_backprop"); -----> NO BACKPROP TEST
|
// methodName.push_back("_backprop"); -----> NO BACKPROP TEST
|
||||||
#ifdef GENERATE_TESTDATA
|
#ifdef GENERATE_TESTDATA
|
||||||
|
{
|
||||||
Ptr<ml::ANN_MLP> xx = ml::ANN_MLP_ANNEAL::create();
|
Ptr<ml::ANN_MLP> xx = ml::ANN_MLP_ANNEAL::create();
|
||||||
Mat_<int> layerSizesXX(1, 4);
|
Mat_<int> layerSizesXX(1, 4);
|
||||||
layerSizesXX(0, 0) = tdata->getNVars();
|
layerSizesXX(0, 0) = tdata->getNVars();
|
||||||
@ -290,6 +293,7 @@ TEST(ML_ANN, Method)
|
|||||||
fs.open(dataname + "_init_weight.yml.gz", FileStorage::WRITE + FileStorage::BASE64);
|
fs.open(dataname + "_init_weight.yml.gz", FileStorage::WRITE + FileStorage::BASE64);
|
||||||
xx->write(fs);
|
xx->write(fs);
|
||||||
fs.release();
|
fs.release();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
for (size_t i = 0; i < methodType.size(); i++)
|
for (size_t i = 0; i < methodType.size(); i++)
|
||||||
{
|
{
|
||||||
@ -300,6 +304,7 @@ TEST(ML_ANN, Method)
|
|||||||
x->setTrainMethod(methodType[i]);
|
x->setTrainMethod(methodType[i]);
|
||||||
if (methodType[i] == ml::ANN_MLP::ANNEAL)
|
if (methodType[i] == ml::ANN_MLP::ANNEAL)
|
||||||
{
|
{
|
||||||
|
x->setAnnealEnergyRNG(RNG(CV_BIG_INT(0xffffffff)));
|
||||||
x->setAnnealInitialT(12);
|
x->setAnnealInitialT(12);
|
||||||
x->setAnnealFinalT(0.15);
|
x->setAnnealFinalT(0.15);
|
||||||
x->setAnnealCoolingRatio(0.96);
|
x->setAnnealCoolingRatio(0.96);
|
||||||
|
@ -1,59 +1,53 @@
|
|||||||
#include <opencv2/opencv.hpp>
|
#include <opencv2/opencv.hpp>
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace cv;
|
using namespace cv;
|
||||||
|
|
||||||
void DrawTravelMap(Mat &img, vector<Point> &p, vector<int> &n);
|
class TravelSalesman : public ml::SimulatedAnnealingSolverSystem
|
||||||
|
|
||||||
class TravelSalesman : public ml::SimulatedAnnealingSolver
|
|
||||||
{
|
{
|
||||||
private :
|
private :
|
||||||
vector<Point> &posCity;
|
const std::vector<Point>& posCity;
|
||||||
vector<int> &next;
|
std::vector<int>& next;
|
||||||
RNG rng;
|
RNG rng;
|
||||||
int d0,d1,d2,d3;
|
int d0,d1,d2,d3;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
TravelSalesman(std::vector<Point> &p, std::vector<int> &n) :
|
||||||
TravelSalesman(vector<Point> &p,vector<int> &n):posCity(p),next(n)
|
posCity(p), next(n)
|
||||||
{
|
{
|
||||||
rng = theRNG();
|
rng = theRNG();
|
||||||
};
|
}
|
||||||
/** Give energy value for a state of system.*/
|
/** Give energy value for a state of system.*/
|
||||||
virtual double energy();
|
/*virtual*/ double energy() const;
|
||||||
/** Function which change the state of system (random pertubation).*/
|
/** Function which change the state of system (random pertubation).*/
|
||||||
virtual void changedState();
|
/*virtual*/ void changeState();
|
||||||
/** Function to reverse to the previous state.*/
|
/** Function to reverse to the previous state.*/
|
||||||
virtual void reverseChangedState();
|
/*virtual*/ void reverseState();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void TravelSalesman::changedState()
|
void TravelSalesman::changeState()
|
||||||
{
|
{
|
||||||
d0 = rng.uniform(0,static_cast<int>(posCity.size()));
|
d0 = rng.uniform(0,static_cast<int>(posCity.size()));
|
||||||
d1 = next[d0];
|
d1 = next[d0];
|
||||||
d2 = next[d1];
|
d2 = next[d1];
|
||||||
d3 = next[d2];
|
d3 = next[d2];
|
||||||
int d0Tmp = d0;
|
|
||||||
int d1Tmp = d1;
|
|
||||||
int d2Tmp = d2;
|
|
||||||
|
|
||||||
next[d0Tmp] = d2;
|
next[d0] = d2;
|
||||||
next[d2Tmp] = d1;
|
next[d2] = d1;
|
||||||
next[d1Tmp] = d3;
|
next[d1] = d3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void TravelSalesman::reverseChangedState()
|
void TravelSalesman::reverseState()
|
||||||
{
|
{
|
||||||
next[d0] = d1;
|
next[d0] = d1;
|
||||||
next[d1] = d2;
|
next[d1] = d2;
|
||||||
next[d2] = d3;
|
next[d2] = d3;
|
||||||
}
|
}
|
||||||
|
|
||||||
double TravelSalesman::energy()
|
double TravelSalesman::energy() const
|
||||||
{
|
{
|
||||||
double e=0;
|
double e = 0;
|
||||||
for (size_t i = 0; i < next.size(); i++)
|
for (size_t i = 0; i < next.size(); i++)
|
||||||
{
|
{
|
||||||
e += norm(posCity[i]-posCity[next[i]]);
|
e += norm(posCity[i]-posCity[next[i]]);
|
||||||
@ -62,7 +56,7 @@ double TravelSalesman::energy()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DrawTravelMap(Mat &img, vector<Point> &p, vector<int> &n)
|
static void DrawTravelMap(Mat &img, std::vector<Point> &p, std::vector<int> &n)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < n.size(); i++)
|
for (size_t i = 0; i < n.size(); i++)
|
||||||
{
|
{
|
||||||
@ -74,12 +68,12 @@ int main(void)
|
|||||||
{
|
{
|
||||||
int nbCity=40;
|
int nbCity=40;
|
||||||
Mat img(500,500,CV_8UC3,Scalar::all(0));
|
Mat img(500,500,CV_8UC3,Scalar::all(0));
|
||||||
RNG &rng=theRNG();
|
RNG rng(123456);
|
||||||
int radius=static_cast<int>(img.cols*0.45);
|
int radius=static_cast<int>(img.cols*0.45);
|
||||||
Point center(img.cols/2,img.rows/2);
|
Point center(img.cols/2,img.rows/2);
|
||||||
|
|
||||||
vector<Point> posCity(nbCity);
|
std::vector<Point> posCity(nbCity);
|
||||||
vector<int> next(nbCity);
|
std::vector<int> next(nbCity);
|
||||||
for (size_t i = 0; i < posCity.size(); i++)
|
for (size_t i = 0; i < posCity.size(); i++)
|
||||||
{
|
{
|
||||||
double theta = rng.uniform(0., 2 * CV_PI);
|
double theta = rng.uniform(0., 2 * CV_PI);
|
||||||
@ -87,25 +81,33 @@ int main(void)
|
|||||||
posCity[i].y = static_cast<int>(radius*sin(theta)) + center.y;
|
posCity[i].y = static_cast<int>(radius*sin(theta)) + center.y;
|
||||||
next[i]=(i+1)%nbCity;
|
next[i]=(i+1)%nbCity;
|
||||||
}
|
}
|
||||||
TravelSalesman ts(posCity,next);
|
Ptr<TravelSalesman> ts_system(new TravelSalesman(posCity, next));
|
||||||
|
ml::SimulatedAnnealingSolver ts(ts_system);
|
||||||
|
|
||||||
|
ts.setIterPerStep(10000*nbCity);
|
||||||
ts.setCoolingRatio(0.99);
|
ts.setCoolingRatio(0.99);
|
||||||
ts.setInitialTemperature(100);
|
ts.setInitialTemperature(100);
|
||||||
ts.setIterPerStep(10000*nbCity);
|
|
||||||
ts.setFinalTemperature(100*0.97);
|
ts.setFinalTemperature(100*0.97);
|
||||||
DrawTravelMap(img,posCity,next);
|
DrawTravelMap(img,posCity,next);
|
||||||
imshow("Map",img);
|
imshow("Map",img);
|
||||||
waitKey(10);
|
waitKey(10);
|
||||||
for (int i = 0; i < 100; i++)
|
for (int i = 0, zeroChanges = 0; zeroChanges < 10; i++)
|
||||||
{
|
{
|
||||||
ts.run();
|
int changesApplied = ts.run();
|
||||||
img = Mat::zeros(img.size(),CV_8UC3);
|
img = Mat::zeros(img.size(),CV_8UC3);
|
||||||
DrawTravelMap(img, posCity, next);
|
DrawTravelMap(img, posCity, next);
|
||||||
imshow("Map", img);
|
imshow("Map", img);
|
||||||
waitKey(10);
|
int k = waitKey(10);
|
||||||
double ti=ts.getFinalTemperature();
|
double ti=ts.getFinalTemperature();
|
||||||
cout<<ti <<" -> "<<ts.energy()<<"\n";
|
std::cout << "i=" << i << " changesApplied=" << changesApplied << " temp=" << ti << " result=" << ts_system->energy() << std::endl;
|
||||||
|
if (k == 27 || k == 'q' || k == 'Q')
|
||||||
|
return 0;
|
||||||
|
if (changesApplied == 0)
|
||||||
|
zeroChanges++;
|
||||||
ts.setInitialTemperature(ti);
|
ts.setInitialTemperature(ti);
|
||||||
ts.setFinalTemperature(ti*0.97);
|
ts.setFinalTemperature(ti*0.97);
|
||||||
}
|
}
|
||||||
|
std::cout << "Done" << std::endl;
|
||||||
|
waitKey(0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user