第一次做遥感图像多分类的语义分割,有点力不从心。在此记录一下一些遇到的bug。(https://github.com/milesial/Pytorch-UNet)源码地址

1.TypeError: Cannot handle this data type

原因:在pytorch中tensor默认是CHW,而PIL中是HWC。在tensorboardX中的SummaryWriter.add_imge()的函数默认dataformats=\’CHW\’,并存在convert_to_HWC操作,致使自己本来是就是HWC的tensor,变成了WCH的numpy类型。从而导致在PIL的fromarray操作无法识别数据类型。

关于tensor、PIL以及numpy转换的问题见下:

https://blog.csdn.net/daydayjump/article/details/88808394?utm_source=distribute.pc_relevant.none-task

 

2.RuntimeError: CUDA out of memory. Tried to allocate…

原因:batch_size或者输入图片尺寸太大了电脑吃不消,改小一点。

 

3.1only batches of spatial targets supported (non-empty 3D tensors) but got targets of size

原因:这个原因是因为在使用Crossentropyloss作为损失函数时,output=net(input)的output应该是[batchsize, channel, height, weight],而label则是[batchsize, height, weight],label是单通道灰度图。需要用torch.squeeze取消一个维度。

而在BCELoss中,两者都是[batchsize, channel, height, weight]

 

4.cuda runtime error: device-side assert triggerde at/pytorch…

原因:模型输出的label与实际的label标签类别数量是否相同?此外,label里不能有-1这个索引。

 

5.在改动Unet的代码跑自己的数据集时,尤其要注意实例化的dataset中,数据的读取是否存在问题。

一般使用os.listdir\os.path.join\splittext组合来读取图片路径,有关os\shutil命令如下:

https://www.cnblogs.com/andy-x/p/10144658.html

 

6.predict出图时,为了可视化结果。

有时不用Dataloader而是直接读取图像路径。为了输入图像到网络,需要先把图片数据转换成tensor,进行resize重采样。然后用unsqueeze扩充1个维度(batchsize)再输入网络,得到输出后,进行softmax计算概率后再减去batchsize的维度。这里存疑,为什么别人说是直接把输出argmax就可以了?我这里最后得到的是bool型的矩阵。但是结果并不理想,目前还不清楚是为什么?

 

  1. class Transformer(object):
    def __init__(self, size, interpolation=Image.BILINEAR):
    self.size = size
    self.interpolation = interpolation
    self.toTensor = transforms.ToTensor()

    def __call__(self, img_):
    img_ = img_.resize(self.size, self.interpolation)
    img_ = self.toTensor(img_)
    return img_


    model = UNet(3,7)
  2. model_path = \'./checkpoint/Unet/model/netG_final.pth\'
  3. model.load_state_dict(torch.load(model_path,map_location=\'cpu\'))
  4. model.eval()
  5. test_image_path = r\'D:\DeepGlobe_LandCover_CVPR2018\train\src\1.jpg\'
  6. test_image = Image.open(test_image_path)
  7. print(\'Operating...\')
  8. transformer = Transformer((256, 256))
  9. img = transformer(test_image)
  10. img = img.unsqueeze(0)
  11. with torch.no_grad():
  12. label_image = model(img)
  13. label_image = F.softmax(label_image, dim=1) #计算loss时,损失函数内置softmax,而网络层没有,所以要可视化,需要softmax 。多分类softmax,二分类sigmoid
  14. label_image = label_image.squeeze(0)
  15. full_mask = label_image.squeeze().numpy()
  16. full_mask = full_mask > 0.5

 7.补充一个rgb2label的代码

 

  1. def color2annotation(input_path, output_path):
  2. # image = scipy.misc.imread(input_path)
  3. # imread is deprecated in SciPy 1.0.0, and will be removed in 1.2.0. Use imageio.imread instead.
  4. image = imageio.imread(input_path)
  5. image = (image >= 128).astype(np.uint8)
  6. image = 4 * image[:, :, 0] + 2 * image[:, :, 1] + image[:, :, 2]
  7. cat_image = np.zeros((2448,2448), dtype=np.uint8)
  8. cat_image[image == 3] = 0 # (Cyan: 011) Urban land
  9. cat_image[image == 6] = 1 # (Yellow: 110) Agriculture land
  10. cat_image[image == 5] = 2 # (Purple: 101) Rangeland
  11. cat_image[image == 2] = 3 # (Green: 010) Forest land
  12. cat_image[image == 1] = 4 # (Blue: 001) Water
  13. cat_image[image == 7] = 5 # (White: 111) Barren land
  14. cat_image[image == 0] = 6 # (Black: 000) Unknown
  15. # scipy.misc.imsave(output_path, cat_image)
  16. imageio.imsave(output_path, cat_image)
  17. pass

 

 8.未完待续。

 

版权声明:本文为ljwgis原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/ljwgis/p/12335760.html