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

1 准备工作

下载工程

  • 工程下载:https://github.com/CoinCheung/BiSeNet
  • 预训练模型下载:
    【工程测试与训练】使用BiSeNetv2测试、训练cityscapes数据集、训练自己的数据集_第1张图片
  • 工程下载后解压,并在其中创建文件夹【MODEL】用于存放预训练模型
    【工程测试与训练】使用BiSeNetv2测试、训练cityscapes数据集、训练自己的数据集_第2张图片

本人的开发环境:

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测试、训练cityscapes数据集、训练自己的数据集_第3张图片
  • 使用【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】,展示的结果是从视频中截取的效果,所以彩色图和预测图片效果不对应,间隔了少量的帧数【工程测试与训练】使用BiSeNetv2测试、训练cityscapes数据集、训练自己的数据集_第4张图片

3 训练cityscapes数据集


3.1 下载数据集并解压

官网链接:https://www.cityscapes-dataset.com/,下载数据需要注册,且账号有一定的要求。登录后进行数据下载:
【工程测试与训练】使用BiSeNetv2测试、训练cityscapes数据集、训练自己的数据集_第5张图片
【工程测试与训练】使用BiSeNetv2测试、训练cityscapes数据集、训练自己的数据集_第6张图片
然后剪切置合适的路径,一般来说,建议将【数据集文件】【工程文件】放置同级路径,不要将 数据集文件 从属于 工程文件。方便多个工程都能很好的使用数据集。
【工程测试与训练】使用BiSeNetv2测试、训练cityscapes数据集、训练自己的数据集_第7张图片
然后进行解压,(命令运行解压速度很快)运行

unzip leftImg8bit_trainvaltest.zip
unzip gtFine_trainvaltest.zip

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

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

【工程测试与训练】使用BiSeNetv2测试、训练cityscapes数据集、训练自己的数据集_第8张图片


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 数据路径布局

标注完数据,编写脚本处理数据路径。结果如下图所示
【工程测试与训练】使用BiSeNetv2测试、训练cityscapes数据集、训练自己的数据集_第9张图片
三个路径下的图片为:
【工程测试与训练】使用BiSeNetv2测试、训练cityscapes数据集、训练自己的数据集_第10张图片
这里需要注意:
中间的图片其实是单通道的,使用 【label = np.array(Image.open(file))】能够正确读取像素值。
使用【label = cv2.imread(file, 0)】读取的像素值,并不是我们标注的标签。
但工程中使用的是opencv,为了尽可能少的修改源码,这里需要将【label_pil】里的数据使用 Image.open 进行读取,然后使用 cv2.imwrite 进行保存。
【工程测试与训练】使用BiSeNetv2测试、训练cityscapes数据集、训练自己的数据集_第11张图片
【label】文件夹下存放的图片效果如下图所示
【工程测试与训练】使用BiSeNetv2测试、训练cityscapes数据集、训练自己的数据集_第12张图片


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】
【工程测试与训练】使用BiSeNetv2测试、训练cityscapes数据集、训练自己的数据集_第13张图片
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
    【工程测试与训练】使用BiSeNetv2测试、训练cityscapes数据集、训练自己的数据集_第14张图片

你可能感兴趣的:(2D实时语义分割,工程配置,深度学习,python)