Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PlotLossesKeras not working due to TypeError #3

Closed
fculinovic opened this issue Mar 20, 2018 · 13 comments
Closed

PlotLossesKeras not working due to TypeError #3

fculinovic opened this issue Mar 20, 2018 · 13 comments

Comments

@fculinovic
Copy link

For Keras version 2.1.3 the PlotLossesKeras crashes due to error in line 33 of keras_plot.py

Reason for this is:
self.metric2printable['loss'] = self.metric2printable.get(self.model.loss, self.model.loss) + " (cost function)"
where this breaks due to self.model.loss being a keras function. This results in

TypeError: unsupported operand type(s) for +: 'function' and 'str'

@stared
Copy link
Owner

stared commented Mar 20, 2018

With Keras 2.0.5 it works well.

In any case - how did you specify the loss function? (Could you provide code, at least model.compile and model.fit lines?)

@fculinovic
Copy link
Author

Model is compiled with

model.compile(loss=keras.losses.binary_crossentropy,
              optimizer=keras.optimizers.Adam(lr=1e-3, amsgrad=True),
             metrics=['accuracy'])

Fitting is done according to your example:

model.fit(data[m_train], labels[m_train],
    epochs=10, verbose=True,
    validation_data=(data[m_val], labels[m_val]),
    callbacks=[checkpointer, PlotLossesKeras()]
)

where your example does

from livelossplot import PlotLossesKeras

model.fit(X_train, Y_train,
          epochs=10,
          validation_data=(X_test, Y_test),
          callbacks=[PlotLossesKeras()],
          verbose=0)

Printing out model.loss shows that the return value of that call is the function itself
<function binary_crossentropy at 0x7fa918886598>

The stacktrace is:

TypeError                                 Traceback (most recent call last)
<ipython-input-99-baaad69844e3> in <module>()
      2     epochs=10, verbose=True,
      3     validation_data=(data[m_val], labels[m_val]),
----> 4     callbacks=[PlotLossesKeras()]
      5 )

~/.local/lib/python3.5/site-packages/keras/engine/training.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, **kwargs)
   1667                               initial_epoch=initial_epoch,
   1668                               steps_per_epoch=steps_per_epoch,
-> 1669                               validation_steps=validation_steps)
   1670 
   1671     def evaluate(self, x=None, y=None,

~/.local/lib/python3.5/site-packages/keras/engine/training.py in _fit_loop(self, f, ins, out_labels, batch_size, epochs, verbose, callbacks, val_f, val_ins, shuffle, callback_metrics, initial_epoch, steps_per_epoch, validation_steps)
   1136             'metrics': callback_metrics or [],
   1137         })
-> 1138         callbacks.on_train_begin()
   1139         callback_model.stop_training = False
   1140         for cbk in callbacks:

~/.local/lib/python3.5/site-packages/keras/callbacks.py in on_train_begin(self, logs)
    127         logs = logs or {}
    128         for callback in self.callbacks:
--> 129             callback.on_train_begin(logs)
    130 
    131     def on_train_end(self, logs=None):

~/.local/lib/python3.5/site-packages/livelossplot/keras_plot.py in on_train_begin(self, logs)
     31                 ((len(self.base_metrics) + 1) // self.max_cols + 1) * self.cell_size[1]
     32             )
---> 33         self.metric2printable['loss'] = self.metric2printable.get(self.model.loss, self.model.loss) + " (cost function)"
     34         self.max_epoch = self.params['epochs'] if not self.dynamic_x_axis else None
     35 

TypeError: unsupported operand type(s) for +: 'function' and 'str'

@utausheva
Copy link

Got the same error

@stared
Copy link
Owner

stared commented Mar 20, 2018

Solved with this commit: a9734f2

Let me know if it works.

@stared stared closed this as completed Mar 20, 2018
@utausheva
Copy link

