【工程测试与训练】使用BiSeNetv2测试,训练cityscapes数据集,训练自己的数据集

1 准备工作

下载工程

  • 工程下载:https://github.com/CoinCheung/BiSeNet
  • 预训练模型下载:
  • 工程下载后解压,并在其中创建文件夹【MODEL】用于存放预训练模型

  • 本人的开发环境:

    ubuntu 18.04、cuda10.2、cudnn7、python3.7、pytorch 1.8.1
    工程运行过程中,会报错找不到库,pip安装对应的库即可

    2 运行demo

  • 使用 【bisenetv2_city】测试图片:
    python tools/demo.py --config configs/bisenetv2_city.py --weight-path ./MDOEL/model_final_v2_city.pth --img-path ./example.png
    会保存结果为【res.jpg】
  • 使用【bisenetv2_coco】测试视频:
    python tools/demo_video.py --config configs/bisenetv2_coco.py --weight-path ./MODEL/model_final_v2_coco.pth --input ./video.mp4 --output res.mp4
    会保存结果为【res.mp4】,展示的结果是从视频中截取的效果,所以彩色图和预测图片效果不对应,间隔了少量的帧数
  • 3 训练cityscapes数据集


    3.1 下载数据集并解压

    官网链接:https://www.cityscapes-dataset.com/,下载数据需要注册,且账号有一定的要求。登录后进行数据下载:


    然后剪切置合适的路径,一般来说,建议将【数据集文件】【工程文件】放置同级路径,不要将 数据集文件 从属于 工程文件。方便多个工程都能很好的使用数据集。

    然后进行解压,(命令运行解压速度很快)运行

    unzip leftImg8bit_trainvaltest.zip
    unzip gtFine_trainvaltest.zip
    

    遵守该工程调用数据路径,我们需要在工程路径下的【./datasets/cityscapes】下创建个软连接。进入该路径运行

    ln -s ../../../cityscapes/leftImg8bit leftImg8bit
    ln -s ../../../cityscapes/gtFine gtFine
    


    3.2 训练BiSeNetv2-cityscapes

    源码提供的pytorch的分布式训练,而我们常有的是单机单卡、或单机多卡。

    export CUDA_VISIBLE_DEVICES=0,1
    python -m torch.distributed.launch --nproc_per_node=2 tools/train_amp.py --config configs/bisenetv2_city.py
    
    export CUDA_VISIBLE_DEVICES=0
    python -m torch.distributed.launch --nproc_per_node=1 tools/train_amp.py --config configs/bisenetv2_city.py
    

    上面的命令和官网提供的命令是一样的效果

    4 训练自己的数据集


    4.1 数据标注

    使用 【labelme】进行标注,语义标注的使用记录在 labelme标注软件的使用 || 语义分割数据标注、批量转换、多类别转换颜色错位问题


    4.2 数据路径布局

    标注完数据,编写脚本处理数据路径。结果如下图所示

    三个路径下的图片为:

    这里需要注意:
    中间的图片其实是单通道的,使用 【label = np.array(Image.open(file))】能够正确读取像素值。
    使用【label = cv2.imread(file, 0)】读取的像素值,并不是我们标注的标签。
    但工程中使用的是opencv,为了尽可能少的修改源码,这里需要将【label_pil】里的数据使用 Image.open 进行读取,然后使用 cv2.imwrite 进行保存。

    【label】文件夹下存放的图片效果如下图所示


    4.3 生成train.txt、val.txt

    【./tools/gen_coco_annos.py】的功能,就是生成 COCO 数据集的train.txt等,我们需要针对我们的数据集来生成 自己数据集的 train.txt
    创建文件【./tools/gen_SW_annos.py】,内容如下:

    import os
    import random
    
    def gen_SW():
    
       data_path = '../Sweeper/data_v1/data'      # 需要修改为自己的路径
       label_path = '../Sweeper/data_v1/label'     # 需要修改为自己的路径
       save_path = "datasets/sweeper/"                  # 
       os.makedirs(save_path) if not os.path.exists(save_path) else None
       
       ftrain = open(os.path.join(save_path,"train.txt"),"w")
       fval = open(os.path.join(save_path,"val.txt"),"w")
       ftest = open(os.path.join(save_path,"test.txt"),"w")
    
       files = os.listdir(data_path)
       random.shuffle(files)
    
       count = -1
       for file in files:
           count += 1
           im_root = os.path.join(data_path, file)
           lb_root = os.path.join(label_path, file)
    
           ftrain.writelines(im_root+","+lb_root+"\n") if count<8000 else None           # 修改自己的数据量的划分
           fval.writelines(im_root+","+lb_root+"\n") if 8000<count<8600 else None       # 修改自己的数据量的划分
           ftest.writelines(im_root+","+lb_root+"\n") if 8600<count else None             # 修改自己的数据量的划分
    
       ftrain.close()
       fval.close()
       ftest.close()
    
    gen_SW()
    

    4.4 源码修改

    【./configs/bisenetv2_city.py】

    ## bisenetv2
    # cfg = dict(
    #     model_type='bisenetv2',
    #     n_cats=19,
    #     num_aux_heads=4,
    #     lr_start=5e-3,
    #     weight_decay=5e-4,
    #     warmup_iters=1000,
    #     max_iter=150000,
    #     dataset='CityScapes',
    #     im_root='./datasets/cityscapes',
    #     train_im_anns='./datasets/cityscapes/train.txt',
    #     val_im_anns='./datasets/cityscapes/val.txt',
    #     scales=[0.25, 2.],
    #     cropsize=[512, 1024],
    #     eval_crop=[1024, 1024],
    #     eval_scales=[0.5, 0.75, 1.0, 1.25, 1.5, 1.75],
    #     ims_per_gpu=8,
    #     eval_ims_per_gpu=2,
    #     use_fp16=True,
    #     use_sync_bn=True,
    #     respth='./res',
    # )
    
    cfg = dict(
       model_type='bisenetv2',
       n_cats=19,           # 修改
       num_aux_heads=4,
       lr_start=5e-3,
       weight_decay=5e-4,
       warmup_iters=1000,
       max_iter=150000,
       dataset='CityScapes',
       im_root='./',
       train_im_anns='./datasets/sweeper/train.txt',    # 修改
       val_im_anns='./datasets/sweeper/val.txt',        # 修改
       scales=[0.25, 2.],
       cropsize=[384, 640],         # 修改
       eval_crop=[384, 640],        # 修改
       eval_scales=[0.5, 0.75, 1.0, 1.25, 1.5, 1.75],
       ims_per_gpu=8,
       eval_ims_per_gpu=2,
       use_fp16=True,
       use_sync_bn=True,
       respth='./res',
    )
    
    


    【./lib/cityscapes_cv2.py】

    1 修改自己数据集合的类别数量,无需加1。
    2 注释代码上图第二个红框。
    一般的我们的标签都是从0开始按顺序标注,不需要标签序号的重映射,注释掉即可。如果需要重新映射标签,仿照变量 labels_info 改写即可。
    3 统计自己数据集的均值与方差,然后用结果替换代码中的 mean、std

    import cv2
    import numpy as np
    
    file_name = "./datasets/sweeper/train.txt"
    with open(file_name,"r") as f:
       files = f.readlines()
       files = [file[:-1].split(",") for file in files]
    # print(files)
    
    MEAN = []
    STD = []
    for file in files:
       img = cv2.imread(file[0])[:,:,::-1]/255.0
       MEAN.append(np.mean(img, axis=(0,1)))
       STD.append(np.std(img, axis=(0,1)))
    
    MEAN = np.array(MEAN)
    STD = np.array(STD)
    print(MEAN.shape)
    print(STD.shape)
    MEAN = np.mean(MEAN,axis=0)
    STD = np.mean(STD,axis=0)
    print(MEAN)
    print(STD)
    

    4.5 训练与评估

    因为上面有偷懒,直接在 cityscapes 的相关脚本上进行修改,所以训练cityscapes 运行命令与前面一致

  • 单机单卡
    export CUDA_VISIBLE_DEVICES=0,1
    python -m torch.distributed.launch --nproc_per_node=2 tools/train_amp.py --config configs/bisenetv2_city.py
  • 单机多卡
    export CUDA_VISIBLE_DEVICES=0
    python -m torch.distributed.launch --nproc_per_node=1 tools/train_amp.py --config configs/bisenetv2_city.py
  • 模型评估
    python tools/evaluate.py --config configs/bisenetv2_city.py --weight-path ./res/model_tmp.pth
  • 物联沃分享整理
    物联沃-IOTWORD物联网 » 【工程测试与训练】使用BiSeNetv2测试,训练cityscapes数据集,训练自己的数据集

    发表评论