Skip to content

Instantly share code, notes, and snippets.

@stared
Last active July 17, 2025 17:36
Show Gist options
  • Select an option

  • Save stared/dfb4dfaf6d9a8501cd1cc8b8cb806d2e to your computer and use it in GitHub Desktop.

Select an option

Save stared/dfb4dfaf6d9a8501cd1cc8b8cb806d2e to your computer and use it in GitHub Desktop.
Live loss plot for training models in Keras (see: https://github.com/stared/livelossplot/ for a library)
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Live loss plots in Jupyter Notebook for Keras\n",
"\n",
"by [Piotr Migdał](http://p.migdal.pl/)\n",
"\n",
"* inspired by a Reddit discussion [Live loss plots inside Jupyter Notebook for Keras? - r/MachineLearning](https://www.reddit.com/r/MachineLearning/comments/65jelb/d_live_loss_plots_inside_jupyter_notebook_for/)\n",
"* my other Keras add-on: [Sequential model in Keras -> parameter ASCII diagram](https://github.com/stared/keras-sequential-ascii)"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Using TensorFlow backend.\n"
]
}
],
"source": [
"%matplotlib inline\n",
"\n",
"import keras\n",
"from keras.datasets import mnist\n",
"from keras.utils import to_categorical\n",
"from keras.models import Sequential\n",
"from keras.layers import Flatten, Dense, Activation\n",
"\n",
"import numpy as np\n",
"from matplotlib import pyplot as plt\n",
"from IPython.display import clear_output"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"'2.0.3'"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"keras.__version__"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# data loading\n",
"(X_train, y_train), (X_test, y_test) = mnist.load_data()"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# data preprocessing\n",
"Y_train = to_categorical(y_train)\n",
"Y_test = to_categorical(y_test)\n",
"X_train = X_train.reshape(-1, 28, 28, 1).astype('float32') / 255.\n",
"X_test = X_test.reshape(-1, 28, 28, 1).astype('float32') / 255."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"# updatable plot\n",
"# a minimal example (sort of)\n",
"\n",
"class PlotLosses(keras.callbacks.Callback):\n",
" def on_train_begin(self, logs={}):\n",
" self.i = 0\n",
" self.x = []\n",
" self.losses = []\n",
" self.val_losses = []\n",
" \n",
" self.fig = plt.figure()\n",
" \n",
" self.logs = []\n",
"\n",
" def on_epoch_end(self, epoch, logs={}):\n",
" \n",
" self.logs.append(logs)\n",
" self.x.append(self.i)\n",
" self.losses.append(logs.get('loss'))\n",
" self.val_losses.append(logs.get('val_loss'))\n",
" self.i += 1\n",
" \n",
" clear_output(wait=True)\n",
" plt.plot(self.x, self.losses, label=\"loss\")\n",
" plt.plot(self.x, self.val_losses, label=\"val_loss\")\n",
" plt.legend()\n",
" plt.show();\n",
" \n",
"plot_losses = PlotLosses()"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# just logistic regression, to keep it simple and fast\n",
"\n",
"model = Sequential()\n",
"\n",
"model.add(Flatten(input_shape=(28, 28, 1)))\n",
"model.add(Dense(10))\n",
"model.add(Activation('softmax'))\n",
"\n",
"model.compile(optimizer='rmsprop',\n",
" loss='categorical_crossentropy',\n",
" metrics=['accuracy'])"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": false,
"scrolled": false
},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x126f27320>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"<keras.callbacks.History at 0x10986c710>"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# in this static viewer it is not obvious,\n",
"# but this plot grows step by step\n",
"\n",
"model.fit(X_train, Y_train,\n",
" epochs=10,\n",
" validation_data=(X_test, Y_test),\n",
" callbacks=[plot_losses],\n",
" verbose=0)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Further ideas\n",
"\n",
"* loss and accuracy side by side, as two plots\n",
"* time per epoch (plot title?)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"anaconda-cloud": {},
"kernelspec": {
"display_name": "Python [default]",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.5.2"
}
},
"nbformat": 4,
"nbformat_minor": 1
}
@kav
Copy link
Copy Markdown

kav commented Dec 11, 2017

Here's a version with loss and accuracy:

