tensorboardX icon indicating copy to clipboard operation
tensorboardX copied to clipboard

tensorboard fails when add_image and add_histogram are used together. (cannot use same tag name for different modality)

Open anmolsjoshi opened this issue 6 years ago • 6 comments

import torch
from torch import nn
import torch.nn.functional as F
from torchvision import utils
import numpy as np

from tensorboardX import SummaryWriter

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(1, 10, kernel_size=5)
        self.conv2 = nn.Conv2d(10, 20, kernel_size=5)
        self.conv2_drop = nn.Dropout2d()
        self.fc1 = nn.Linear(320, 50)
        self.fc2 = nn.Linear(50, 10)

    def forward(self, x):
        x = F.relu(F.max_pool2d(self.conv1(x), 2))
        x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2))
        x = x.view(-1, 320)
        x = F.relu(self.fc1(x))
        x = F.dropout(x, training=self.training)
        x = self.fc2(x)
        return F.log_softmax(x, dim=-1)

def vistensor(tensor, ch=0, allkernels=False, nrow=8, padding=1): 
    '''
    vistensor: visuzlization tensor
        @ch: visualization channel 
        @allkernels: visualization all tensores
    ''' 
    
    n,c,w,h = tensor.shape
    if allkernels: tensor = tensor.view(n*c,-1,w,h )
    elif c != 3: tensor = tensor[:,ch,:,:].unsqueeze(dim=1)
        
    rows = np.min( (tensor.shape[0]//nrow + 1, 64 )  )    
    grid = utils.make_grid(tensor, nrow=nrow, normalize=True, padding=padding)

    return grid

net = Net()

writer = SummaryWriter(log_dir='logs/')

for name, param in net.named_parameters(): 
    #writer.add_histogram(tag=name, values=param.data, global_step=1)
    w_img = param.data
    shape = list(w_img.size())
    
    if len(shape) == 1:
        w_img = w_img.view(shape[0], 1, 1, 1)
        if shape[0] > 16:
            nrow = 16
        else:
            nrow = shape[0]
        grid = vistensor(w_img, ch=0, allkernels=True, padding=0, nrow=nrow)

    elif len(shape) == 2:
        if shape[0] > shape[1]:
            w_img = torch.transpose(w_img, 0, 1)
            shape = list(w_img.size())
        w_img = w_img.view(shape[0] * shape[1], 1, 1, 1)
        grid = vistensor(w_img, ch=0, allkernels=True,
                                nrow=int(np.sqrt(shape[0] * shape[1])), padding=0)

    elif len(shape) == 3:
        w_img = w_img.view(shape[0], 1, shape[1], shape[2])
        grid = vistensor(w_img, ch=0, allkernels=True, padding=1)

    elif len(shape) == 4:
        grid = vistensor(w_img, ch=0, allkernels=True, padding=1)

    else:
        continue

    writer.add_image(name, grid.numpy(), 1)
    writer.add_histogram(tag=name, values=param.data, global_step=1)

It looks like add_image and add_histogram can't work together for the above code. One or the other can be run independently, but cannot be run together. I get the error below, any idea what I'm doing wrong?

    execute(self.server.app)
  File "/home/joshi/nlptorch/env/lib/python3.5/site-packages/werkzeug/serving.py", line 258, in execute
    application_iter = app(environ, start_response)
  File "/home/joshi/nlptorch/env/lib/python3.5/site-packages/tensorboard/backend/application.py", line 270, in __call__
    return self.data_applications[clean_path](environ, start_response)
  File "/home/joshi/nlptorch/env/lib/python3.5/site-packages/werkzeug/wrappers.py", line 308, in application
    resp = f(*args[:-2] + (request,))
  File "/home/joshi/nlptorch/env/lib/python3.5/site-packages/tensorboard/plugins/histogram/histograms_plugin.py", line 233, in histograms_route
    return http_util.Respond(request, body, mime_type, code=code)
  File "/home/joshi/nlptorch/env/lib/python3.5/site-packages/tensorboard/backend/http_util.py", line 116, in Respond
    content = json.dumps(json_util.Cleanse(content, encoding),
  File "/home/joshi/nlptorch/env/lib/python3.5/site-packages/tensorboard/backend/json_util.py", line 68, in Cleanse
    return [Cleanse(i, encoding) for i in obj]
  File "/home/joshi/nlptorch/env/lib/python3.5/site-packages/tensorboard/backend/json_util.py", line 68, in <listcomp>
    return [Cleanse(i, encoding) for i in obj]
  File "/home/joshi/nlptorch/env/lib/python3.5/site-packages/tensorboard/backend/json_util.py", line 68, in Cleanse
    return [Cleanse(i, encoding) for i in obj]
  File "/home/joshi/nlptorch/env/lib/python3.5/site-packages/tensorboard/backend/json_util.py", line 68, in <listcomp>
    return [Cleanse(i, encoding) for i in obj]
  File "/home/joshi/nlptorch/env/lib/python3.5/site-packages/tensorboard/backend/json_util.py", line 68, in Cleanse
    return [Cleanse(i, encoding) for i in obj]
  File "/home/joshi/nlptorch/env/lib/python3.5/site-packages/tensorboard/backend/json_util.py", line 68, in <listcomp>
    return [Cleanse(i, encoding) for i in obj]
  File "/home/joshi/nlptorch/env/lib/python3.5/site-packages/tensorboard/backend/json_util.py", line 66, in Cleanse
    return tf.compat.as_text(obj, encoding)
  File "/home/joshi/nlptorch/env/lib/python3.5/site-packages/tensorflow/python/util/compat.py", line 88, in as_text
    return bytes_or_text.decode(encoding)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x89 in position 0: invalid start byte
E0912 01:00:08.212224 Thread-26 _internal.py:88] Error on request:

@lanpa any idea what's wrong?

Using tensorboard 1.7.0, pytorch 0.4, torchvision 0.2 and tensorboardX from the FAQ

anmolsjoshi avatar Sep 12 '18 08:09 anmolsjoshi

Hi, I changed writer.add_image(name, grid.numpy(), 1) to writer.add_image('img_'+name, grid.numpy(), 1) and everything works.

It appears that it's a name conflict problem and will need further investigation. (the name was used in image and histogram proto, not sure if it's a tensorboard bug or tensorboardX bug)

lanpa avatar Sep 19 '18 16:09 lanpa

I tried make the same conflict in demo.py and the situation is the same. There is no problem in your code.

lanpa avatar Sep 19 '18 16:09 lanpa

Thanks for getting back to me. This is a fantastic library!

anmolsjoshi avatar Sep 19 '18 17:09 anmolsjoshi

I'm get same error when create scalar and histogram with same tag:

Traceback (most recent call last):
  File "/home/toodef/anaconda3/envs/tensorflow/lib/python3.6/site-packages/werkzeug/serving.py", line 270, in run_wsgi
    execute(self.server.app)
  File "/home/toodef/anaconda3/envs/tensorflow/lib/python3.6/site-packages/werkzeug/serving.py", line 258, in execute
    application_iter = app(environ, start_response)
  File "/home/toodef/anaconda3/envs/tensorflow/lib/python3.6/site-packages/tensorboard/backend/application.py", line 291, in __call__
    return self.data_applications[clean_path](environ, start_response)
  File "/home/toodef/anaconda3/envs/tensorflow/lib/python3.6/site-packages/werkzeug/wrappers.py", line 308, in application
    resp = f(*args[:-2] + (request,))
  File "/home/toodef/anaconda3/envs/tensorflow/lib/python3.6/site-packages/tensorboard/plugins/scalar/scalars_plugin.py", line 195, in scalars_route
    (body, mime_type) = self.scalars_impl(tag, run, output_format)
  File "/home/toodef/anaconda3/envs/tensorflow/lib/python3.6/site-packages/tensorboard/plugins/scalar/scalars_plugin.py", line 158, in scalars_impl
    for tensor_event in tensor_events]
  File "/home/toodef/anaconda3/envs/tensorflow/lib/python3.6/site-packages/tensorboard/plugins/scalar/scalars_plugin.py", line 158, in <listcomp>
    for tensor_event in tensor_events]
ValueError: can only convert an array of size 1 to a Python scalar

TEnsorboardX 1.2; Tensorboard 1.9.0 (looks like all versions from 1.6 raise this error).

toodef avatar Dec 14 '18 07:12 toodef

THANK YOU SOOO MUCH. Literally saved me hours.

Way-Yuhao avatar Feb 17 '22 05:02 Way-Yuhao

I recently encountered a similar issue with TensorBoardX. To resolve it, I had to put an if-else clause for handling add_image and add_histogram function calls separately. Subscribed to this thread for updates.

yyyuhan avatar Dec 11 '23 12:12 yyyuhan