I want to use MaxEnt/GIS in an incremental way. I want to obtain a model using the first N data points; then when 10 more data points are available I want to update the model to include the new points.
Of course, the update should not require much computation, probably just a few iterations of GIS.
I've resigned myself to a bit of hacking in order to do this, but I figured I would ask here first to see if anyone else has done the same thing. Alternatively, it would be nice to hear recommendations on how to proceed.
thanks,
Dan
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi,
Sorry its taken a couple of days to get to this. So the convergence properties of a maxent model don't require a specific starting point. Said another way, you can start your model from any state and it will still converge. Probably the best way to do this is to add some code in GISTrainer to load an initial set of parameters from your previous model instead of the defaults You would change the params[pi].setParameter to use the models value.
for (int aoi=0;aoi<numActiveOutcomes;aoi++) {
int oi = outcomePattern[aoi];
params[pi].setParameter(aoi, 0.0);
modelExpects[pi].setParameter(aoi, 0.0);
if (predCount[pi][oi] > 0) {
observedExpects[pi].setParameter(aoi, predCount[pi][oi]);
}
else if (useSimpleSmoothing) {
observedExpects[pi].setParameter(aoi,smoothingObservation);
}
}
From that you can likely lower the number of iterations you use to converge to the new model which will cause the process to quicker. This makes sense as a general feature so I'll look at adding it in the future. Thanks...Tom
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
There, you posted how to speed up model learning by incorporate code into
GISTrainer to load an initial set of params from a previous model instead of defaults.
This code follows below:
for (int aoi=0;aoi<numActiveOutcomes;aoi++) {
int oi = outcomePattern[aoi];
params[pi].setParameter(aoi, 0.0);
modelExpects[pi].setParameter(aoi, 0.0);
if (predCount[pi][oi] > 0) {
observedExpects[pi].setParameter(aoi, predCount[pi][oi]);
}
else if (useSimpleSmoothing) {
observedExpects[pi].setParameter(aoi,smoothingObservation);
}
}
...from looking at the GISTrainer.java code in the release 2.4.0 source, I don't really
see much of a difference between the enhancement and the existing code. In fact,
the only thing that I see from the matching code is that 'oi', in the above, is declared
inside the for loop. You will see this in the below downloaded (v2.4) code matching
the above loop:
for (int aoi=0;aoi<numActiveOutcomes;aoi++) {
OID = outcomePattern[aoi];
params[PID].setParameter(aoi, 0.0);
modelExpects[PID].setParameter(aoi, 0.0);
if (predCount[PID][OID] > 0) {
observedExpects[PID].setParameter(aoi, predCount[PID][OID]);
}
else if (_simpleSmoothing) {
observedExpects[PID].setParameter(aoi,smoothingObservation);
}
}
}
....of course there is a difference in the variable names e.g. OID->oi, and PID ->pi;
however, this should not matter. So, my general question is: Could the code that
you have available in the version 2.4 already have the efficiency update? Note,
however, that the version 2.4 code update date is earlier than the posting of the
response to DanB
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Tom was just pointing out where you would change the code. So the values "0.0" in the setParameter calls would be substituted with the parameters from the previously trained model. (Whether or not it would perform better is a different question.)
Regardless of that, if you really need to have online training of the kind mentioned by DanB, I would say that maxent might not be the right algorithm for you. Use naive Bayes if it works for your task (and it often does), or use a (averaged) perceptron -- both can be straightforwardly extended with new data given a trained model.
If you were to use maxent in this incremental update way, I'd make sure to not to drop the old model and instead interpolate it with the new one(s).
Jason
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hey guys. Sorry in advance for having dug up this thread but I'm also kind of facing the same "problem" here. It's not absolutely mandatory but it would probably speed up my application a lot. I have quite a bunch (approx. 100k+) of precomputed events and outcomes (image statistics) stored in a database but I can only maxentevaluate the whole thing after having collected additonal data that cannot be stored or computed beforehand (comparing contours of a query image to those stored in the database).
It's working and it's working extremely well so thanks a million for providing such a great framework but it's taking an awful lot of time to fire up the whole GIS loop every time.
So, I'm kind of stuck in the GISTrainer.trainModel(…) method. You guys mentioned to overwrite the params.setParameter part, right? Say I pass an additional GISModel prevModel parameter to the trainModel method, then I can extract the necessary data via getDataStructures()… and then? *blush*
Could you guys give me a hint how to accomplish that incremental task? I've just started to comb through those passages of code in GISTrainer and I'm sure I'll get there someday but I thought it'd be wiser to ask the authors first - they know their own code better, do they? ;)
…or is there a way to do this in v3.0 now?
Thx!
Stephan
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi,
I want to use MaxEnt/GIS in an incremental way. I want to obtain a model using the first N data points; then when 10 more data points are available I want to update the model to include the new points.
Of course, the update should not require much computation, probably just a few iterations of GIS.
I've resigned myself to a bit of hacking in order to do this, but I figured I would ask here first to see if anyone else has done the same thing. Alternatively, it would be nice to hear recommendations on how to proceed.
thanks,
Dan
Hi,
Sorry its taken a couple of days to get to this. So the convergence properties of a maxent model don't require a specific starting point. Said another way, you can start your model from any state and it will still converge. Probably the best way to do this is to add some code in GISTrainer to load an initial set of parameters from your previous model instead of the defaults You would change the params[pi].setParameter to use the models value.
for (int aoi=0;aoi<numActiveOutcomes;aoi++) {
int oi = outcomePattern[aoi];
params[pi].setParameter(aoi, 0.0);
modelExpects[pi].setParameter(aoi, 0.0);
if (predCount[pi][oi] > 0) {
observedExpects[pi].setParameter(aoi, predCount[pi][oi]);
}
else if (useSimpleSmoothing) {
observedExpects[pi].setParameter(aoi,smoothingObservation);
}
}
From that you can likely lower the number of iterations you use to converge to the new model which will cause the process to quicker. This makes sense as a general feature so I'll look at adding it in the future. Thanks...Tom
I'm looking at your response to DanB's question on 'incremental MaxEnt' at: https://sourceforge.net/forum/forum.php?thread_id=1788108&forum_id=18385
There, you posted how to speed up model learning by incorporate code into
GISTrainer to load an initial set of params from a previous model instead of defaults.
This code follows below:
for (int aoi=0;aoi<numActiveOutcomes;aoi++) {
int oi = outcomePattern[aoi];
params[pi].setParameter(aoi, 0.0);
modelExpects[pi].setParameter(aoi, 0.0);
if (predCount[pi][oi] > 0) {
observedExpects[pi].setParameter(aoi, predCount[pi][oi]);
}
else if (useSimpleSmoothing) {
observedExpects[pi].setParameter(aoi,smoothingObservation);
}
}
...from looking at the GISTrainer.java code in the release 2.4.0 source, I don't really
see much of a difference between the enhancement and the existing code. In fact,
the only thing that I see from the matching code is that 'oi', in the above, is declared
inside the for loop. You will see this in the below downloaded (v2.4) code matching
the above loop:
for (int aoi=0;aoi<numActiveOutcomes;aoi++) {
OID = outcomePattern[aoi];
params[PID].setParameter(aoi, 0.0);
modelExpects[PID].setParameter(aoi, 0.0);
if (predCount[PID][OID] > 0) {
observedExpects[PID].setParameter(aoi, predCount[PID][OID]);
}
else if (_simpleSmoothing) {
observedExpects[PID].setParameter(aoi,smoothingObservation);
}
}
}
....of course there is a difference in the variable names e.g. OID->oi, and PID ->pi;
however, this should not matter. So, my general question is: Could the code that
you have available in the version 2.4 already have the efficiency update? Note,
however, that the version 2.4 code update date is earlier than the posting of the
response to DanB
Tom was just pointing out where you would change the code. So the values "0.0" in the setParameter calls would be substituted with the parameters from the previously trained model. (Whether or not it would perform better is a different question.)
Regardless of that, if you really need to have online training of the kind mentioned by DanB, I would say that maxent might not be the right algorithm for you. Use naive Bayes if it works for your task (and it often does), or use a (averaged) perceptron -- both can be straightforwardly extended with new data given a trained model.
If you were to use maxent in this incremental update way, I'd make sure to not to drop the old model and instead interpolate it with the new one(s).
Jason
Hey guys. Sorry in advance for having dug up this thread but I'm also kind of facing the same "problem" here. It's not absolutely mandatory but it would probably speed up my application a lot. I have quite a bunch (approx. 100k+) of precomputed events and outcomes (image statistics) stored in a database but I can only maxentevaluate the whole thing after having collected additonal data that cannot be stored or computed beforehand (comparing contours of a query image to those stored in the database).
It's working and it's working extremely well so thanks a million for providing such a great framework but it's taking an awful lot of time to fire up the whole GIS loop every time.
So, I'm kind of stuck in the GISTrainer.trainModel(…) method. You guys mentioned to overwrite the params.setParameter part, right? Say I pass an additional GISModel prevModel parameter to the trainModel method, then I can extract the necessary data via getDataStructures()… and then? *blush*
Could you guys give me a hint how to accomplish that incremental task? I've just started to comb through those passages of code in GISTrainer and I'm sure I'll get there someday but I thought it'd be wiser to ask the authors first - they know their own code better, do they? ;)
…or is there a way to do this in v3.0 now?
Thx!
Stephan