class PlotLearning(Callback):
    def on_train_begin(self, logs={}):
        self.i = 0
        self.x = []
        self.losses = []
        self.val_losses = []
        self.acc = []
        self.val_acc = []
        self.fig = plt.figure()
        
        self.logs = []

    def on_epoch_end(self, epoch, logs={}):
        
        self.logs.append(logs)
        self.x.append(self.i)
        self.losses.append(logs.get('loss'))
        self.val_losses.append(logs.get('val_loss'))
        self.acc.append(logs.get('acc'))
        self.val_acc.append(logs.get('val_acc'))
        self.i += 1
        f, (ax1, ax2) = plt.subplots(1, 2, sharex=True)
        
        clear_output(wait=True)
        
        ax1.set_yscale('log')
        ax1.plot(self.x, self.losses, label="loss")
        ax1.plot(self.x, self.val_losses, label="val_loss")
        ax1.legend()
        
        ax2.plot(self.x, self.acc, label="accuracy")
        ax2.plot(self.x, self.val_acc, label="validation accuracy")
        ax2.legend()
        
        plt.show();
        
plot = PlotLearning()

I also switched loss to a log plot since it tends to resolve that way

@maxberggren
Copy link
Copy Markdown

Works great, thanks!

@baristahell
Copy link
Copy Markdown

Thanks for this, it's really nice!

Do you have a way to change the figure size? I'd like it to be larger but something like figsize=(20,10) doesn't work.

@stared
Copy link
Copy Markdown
Author

stared commented Mar 9, 2018

@stared
Copy link
Copy Markdown
Author

stared commented Mar 18, 2018

UPDATE: I created a dedicated library: https://github.com/stared/livelossplot/ - contributions are welcomed! :)

You can install it with pip:

pip install livelossplot

@ckolluru
Copy link
Copy Markdown

ckolluru commented May 1, 2018

Hi, I'd like to know if it is possible to plot loss curves with respect to iteration number in Keras? Thanks!

@ChanChar
Copy link
Copy Markdown

@ckolluru you can create the above using your own custom callback but in terms of granularity, it looks like Keras supports down to at most a batch level.

@svshivapuja
Copy link
Copy Markdown

how do we add our own model to this?

@socca
Copy link
Copy Markdown

socca commented Jul 18, 2018

Thanks for the great project! I was wondering why is my figure show blocking the training? it seems I should close the figure every iteration to let it run and show the updated results. The training does not continue unless I close the figure.

@alexcpn
Copy link
Copy Markdown

alexcpn commented Jan 22, 2019

Thanks a lot

@rameshKrSah
Copy link
Copy Markdown

rameshKrSah commented Feb 18, 2019

Thanks!

@vikeshsingh37
Copy link
Copy Markdown

Thanks!

@Tez01
Copy link
Copy Markdown

Tez01 commented Mar 17, 2019

Thanks!

@ElaheMrz
Copy link
Copy Markdown

Thanks for the great project! I was wondering why is my figure show blocking the training? it seems I should close the figure every iteration to let it run and show the updated results. The training does not continue unless I close the figure.

was your problem solved? I have the same problem

@stared
Copy link
Copy Markdown
Author

stared commented Jun 19, 2019

This script is no longer being maintained (for the last year!).
Please use https://github.com/stared/livelossplot/ instead.

@ElaheMrz
Copy link
Copy Markdown

This script is no longer being maintained (for the last year!).
Please use https://github.com/stared/livelossplot/ instead.

I'm actually using that , but I have the same problem with that. the figure blocks the process and every epoch I have to close it for the build to continue ...

@maajdl
Copy link
Copy Markdown

maajdl commented Aug 22, 2019

Thanks a lot it saved my day!
I simply made log-log scale to display th loss ... since I hope the loss decreasing by several orders of magnitude !

@macd2
Copy link
Copy Markdown

macd2 commented Oct 17, 2019

is it possible to get the live plot per batch instead of per epoch?

@Melavous
Copy link
Copy Markdown

Hi, I have the same problem than @socca. Could somebody help please?

@lvwarren
Copy link
Copy Markdown

This is just fantastic. Thank you.

@ahmed-ais
Copy link
Copy Markdown

@ElaheMrz you need to use Jupyter for that.

@CrazyHrodgar
Copy link
Copy Markdown

Awesome work, it works very well!
Thanks for sharing :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment