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

本文档详细介绍了如何使用BiSeNetv2模型进行语义分割,包括下载工程和预训练模型、运行demo、训练Cityscapes数据集以及训练自定义数据集的全过程。涉及的内容包括环境配置、数据准备、源码修改、训练与评估等关键步骤,适合希望使用BiSeNetv2进行语义分割任务的开发者参考。
摘要由CSDN通过智能技术生成

1 准备工作

下载工程
本人的开发环境:

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 ./MODEL/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
    在这里插入图片描述
下面是使用 BiSeNet V2 实现图像分割的一个简单示例: 1. 首先,需要准备数据集。可以使用常见的图像分割数据集,如 Cityscapes、PASCAL VOC、ADE20K 等。 2. 然后,需要下载 BiSeNet V2 的预训练模型。可以从官方 Github 仓库下载,链接为 https://github.com/CoinCheung/BiSeNet/tree/v2。 3. 接下来,需要对数据集进行预处理。可以使用常见的图像预处理方法,如裁剪、缩放、旋转、翻转等。此外,还需要将标签图像转换为 one-hot 编码。 4. 然后,需要加载预训练模型,并根据需要进行微调。可以使用 PyTorch 或 TensorFlow 等深度学习框架来实现。 5. 最后,可以使用模型对测试图像进行分割,并将分割结果保存为图像。 下面是一个简单的 Python 代码示例,展示了如何使用 BiSeNet V2 实现图像分割: ```python import torch import torchvision.transforms as transforms from PIL import Image import numpy as np # 加载预训练模型 model = torch.load('path/to/bisenetv2.pt') # 图像预处理 transform = transforms.Compose([ transforms.Resize((512, 512)), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ]) # 加载测试图像 image = Image.open('path/to/test_image.jpg') image = transform(image) image = image.unsqueeze(0) # 模型推理 with torch.no_grad(): output = model(image) # 将输出转为 Numpy 数组 output = output.squeeze(0).cpu().numpy() output = np.argmax(output, axis=0) # 将输出保存为图像 output = Image.fromarray(output.astype(np.uint8)) output.save('path/to/output.png') ``` 需要注意的是,上述代码示例仅供参考,实际应用中可能需要根据具体情况进行修改。此外,还需要对数据集、模型参数等进行调整和优化,以实现更好的分割效果。
评论 54
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值