Talk with your network with Visdom

Visdom Callback

In this post, I will give an example of how to set up callable UI with Visdom. It will give you the ability to request a picture from your Pytorch training script just by pressing a key on the keyboard.

A screenshot of this functionality can be seen in the following gif where with the press of the ENTER key the first window on the left is updated by a fresh input sample on a toy network training on MNIST



Visdom is power tool by Facebook, that can provide you with useful, easy to set up visualization to monitor the training of your deep learning models. In comparison with the other popular option of Tensorboard, it can supply a wider range of visualizations. On the other hand, only a few coding examples are available online, discouraging its use

As Visdom windows support callable functions can be used to build useful utilities. This kind of functionality in your code can give an early insight into how your training is going, in a visually appealing way.

But let’s begin. To incorporate Visdom in my Pytorch code you can use the tnt library. TNT is a library providing, among other utilities, powerful logging and visualization tools for Python. It is closely integrated with PyTorch.

If you haven’t yet, Install Visdom through pip

Run this command in your terminal to initialize the Visdom server

python -m visdom.server -port 8097 &

Import in your script the following import statements for tnt

import torchnet as tnt
from torchnet.logger import VisdomPlotLogger, VisdomLogger, VisdomSaver, VisdomTextLogger

The default scalar plots can be initialized as follows.

    train_lossperbatch_logger = VisdomPlotLogger(
        'line', port=port, opts={'title': 'Train Loss per batch'},env='exp2')

and updated in every training iteration

def on_forward(state):
#i is just an incremented integer variable
global i

More example of applying visdom logger like this can be found in here

To improve upon this logger and add the desirable callable functionality, we can subclass it in the following class

class CallbackLogger(VisdomLogger):

    def __init__(self,*args, **kwargs):
#pass the supplied arguments into the parent class (Visdom Logger constructor)
        super(CallbackLogger,self).__init__(*args, **kwargs)
        self.img_to_use = torch.rand([3, 10, 10])

    def requestImage(self, imageTouse):

    def callback(self,event):

Let’s talk a little about the previous code snippet. The constructor is passing *args, **kwargs to the parent class in order to avoid altering the VisdomLogger constructor.

The line is just initializing the Visdom Logger with a random image. I have to use this line cause in a different case the property that I am supplying next to self.viz.register_event_handler(self.callback, will not get an initial value.

self.img_to_use = torch.rand([3, 10, 10])

Not the neatest solution but if you dont log an image this parameter stays equal to None

The bool property self.callbackhit will be checked from my main training function to see if the callback has been invoked from the user. If yes a new image will be registered again from the main training function.

In the code that handles the network forward pass we add

 if(textfield.callbackhit is True):


The new logger class we created can be initialized like

customLogger=CallbackLogger('image',env='exp2', port= 8097)


The result is that by just selecting the callback logger window in the visdom web UI and pressing ENTER, the window is updated with an image of the network output.


  1. Keerthy

    Hey! Thats a great post!! I am sure this is going to help us all deep learning bugs! Will keep you posted on how it goes!

Leave a Reply

Your email address will not be published. Required fields are marked *