Search code examples
pythonkerasiterable-unpacking

list of keras callbacks generates error: 'tuple' object has no attribute 'set_model'


I am writing a keras model where I want to use a few built-in keras callbacks, however I am probably making a grammar mistake somewhere that I cannot spot. The piece of code giving me troubles is the following:

from keras.callbacks import EarlyStopping, ModelCheckpoint, TensorBoard
...
...
es = EarlyStopping(monitor='val_loss', min_delta=0.01, verbose=1, patience=5)
tb = TensorBoard(log_dir=logdir, write_graph=True, write_images=True, histogram_freq=0)
mc = ModelCheckpoint(filepath=filepath, save_best_only=True, monitor='val_loss', mode='min')

history = model.fit(X_train, y_train,
                    batch_size=batch_size,
                    epochs=n_epochs,
                    verbose=1,
                    validation_split=0.3,
                    callbacks=[es, tb, mc])

however in doing so I get the error 'tuple' object has no attribute 'set_model'. Referring to this other question it seems that the problem is generated by the fact that es, tb are already tuples per sé and therefore positioning them into a list (in the call callbacks=[es, tb, mc]) raises the error. In fact

print(type(es))
print(type(tb))
print(type(mc))

<class 'tuple'>
<class 'tuple'>
<class 'keras.callbacks.ModelCheckpoint'>

This said, I do not understand how to work around it. EarlyStopping and TensorBoard return tuples, how are they supposed to be called in the keras callbacks list?


Solution

  • Unpack your tuples - in this case, it's simple: (object,)[0] == object - but in general, you may have (object1, object2), etc, which you can handle via callbacks=[*es, *tb, *mc].

    The * unpacks iterables - as a demo:

    def print_unpacked(*positional_args):
        print(positional_args)
        print(*positional_args)
    a = 1
    b = ('dog',5)
    
    print_unpacked(a,b)
    # >> (1, ('dog',5))
    # >> 1 ('dog',5)
    print(a,b)
    # >> 1 ('dog',5)
    print(a,*b)
    # >> 1 'dog' 5