Visdom: TypeError: Object of type Tensor is not JSON serializable

Created on 23 Jan 2019  路  12Comments  路  Source: fossasia/visdom

Bug Description
**When trying to train my model and show the process,I found that the process of train is OK,but it shows that 'TypeError: Object of type Tensor is not JSON serializable' like this.And the visdom didn't work.

Traceback (most recent call last):
File "main.py", line 354, in
fire.Fire()
File "/home/lyz/anaconda3/lib/python3.7/site-packages/fire/core.py", line 127, in Fire
component_trace = _Fire(component, args, context, name)
File "/home/lyz/anaconda3/lib/python3.7/site-packages/fire/core.py", line 366, in _Fire
component, remaining_args)
File "/home/lyz/anaconda3/lib/python3.7/site-packages/fire/core.py", line 542, in _CallCallable
result = fn(varargs, *kwargs)
File "main.py", line 198, in train
'val_acc':val_acc.value()[0]},win_name = 'Acc')
File "/home/lyz/project/awesome_face_antispoofing/utils/Visualizer.py", line 67, in plot_many_stack
update=None if x == 0 else 'append'
File "/home/lyz/anaconda3/lib/python3.7/site-packages/visdom/__init__.py", line 335, in wrapped_f
return f(args, *kwargs)
File "/home/lyz/anaconda3/lib/python3.7/site-packages/visdom/__init__.py", line 1367, in line
update=update, name=name)
File "/home/lyz/anaconda3/lib/python3.7/site-packages/visdom/__init__.py", line 335, in wrapped_f
return f(args, *kwargs)
File "/home/lyz/anaconda3/lib/python3.7/site-packages/visdom/__init__.py", line 1292, in scatter
return self._send(data_to_send, endpoint=endpoint)
File "/home/lyz/anaconda3/lib/python3.7/site-packages/visdom/__init__.py", line 548, in _send
data=json.dumps(msg),
File "/home/lyz/anaconda3/lib/python3.7/json/__init__.py", line 231, in dumps
return _default_encoder.encode(obj)
File "/home/lyz/anaconda3/lib/python3.7/json/encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/home/lyz/anaconda3/lib/python3.7/json/encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "/home/lyz/anaconda3/lib/python3.7/json/encoder.py", line 179, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type Tensor is not JSON serializable

while my Pytorch is 1.0.0.Any advice will be greatful,thanks in advance.

Most helpful comment

@JackUrb I got the answer, I converted each element to numpy using torch.cpu().data.numpy() and it works now.

All 12 comments

Please let us know more information regarding it.
For example: OS description, the part of code where this error occurred, etc.
What you have given is the problem but where it occurred, please mention that too.

Hi @liuyazhou951218 - I haven't actually caught up with testing pytorch 1.0 compatibility. In 0.4 a passed tensor would be converted to a numpy array automatically, but perhaps that's not working correctly anymore? Can you give a reproducible example, like providing the values of the args that you're sending to visdom.line?

@JafferWilson @JackUrb thanks for your quick response.I just forked this project https://github.com/JinghuiZhou/awesome_face_antispoofing to my repository. My OS is Ubuntu 14.04.5 LTS,and the visdom is 0.1.8.8. Here is a script for visualization in https://github.com/JinghuiZhou/awesome_face_antispoofing/blob/master/utils/Visualizer.py. and I think that the wrong part of the code is
` def plot_many_stack(self, d, win_name):
name=list(d.keys())
name_total=" ".join(name)
x = self.index.get(name_total, 0)
val=list(d.values())
if len(val)==1:
y=np.array(val)
else:
y=np.array(val).reshape(-1,len(val))
#print(x)
self.vis.line(Y=y,X=np.ones(y.shape)*x,
win=str(win_name),#unicode
opts=dict(legend=name,
title=win_name),
update=None if x == 0 else 'append'
)
self.index[name_total] = x + 1

'
when I try to send values to visdom.so how can I fix this? Thanks a lot

And the browser shows that 'File failed to load: /extensions/MathZoom.js'

Can you print the values of X and Y right before the vis.line call?

Closing as there hasn't been any updates. I suspect that the issue is that np.array(val) isn't properly converting val to a numpy array as val is an array of tensors which should be converted using torch syntax, but without a response I can't confirm.

Can we open this issue @JackUrb as am getting similar error and my values of Y are : [tensor(1.2048, device='cuda:1'), tensor(32.4229, device='cuda:1'), tensor(0.9801, device='cuda:1'), tensor(0.6179, device='cuda:1')]

@Eyshika While we're able to convert tensors, converting a list of tensors currently is not supported.

Can you try editing __init__.py and updating the start of _to_numpy to look as such:

def _to_numpy(a):
    if isinstance(a, list):
        return np.array([_to_numpy(i) for i in a])
    ...

@JackUrb I got the answer, I converted each element to numpy using torch.cpu().data.numpy() and it works now.

Right - the above suggestion should hopefully do exactly that automatically, but I haven't been able to take a chance to test it. Glad to hear you found a solution though.

@JackUrb I got the answer, I converted each element to numpy using torch.cpu().data.numpy() and it works now.

can you tell more details about it?I meet similar problem and I dont know how to convert each element to numpy...Thanks a lot

@JackUrb I got the answer, I converted each element to numpy using torch.cpu().data.numpy() and it works now.

can you tell more details about it?I meet similar problem and I dont know how to convert each element to numpy...Thanks a lot

@spicy-dog
Hope you have solved your problem, if not, that is what I have done to pass through.
If you are using the same repository as @liuyazhou951218, that is awesome_face_antispooing.
I used some of the code in __init__.py of Visdom, and I copied some of them to the Visualizer.py since I have no idea how to call them outside of the __init__.py file.
This method may seem to be dummy, but it really works.
After the part of importing libraries in Visualizer.py, I add the following code:

torch_types = []
try:
    import torch
    torch_types.append(torch.Tensor)
    torch_types.append(torch.nn.Parameter)
except (ImportError, AttributeError):
    pass

Then, in the class Visualizer(object), I add the following function:

    def to_numpy(self, a):
        if isinstance(a, list):
            return np.array(a)
        for kind in torch_types:
            if isinstance(a, kind):
                if hasattr(a, 'detach'):
                    a = a.detach()
                return a.cpu().numpy()
        return a

Finally, I changed the y in the function plot_many_stack(self, d, win_name)
from

        if len(val) == 1:
            y = np.array(val)
        else:
            y = np.array(val).reshape(-1, len(val))

to

        if len(val) == 1:
            y = np.array([self.to_numpy(i) for i in val])
        else:
            y = np.array([self.to_numpy(i) for i in val]).reshape(-1, len(val))

That is all you need for the modification in Visualizer.py file.

Was this page helpful?
0 / 5 - 0 ratings