maxpumperla / hyperas

Keras + Hyperopt: A very simple wrapper for convenient hyperparameter optimization
http://maxpumperla.com/hyperas/
MIT License
2.17k stars 316 forks source link

Error `minimize` is not reading keras custom callback #229

Open virtualdvid opened 5 years ago

virtualdvid commented 5 years ago

Hi,

I tried to pass a callback in a hyperas minimize iteration without success. Here the error I got:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-22-7e1cf0605bf7> in <module>()
      5                                       max_evals=50,
      6                                       trials=Trials(),
----> 7                                       notebook_name='my_notebook')

8 frames
/usr/lib/python3.6/inspect.py in getfile(object)
    652             if hasattr(object, '__file__'):
    653                 return object.__file__
--> 654         raise TypeError('{!r} is a built-in class'.format(object))
    655     if ismethod(object):
    656         object = object.__func__

TypeError: <module '__main__'> is a built-in class

Is interesting because base on this error I got before minimize admit classes:

TypeError: 'my_test' is not a module, class, method, function, traceback, frame, or code object

What I did was: wrote the callback: (copy and paste from keras docs)

class LossHistory(keras.callbacks.Callback):
    def on_train_begin(self, logs={}):
        self.losses = []

    def on_batch_end(self, batch, logs={}):
        self.losses.append(logs.get('loss')) 

Then pass it through minimize as a funtion:

best_run, best_model = optim.minimize(model=model_op,
                                      data=data,
                                      functions=[LossHistory], # << callback
                                      algo=tpe.suggest,
                                      max_evals=5,
                                      trials=Trials(),
                                      notebook_name='my_notebook')

I got it to work when I put the class inside the function model_op. But I don't know, I can't avoid the feeling that it should pass as a parameter in the list of functions. Let me know if there is a better way to do this. Thanks!!

Regards David Molina