Nothing changed((

@fculinovic
Copy link
Author

fculinovic commented Mar 20, 2018

This fixed the issue at my end. You sure you have used pip3 install git+git://github.com/stared/livelossplot.git@a9734f2488d10e568fbf12bc35e39396d782db9e --user ?

Here's the ending of this command

Installing collected packages: livelossplot
  Found existing installation: livelossplot 0.1.1
    Uninstalling livelossplot-0.1.1:
      Successfully uninstalled livelossplot-0.1.1
  Running setup.py install for livelossplot ... done
Successfully installed livelossplot-0.1.2

@utausheva
Copy link

utausheva commented Mar 20, 2018

I do. Error changed: now its:
Traceback (most recent call last):
File "C:/Users/ASUS/PycharmProjects/achimovka/train.py", line 108, in
shuffle=True)
File "C:\Users\ASUS\AppData\Local\Programs\Python\Python36\lib\site-packages\keras\models.py", line 963, in fit
validation_steps=validation_steps)
File "C:\Users\ASUS\AppData\Local\Programs\Python\Python36\lib\site-packages\keras\engine\training.py", line 1705, in fit
validation_steps=validation_steps)
File "C:\Users\ASUS\AppData\Local\Programs\Python\Python36\lib\site-packages\keras\engine\training.py", line 1163, in _fit_loop
callbacks.on_train_begin()
File "C:\Users\ASUS\AppData\Local\Programs\Python\Python36\lib\site-packages\keras\callbacks.py", line 130, in on_train_begin
callback.on_train_begin(logs)
File "C:\Users\ASUS\AppData\Local\Programs\Python\Python36\lib\site-packages\livelossplot\keras_plot.py", line 42, in on_train_begin
self.metric2printable['loss'] = self.metric2printable.get(loss_name, loss_name) + " (cost function)"
TypeError: unhashable type: 'list'

@fculinovic
Copy link
Author

Could you provide the parts of code regarding the compile and fit functions?

@utausheva
Copy link

model.compile(optimizer=opt, loss=['mae'], metrics=['mae'])
plot_losses = livelossplot.PlotLossesKeras()

history = model.fit(X_train, Y_train,
nb_epoch=10,
batch_size=2,
verbose=0,
validation_data=(X_test, Y_test),
callbacks=[reduce_lr,checkpointer,plot_losses],
shuffle=True)

@fculinovic
Copy link
Author

fculinovic commented Mar 20, 2018

Ok, so it seems that this is the case:

if the loss is defined as
model.compile(..., loss= 'mae', ...)
or
model.compile(..., loss=keras.losses.mean_absolute_error)
it should work.

This is a solution if you have only 1 loss function. As for more loss functions, it seems that
self.metric2printable['loss'] = self.metric2printable.get(loss_name, loss_name) + " (cost function)"

and the accompanying function

def loss2name(loss):
    if hasattr(loss, '__call__'):
        # if passed as a function
        return loss.__name__
    else:
        # if passed as a string
        return loss

aren't written to accomodate multiple losses

@stared
Copy link
Owner

stared commented Mar 20, 2018

@utausheva Write
model.compile(optimizer=opt, loss='mae', metrics=['mae']) and it will be all right (and actually in your case metrics is not needed as we keep tract of 'mae' anyway).

For typical networks there is only one loss function, see https://keras.io/models/model/#compile.
I need to dive into model.compile to make sure I pre-process data in the same way.

@stared stared reopened this Mar 20, 2018
@stared
Copy link
Owner

stared commented Mar 20, 2018

@utausheva Please open a separate issue with PyCharm. Make sure to provide complete examples and versions. (In this thread I am deleting off-topic comments.)

@stared stared closed this as completed Mar 20, 2018
Repository owner deleted a comment from utausheva Mar 20, 2018
Repository owner deleted a comment from utausheva Mar 20, 2018
Repository owner deleted a comment from fculinovic Mar 20, 2018
Repository owner deleted a comment from utausheva Mar 20, 2018
Repository owner deleted a comment from utausheva Mar 20, 2018
@stared
Copy link
Owner

stared commented Mar 20, 2018

Looked at https://github.com/keras-team/keras/blob/master/keras/engine/training.py.

Now loss can be a list or a dict, see: 8abe5f4.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants