Closed fculinovic closed 6 years ago
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?)
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'
Got the same error
Solved with this commit: https://github.com/stared/livelossplot/commit/a9734f2488d10e568fbf12bc35e39396d782db9e
Let me know if it works.
Nothing changed((
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
I do. Error changed: now its:
Traceback (most recent call last):
File "C:/Users/ASUS/PycharmProjects/achimovka/train.py", line 108, in
Could you provide the parts of code regarding the compile
and fit
functions?
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)
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
@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.
@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.)
Looked at https://github.com/keras-team/keras/blob/master/keras/engine/training.py.
Now loss
can be a list or a dict, see: https://github.com/stared/livelossplot/commit/8abe5f4e63b1a6f5a101dcae0eaf0c29747a1322.
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 inTypeError: unsupported operand type(s) for +: 'function' and 'str'