1.问题
在ssds检测项目中,其中求损失的multibox_loss.py中遇到一个bug,错误为:
IndexError: The shape of the mask [32, 2990] at index 0 does not match the shape of the indexed tensor [95680, 1] at index 0
报错代码如下:
loss_c[pos] = 0
其中,pos和loss_c的尺寸维度分别是:
loss_c.size torch.Size([95680, 1])
pos.size torch.Size([32, 2990])
然后,我写了一小段代码,来看一下loss_c[pos]操作是怎么操作的,其中的原理以及作用是什么。
测试代码:
loss = torch.rand(10,1)
print('loss',loss)
pos = pos.byte()
print('pos.size',pos.size(),'pos.type',type(pos),'\n','pos',pos)
print(loss[pos])
结果如下:
可以看出,如果直接用上述的pos和loss_c的维度是会报上述的错误,经过我的测试,loss_c[pos]操作是把pos为1的元素对应的位置上的loss_c的元素保留下来,最终输出一个列表,所以两者的维度需要一样。
需要注意的是,pos定义的类型需要是byte 或bool tensor类型,不然不能用作index。
我将代码更改如下,将loss_c的维度更改为和pos一样:
loss = torch.rand(10,1)
print('loss',loss)
pos = pos.byte()
print('pos.size',pos.size(),'pos.type',type(pos),'\n','pos',pos)
loss = loss.view(pos.size()[0],pos.size()[1])
print(loss[pos])
结果如下:
可以看出,操作结果确实如上所说。
所以在这里的源代码里,在loss_c[pos] = 0之前,也加上上述修改代码。
2.修改完之后,又遇到一个新的问题:
IndexError: invalid index of a 0-dim tensor. Use tensor.item() to convert a 0-dim tensor to a Python number
这里只需要把ssds_train.py中的
loss_l.data[0]
loss_c.data[0]
对应修改为:
loss_l.item()
loss_c.item()
即可。
3.在这个过程中,还有一个警告,这个警告是因为pytorch升级所引起的。警告如下:
UserWarning: size_average and reduce args will be deprecated, please use reduction='sum' instead.
warnings.warn(warning.format(ret))
意思就是,在新的pytorch版本中,size_average 和reduce 这两个参数,都将不再支持,按照上面提示进行修改,将multibox_loss.py中对应的代码:
loss_c = F.cross_entropy(conf_p, targets_weighted, size_average=False)
修改为如下:
loss_c = F.cross_entropy(conf_p, targets_weighted, reduction='sum')
所有对应的位置都需要修改。
4.在进行eval的时候,报错如下:
File "/home/dhb/jupyter notebook/Project/Project_1/ssds.pytorch-master/lib/utils/eval_utils.py", line 96, in cal_tp_fp
gt_c = [_gt[:4].data.resize_(1,4) for _gt in gt if int(_gt[4]) == i]
File "/home/dhb/jupyter notebook/Project/Project_1/ssds.pytorch-master/lib/utils/eval_utils.py", line 96, in
gt_c = [_gt[:4].data.resize_(1,4) for _gt in gt if int(_gt[4]) == i]
RuntimeError: set_sizes_contiguous is not allowed on Tensor created from .data or .detach()
主要也是因为pytorch升级带来的错误需要将该代码:
gt_c = [_gt[:4].data.resize_(1,4) for _gt in gt if int(_gt[4]) == i]
修改为如下:
gt_c = [_gt[:4].resize_(1,4) for _gt in gt if int(_gt[4]) == i]
即可。
在eval_utils.py的所有地方都要进行此修改。
5.visialize_utils.py的问题
File "/home/dhb/jupyter notebook/Project/Project_1/ssds.pytorch-master/lib/ssds_train.py", line 526, in visualize_epoch
File "/home/dhb/jupyter notebook/Project/Project_1/ssds.pytorch-master/lib/utils/visualize_utils.py", line 156, in viz_prior_box
writer.add_image('example_prior_boxs/feature_map_{}'.format(k), image_show, epoch)
File "/home/dhb/anaconda3/lib/python3.7/site-packages/tensorboardX/writer.py", line 548, in add_image
image(tag, img_tensor, dataformats=dataformats), global_step, walltime)
File "/home/dhb/anaconda3/lib/python3.7/site-packages/tensorboardX/summary.py", line 216, in image
image = make_image(tensor, rescale=rescale)
File "/home/dhb/anaconda3/lib/python3.7/site-packages/tensorboardX/summary.py", line 256, in make_image
image = Image.fromarray(tensor)
File "/home/dhb/anaconda3/lib/python3.7/site-packages/PIL/Image.py", line 2517, in fromarray
raise TypeError("Cannot handle this data type")
TypeError: Cannot handle this data type
这也是因为pytorch版本升级引起的问题,需要将问题代码如下:
writer.add_image('example_prior_boxs/feature_map_{}'.format(k), image_show, epoch)
修改为如下:
image_show=torch.from_numpy(image_show).permute(2,0,1)
writer.add_image('example_prior_boxs/feature_map_{}'.,,ormat(k), image_show/255, epoch)
需要将对应的代码都要做上述修改,需要把numpy类型转为tensor类型。
参考:https://github.com/albertpumarola/GANimation/issues/49
另外,为了解决转换之后内存地址不连续的问题,在转换前应该加上:
image = image.copy()
变成如下所示:
image = image.copy() #解决内存地址不连续的问题
image=torch.from_numpy(image).permute(2,0,1)
writer.add_image('{}/{}'.format(prefix, name), image/255, epoch)