• Ubuntu20运行SegNeXt代码提取道路水体(四)——成功解决训练与推理自己的数据集iou为0的问题!!


    在我的这篇博文里
    Ubuntu20运行SegNeXt代码提取道路水体(三)——SegNeXt训练与推理自己的数据集
    经过一系列配置后
    iou算出来是0
    经过多次尝试后
    终于让我试出来了正确配置方法!

    具体的配置细节请查看这篇文章

    1、在mmseg/datasets下面对数据集进行初始定义

    我新建了一个myroaddata.py文件
     里面的内容是:

    1. # Copyright (c) OpenMMLab. All rights reserved.
    2. import os.path as osp
    3. import mmcv
    4. import numpy as np
    5. from PIL import Image
    6. from .builder import DATASETS
    7. from .custom import CustomDataset
    8. @DATASETS.register_module()
    9. class MyRoadData(CustomDataset):
    10. CLASSES = ('background','road')
    11. PALETTE = [[0,0,0],[255, 255, 255]]
    12. def __init__(self, **kwargs):
    13. super(MyRoadData, self).__init__(img_suffix='_sat.tif', seg_map_suffix='_mask.png',
    14. **kwargs)
    15. assert osp.exists(self.img_dir)

    2、修改mmseg/datasets/目录下的_init_.py

     把我的自定义数据集加到原_init_.py中

    1. # Copyright (c) OpenMMLab. All rights reserved.
    2. from .ade import ADE20KDataset
    3. from .builder import DATASETS, PIPELINES, build_dataloader, build_dataset
    4. from .chase_db1 import ChaseDB1Dataset
    5. from .cityscapes import CityscapesDataset
    6. from .coco_stuff import COCOStuffDataset
    7. from .custom import CustomDataset
    8. from .dark_zurich import DarkZurichDataset
    9. from .dataset_wrappers import (ConcatDataset, MultiImageMixDataset,
    10. RepeatDataset)
    11. from .drive import DRIVEDataset
    12. from .hrf import HRFDataset
    13. from .isaid import iSAIDDataset
    14. from .isprs import ISPRSDataset
    15. from .loveda import LoveDADataset
    16. from .night_driving import NightDrivingDataset
    17. from .pascal_context import PascalContextDataset, PascalContextDataset59
    18. from .potsdam import PotsdamDataset
    19. from .stare import STAREDataset
    20. from .voc import PascalVOCDataset
    21. from .myroaddata import MyRoadData
    22. __all__ = [
    23. 'CustomDataset', 'build_dataloader', 'ConcatDataset', 'RepeatDataset',
    24. 'DATASETS', 'build_dataset', 'PIPELINES', 'CityscapesDataset',
    25. 'PascalVOCDataset', 'ADE20KDataset', 'PascalContextDataset',
    26. 'PascalContextDataset59', 'ChaseDB1Dataset', 'DRIVEDataset', 'HRFDataset',
    27. 'STAREDataset', 'DarkZurichDataset', 'NightDrivingDataset',
    28. 'COCOStuffDataset', 'LoveDADataset', 'MultiImageMixDataset',
    29. 'iSAIDDataset', 'ISPRSDataset', 'PotsdamDataset','MyRoadData'
    30. ]

    3、在configs/base/datasets下面对数据加载进行定义

     我新建了一个myroad.py

    里面的内容为

    1. # dataset settings
    2. dataset_type = 'MyRoadData'
    3. data_root = 'data/MyRoadData'
    4. img_norm_cfg = dict(
    5. mean=[0.5947, 0.5815, 0.5625], std=[0.1173, 0.1169, 0.1157], to_rgb=True)
    6. img_scale = (512, 512)
    7. crop_size = (256, 256)
    8. train_pipeline = [
    9. dict(type='LoadImageFromFile'),
    10. dict(type='LoadAnnotations'),
    11. dict(type='Resize', img_scale=img_scale, ratio_range=(0.5, 2.0)),
    12. dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.75),
    13. dict(type='RandomFlip', prob=0.5),
    14. dict(type='PhotoMetricDistortion'),
    15. dict(type='Normalize', **img_norm_cfg),
    16. dict(type='Pad', size=crop_size, pad_val=0, seg_pad_val=255),
    17. dict(type='DefaultFormatBundle'),
    18. dict(type='Collect', keys=['img', 'gt_semantic_seg'])
    19. ]
    20. test_pipeline = [
    21. dict(type='LoadImageFromFile'),
    22. dict(
    23. type='MultiScaleFlipAug',
    24. img_scale=img_scale,
    25. # img_ratios=[0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0],
    26. flip=False,
    27. transforms=[
    28. dict(type='Resize', keep_ratio=True),
    29. dict(type='RandomFlip'),
    30. dict(type='Normalize', **img_norm_cfg),
    31. dict(type='ImageToTensor', keys=['img']),
    32. dict(type='Collect', keys=['img'])
    33. ])
    34. ]
    35. data = dict(
    36. samples_per_gpu=4,
    37. workers_per_gpu=8,
    38. train=dict(
    39. type='RepeatDataset',
    40. times=40000,
    41. dataset=dict(
    42. type=dataset_type,
    43. data_root=data_root,
    44. img_dir='images/training',
    45. ann_dir='annotations/training',
    46. pipeline=train_pipeline)),
    47. val=dict(
    48. type=dataset_type,
    49. data_root=data_root,
    50. img_dir='images/validation',
    51. ann_dir='annotations/validation',
    52. pipeline=test_pipeline),
    53. test=dict(
    54. type=dataset_type,
    55. data_root=data_root,
    56. img_dir='images/validation',
    57. ann_dir='annotations/validation',
    58. pipeline=test_pipeline))


    4、在configs/下面选择你需要的模型参数进行修改

    在configs/下面选择你需要的模型参数进行修改 以pspnet为例子,在configs/pspnet/下新建一个文件pspnet_r50-d8_512x1024_40k_myroaddata.py

    1. _base_ = [
    2. '../_base_/models/pspnet_r50-d8.py', '../_base_/datasets/myroad.py',
    3. '../_base_/default_runtime.py', '../_base_/schedules/schedule_40k.py'
    4. ]

    5、修改configs/base/models/下面的pspnet_r50-d8.py

    1. # model settings
    2. norm_cfg = dict(type='BN', requires_grad=True)
    3. model = dict(
    4. type='EncoderDecoder',
    5. pretrained='open-mmlab://resnet50_v1c',
    6. backbone=dict(
    7. type='ResNetV1c',
    8. depth=50,
    9. num_stages=4,
    10. out_indices=(0, 1, 2, 3),
    11. dilations=(1, 1, 2, 4),
    12. strides=(1, 2, 1, 1),
    13. norm_cfg=norm_cfg,
    14. norm_eval=False,
    15. style='pytorch',
    16. contract_dilation=True),
    17. decode_head=dict(
    18. type='PSPHead',
    19. in_channels=2048,
    20. in_index=3,
    21. channels=512,
    22. pool_scales=(1, 2, 3, 6),
    23. dropout_ratio=0.1,
    24. num_classes=19,
    25. norm_cfg=norm_cfg,
    26. align_corners=False,
    27. loss_decode=dict(
    28. type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)),
    29. auxiliary_head=dict(
    30. type='FCNHead',
    31. in_channels=1024,
    32. in_index=2,
    33. channels=256,
    34. num_convs=1,
    35. concat_input=False,
    36. dropout_ratio=0.1,
    37. num_classes=19,
    38. norm_cfg=norm_cfg,
    39. align_corners=False,
    40. loss_decode=dict(
    41. type='CrossEntropyLoss', use_sigmoid=False, loss_weight=0.4)),
    42. # model training and testing settings
    43. train_cfg=dict(),
    44. test_cfg=dict(mode='whole'))

    6、返回tools/train.py进行训练

    python tools/train.py configs/pspnet/pspnet_r50-d8_512x1024_40k_myroaddata.py
    就可以跑啦

    结果图:

    自定义数据集格式配置 

     在data文件夹下新建一个MyRoadData文件夹,存放数据

    再次新建俩个文件夹

    annotation和images下面新建training和validation文件夹

     annotation-training下放训练标签

    annotation-validation放预测标签

    同理

    images-training放训练原图

    images-validation下放预测原图

    1、图片格式要求为8位深度

    注意,如果是24位的图片要全部转成8位!!!!

    不然会报错

    转换代码如下

    1. # -*- coding: utf-8 -*-
    2. """
    3. Created on Wed Oct 4 16:50:20 2022
    4. @author:Laney_Midory
    5. csdn:Laney_Midory
    6. """
    7. import cv2
    8. import os
    9. import glob
    10. import shutil
    11. import matplotlib.pyplot as plt
    12. import numpy as np
    13. from PIL import Image
    14. import torch
    15. import torch.nn as nn
    16. import torch.utils.data as data
    17. from torch.autograd import Variable as V
    18. import pickle
    19. from time import time
    20. os.environ["CUDA_VISIBLE_DEVICES"] = '0' # 指定第一块GPU可用
    21. # config.gpu_options.per_process_gpu_memory_fraction = 0.7 # 程序最多只能占用指定gpu50%的显存,服务器上注释掉这句
    22. Image.MAX_IMAGE_PIXELS = None
    23. tar = "/home/wangtianni/SegNeXt-main/SegNeXt-main/data/data/MyRoadData/annotations/training/"
    24. print('将24位深度转换为8位')
    25. mask_names = filter(lambda x: x.find('png')!=-1, os.listdir(tar))
    26. #trainlist = list(map(lambda x: x[:-8], imagelist))
    27. #new_path = "C:/Users/Administrator/Desktop/white/" # 目标文件夹
    28. for file in mask_names:
    29. path = tar + file.strip()
    30. if not os.path.exists(path):
    31. continue;
    32. img = Image.open(tar+file)#读取系统的内照片
    33. img2 = img.convert('P')
    34. # print(train_path+'\\'+base_name[0]+'_mask.png')
    35. img2.save(path)
    36. #img2.save(new_path +path2 + "_mask.png")
    37. print("Finish deep change!")

    2、图片一定要转换成0、1格式!!

    如果不转换成0,1格式的话可以跑起来,但结果不对

     

     因为我的road是255,背景是0,现在要把road变成1,背景是0,代码如下:

    1. # -*- coding: utf-8 -*-
    2. """
    3. Created on Wed Oct 4 16:50:20 2022
    4. @author:Laney_Midory
    5. csdn:Laney_Midory
    6. """
    7. import cv2
    8. import os
    9. import glob
    10. import shutil
    11. import matplotlib.pyplot as plt
    12. import numpy as np
    13. from PIL import Image
    14. import torch
    15. import torch.nn as nn
    16. import torch.utils.data as data
    17. from torch.autograd import Variable as V
    18. import pickle
    19. from time import time
    20. os.environ["CUDA_VISIBLE_DEVICES"] = '0' # 指定第一块GPU可用
    21. # config.gpu_options.per_process_gpu_memory_fraction = 0.7 # 程序最多只能占用指定gpu50%的显存,服务器上注释掉这句
    22. Image.MAX_IMAGE_PIXELS = None
    23. tar = "/home/wangtianni/SegNeXt-main/data/MyRoadData/annotations/training/"
    24. mask_list = os.listdir(tar)
    25. for file in mask_list:
    26. i = 0
    27. j = 0
    28. path = tar + file.strip()
    29. if not os.path.exists(path):
    30. continue;
    31. img = Image.open(tar+file)#读取系统的内照片
    32. width = img.size[0]#长度
    33. height = img.size[1]#宽度
    34. for i in range(0,width):#遍历所有长度的点
    35. for j in range(0,height):#遍历所有宽度的点
    36. data = (img.getpixel((i,j)))#打印该图片的所有点
    37. #print (data)#打印每个像素点的颜色RGBA的值(r,g,b)
    38. #print (data[0])#打印RGBA的r值
    39. if(data!=0):
    40. img.putpixel((i,j),1)
    41. data = (img.getpixel((i,j)))#打印该图片的所有点
    42. print(data)
    43. #img_array2[i, j] = (0, 0, 0)
    44. #img = img.convert("RGB")#把图片强制转成RGB
    45. print(path)
    46. img.save(path)#保存修改像素点后的图片
    47. print("finish!")

    如果想要看自己的图片像素值是不是0,1就直接print就可以啦

    3、修改数据集的均值和方差!!

    这点也很重要

    修改SegNeXt-main/configs/_base_/datasets里的myroad.py

    我的修改成了

    img_norm_cfg = dict(
        mean=[0.5947, 0.5815, 0.5625], std=[0.1173, 0.1169, 0.1157], to_rgb=True)

    需要计算一下图片的方差,因为这个值不对的话也还是跑不出来的

    到这一步 你就觉得可以成功跑起来了么

    如果这样想 那你就大错特错啦

    运行结果报错说

      File "/home/wangtianni/.conda/envs/pytorch/lib/python3.6/site-packages/torch/nn/functional.py", line 2248, in _verify_batch_size
        raise ValueError("Expected more than 1 value per channel when training, got input size {}".format(size))
    ValueError: Expected more than 1 value per channel when training, got input size torch.Size([1, 512, 1, 1])
     

    输入torchsize为[1,1,512,1]

    但是程序要求的是1个size

    我就很奇怪

    我明明已经把图片设置成了8位

    怎么还会报错

    看了半天后经过各种实验

    终于让我找到了解决思路:

    再次运行一遍步骤1!!!!

    4、再次运行步骤一的图片深度改变成8位的代码

    就可以正常运行啦!

  • 相关阅读:
    WSL-Ubuntu20.04训练环境配置
    java项目-第145期ssm汽车在线销售系统-java毕业设计_计算机毕业设计
    树控件、下拉框、文本框常用测试用例
    随时随地创建参数化3D模型—xDesign
    二硫化钼-石墨烯纳米复合材料(MoS2-rGO)|PEI修饰MoS2二硫化钼纳米材料|金纳米颗粒功能化二硫化钼(AuNPs@MoS2)
    ⽤nginx做负载均衡服务器,配置动静分离
    主流商业智能(BI)工具的比较(三):Qlik与Domo
    .NET 8使用日志功能以及自定义日志提供程序
    虚拟机Ubuntu20.04 网络连接器图标开机不显示怎么办
    【游戏引擎之路】登神长阶(七)——x86汇编学习:凡做难事,必有所得
  • 原文地址:https://blog.csdn.net/Laney_Midory/article/details/134089093