Hello,
In my training code I write the mean accuracy and the accuracy of each class to a json file, at every epoch. The code works well in general, except on one of my datasets, it generated an error:
TypeError: tensor(0.9238, device=‘cuda:0’, dtype=torch.float64) is not JSON serializable
json.dump(class_accuracies, outfile, cls=MyEncoder)
File “/usr/lib/python2.7/json/init.py”, line 189, in dump
for chunk in iterable:
File “/usr/lib/python2.7/json/encoder.py”, line 431, in _iterencode
for chunk in _iterencode_list(o, _current_indent_level):
File “/usr/lib/python2.7/json/encoder.py”, line 332, in _iterencode_list
for chunk in chunks:
File “/usr/lib/python2.7/json/encoder.py”, line 408, in _iterencode_dict
for chunk in chunks:
File “/usr/lib/python2.7/json/encoder.py”, line 442, in _iterencode
o = _default(o)
File “/root/computing/models/image_recognition/resnet/khue_lib/train_qopius.py”, line 62, in default
return super(MyEncoder, self).default(obj)
File “/usr/lib/python2.7/json/encoder.py”, line 184, in default
raise TypeError(repr(o) + " is not JSON serializable")
TypeError: tensor(0.9238, device=‘cuda:0’, dtype=torch.float64) is not JSON serializable
What is strange is that this error only occurs on one dataset. I have using this code for a long time without any problems. My PyTorch version is 1.0 and the main part of the code is attached below.
Thank you very much for your help!
class_accuracies = []
best_acc = -1.0
for epoch in range(num_epochs):
for phase in ['train', 'val']:
print('Entering in phase:', phase)
if phase == 'train':
scheduler.step(best_acc)
model.train()
else:
model.eval()
running_loss = 0.0
running_corrects = 0
# Iterate over data.
print('Iterating over data:')
n_samples = 0
for batch_idx, (inputs, labels) in enumerate(dataloaders[phase]):
inputs = inputs.to(device)
labels = labels.to(device)
# zero the parameter gradients
optimizer.zero_grad()
# forward
# track history if only in train
with torch.set_grad_enabled(phase == 'train'):
outputs = model(inputs)
_, preds = torch.max(outputs, 1)
loss = criterion(outputs, labels)
# backward + optimize only if in training phase
if phase == 'train':
loss.backward()
optimizer.step()
# statistics
running_loss += loss.item() * inputs.size(0)
running_corrects += torch.sum(preds == labels.data)
n_samples += len(labels)
if phase == 'train':
print('{}/{} Avg Loss: {:.4f} Avg Acc: {:.4f}'.format(n_samples, dataset_sizes[phase],
running_loss/n_samples, running_corrects.double()/n_samples))
print('Done iterating over data')
epoch_loss = running_loss / dataset_sizes[phase]
epoch_acc = running_corrects.double() / dataset_sizes[phase]
print('\t{} Loss: {:.4f}\t{} Acc: {:.4f}'.format(phase, epoch_loss, phase, epoch_acc))
# Here we are at the end of the 'val' phase
# check for improvement over the last epochs
if epoch_acc > best_acc:
print('Improved.')
best_acc = epoch_acc
try:
state_dict = model.module.state_dict()
except AttributeError:
state_dict = model.state_dict()
torch.save(state_dict, save_path)
class_acc_dict = defaultdict(str)
class_acc_dict['epoch'] = epoch
class_acc_dict['accuracy'] = best_acc
for i, class_name in enumerate(class_names):
class_acc_dict[unicode(class_name).encode("utf-8")] = per_class_accuracy[i]
class_accuracies.append(class_acc_dict)
with open(class_accuracy_file, 'w') as outfile:
json.dump(class_accuracies, outfile, cls=MyEncoder)