saving hof individuals

846 views
Skip to first unread message

William Smits

unread,
Aug 28, 2013, 6:44:53 PM8/28/13
to deap-...@googlegroups.com
Looking for simple method to save a hall of fame individual when the code completes.  Couldn't find method in library or example in forums to complete this task.  The hall of fame methods are not pickable.  I am sure there is some parent class or function in which to convert this to that would make this simple, not seeing it at the moment.  

I've tried a standard python pickle.  Also attempted using checkpoint method.  Get exact same pickle failure.  
## end of code
def main():
    random.seed(10)
    pop = toolbox.population(n=100)
    hof = tools.HallOfFame(10)
    stats = tools.Statistics(lambda ind: ind.fitness.values)
    stats.register("avg", tools.mean)
    stats.register("std", tools.std)
    stats.register("min", min)
    stats.register("max", max)
   
    algorithms.eaSimple(pop, toolbox, 0.5, 0.2, 50, stats, halloffame=hof)

    return pop, stats, hof

if __name__ == "__main__":
    pop, stats, hof = main()
    

    output = open('hof_10.pkl', 'wb')
    cPickle.dump(hof[0],output)
    output.close()


##Error
Traceback (most recent call last):
  File "C:\Users\user\folder\gp_ver3.pyw", line 158, in <module>
    cPickle.dump(hof[0],output)
  File "C:\Python27\lib\copy_reg.py", line 77, in _reduce_ex
    raise TypeError("a class that defines __slots__ without "
TypeError: a class that defines __slots__ without defining __getstate__ cannot be pickled


my attempt at checkpoint
if __name__ == "__main__":
    pop, stats, hof = main()
    cp = Checkpoint()
    cp.add("my_object", hof[0])
    cp.dump(open("example.ecp", "w"))

  File "C:\Python27\lib\copy_reg.py", line 77, in _reduce_ex
    raise TypeError("a class that defines __slots__ without "
TypeError: a class that defines __slots__ without defining __getstate__ cannot be pickled

EBo

unread,
Aug 28, 2013, 8:43:58 PM8/28/13
to deap-...@googlegroups.com
What I did (which was likely not the most elegant) was to write them
out to a file. Simple but effective. I can then read this back in as
needed. In my case, every trial evaluation can represent several hours
of CPU time. Each HOF can represent hundreds of hours...

EBo --

William Smits

unread,
Aug 28, 2013, 8:59:50 PM8/28/13
to deap-...@googlegroups.com
How so?  I realize in my above code i went to pickle an individual.  I know python can't pickle function or classes.  My one thought process was to stringify the hof individuals then pickle them, then unpickle for call back. could write to a file as well.    Not sure on an elegant method of taking the string and repopulating it back into the individual class though as of yet.  Do you have an example?

##like so
sa = deap.gp.stringify(hof[0])

EBo

unread,
Aug 29, 2013, 12:29:12 AM8/29/13
to deap-...@googlegroups.com
My code has not been cleared for release, so I cannot post it, but my
evaluate routine parsed the response and set a multi state evaluation.
When I did that it was to something that was picklable.

Hope that helps,

EBo --

Milon

unread,
Aug 29, 2013, 1:50:44 AM8/29/13
to deap-...@googlegroups.com
Hi,

In hof an individual is stored with its fitness. I guess you have to 
pick individual only.

Milon

Marc-André Gardner

unread,
Aug 29, 2013, 2:16:40 AM8/29/13
to deap-...@googlegroups.com
Hi William,

Try to replace :
cPickle.dump(hof[0],output)
by :
cPickle.dump(hof[0],output, -1)

And it should work. The reason is that the ancient ASCII pickling protocol do not supports classes with __slots__ defined (this is the case for the Primitive and Terminal classes, because it speeds up the code and reduce memory consumption). Switching to a more recent (and efficient) protocol solves the issue. So basically the problem does not come from the fitness or even the hall of fame object, but from the individual in itself.

Overall, it is not actually a DEAP bug. That said, I must admit that this behavior is definitely not user-friendly nor clear. It also affects the stable 0.9 and the upcoming 1.0 release. I will talk with the other DEAP developers to find a proper way to clarify this issue, maybe add a __getstate__ or __reduce__ functions to the classes with __slots__ defined.

In the meantime, do not hesitate if you have any other questions,

Marc-André Gardner
DEAP developper
Reply all
Reply to author
Forward
0 new messages