基于U-HRNet模型的高分辨率语义分割

   日期:2023-09-03     浏览:3    

1. 项目说明

  本示例是基于 PaddlSeg 2.1 版本实现的 U-HRNet,并提供了基于 ImageNet 数据集的 W18-small 和 W48 版本的预训练模型,并在 Cityscapes 数据集进行了训练。

 

图 1 - 车辆检测模型效果

方案难点: 在地面要素分割、人像分割、医学图像分割等对分割精度要求比较高的分割场景下,往往存在一些细长或者较小的待分割元素,由于这些元素前景占比较非常小,因此想要达到比较高的分割精度,就要探索如何在维持高分辨率特征的前提下,近一��增强低分辨率的语义信息,以及高低分辨率特征之间的信息交互。

应用场景:

  • 地图要素分割

  • 人像分割

  • 医学图像分割

  • 其他适合 U 型高分辨语义分割网络的应用场景

2. 安装说明

2.1 环境要求

  • PaddlePaddle 2.2.2

  • Python 3(3.5.1+/3.6/3.7/3.8/3.9)

  • CUDA >= 10.1

  • cuDNN >= 7.6

2.2 解压数据及代码

项目代码在 PaddleSeg.tar 文件中,数据集在 cityscapes.tar 文件中,解压到合适路径即可使用。# 如果希望解压到其他目录
#可选择其他路径(默认 /home/aistudio )
%cd ~
! unzip -qo ~/data/data141439/PaddleSeg.zip
! rm -rf __MACOSX
%cd ~/PaddleSeg
! mkdir data &&
tar xf ~/data/data141439/cityscapes.tar -C data

3. 数据准备

该项目提供 cityscapes 数据集,且上方代码已将其解压到 PaddleSeg 目录下,直接使用即可。

3.1 数据介绍

本案例使用的公开数据集 Cityscapes,共 5000 张精标注数据,其中训练集 2975 张,验证集 500 张,1525 张测试集。数据集展示如下图:

图 2 - 部分 Cityscapes 数据展示

3.2 数据结构

首先我们看一下文档树结构

cityscapes
├── gtFine
│   ├── test
│   ├── train
│   └── val
├── infer.list
├── leftImg8bit
│   ├── test
│   ├── train
│   └── val
├── test.list
├── train.list
├── trainval.list
└── val.list

leftImg8bit 已经对 image 进行了划分,分为 train、val、test 文件夹。

train文件夹总共包含18个城市,为在全球选择的18个城市街景图片。

下图为 aachen 文件夹中包含的街景图片。命名规则是,第一部分设定是该文件夹的名字,第二部分是对应的第几张图片,第三/四部分固定是 000019 和 leftImg8bit.png。

图 3 - 随机选取的一张街景图片

gtFine 和 leftImg8bit 相同,分为三个文件夹,分别是 train、val、test。同样的,train 文件夹包含 18 个类,为相应的标签图片。

还是以 aachen 文件夹为例

aachen_000000_000019_gtFine_color.png                       可视化的分割图
aachen_000000_000019_gtFine_instaceIds.png                  实例分割标注文件
aachen_000000_000019_gtFine_labelIds.png                    语义分割标注文件
aachen_000000_000019_gtFine_labelTrainIds.png               语义分割标注文件
aachen_000000_000019_gtFine_polygons.json                   存储的是各个类和相应的区域
                                                            (用多边形顶点的位��表示区域的边界)

4. 模型选择

在 HRNet 中( HRNet 基于 PaddleSeg2.1 的训练和推理具体教程可参考 PaddleSeg全流程跑通 ),维持高分辨 feature map(1/4)的传播,有比较大的计算量,但是这部分语义信息相对较少,并且针对 1/32 低分辨率,具有更丰富语义信息的 feature map,没有更充分的利用。因此,我们基于这两点,通过

1)删减高分辨率 featue map 支路的计算量

2)增加对低分辨率语义信息的利用,以及高低分辨率信息的交互设计了 U 型高分辨率语义分割网络 UHRNet,并基于 PaddleSeg2.1 进行开发。

UHRNet 对于包含更多语义信息的低分辨率 feature map 进行更充分的利用,对于计算量非常大,但是包含语义信息相对较少的高分辨率 feature map 进行适当的简化,在保证计算量基本不变的情况,达到了更高的分割精度。

图 4 - 模型对比如图

图 5 - UHRNet效果如图

模型优化效果对比:


HRNet-W48U-HRNet-W48U-HRNet-W18-small
mIoU0.81560.82060.7886
Acc-0.96770.9642
Kappa-0.95810.9536

如对模型性能有要求,可以采用 U-HRNet-W18-small

5. 模型训练

训练被拆分成了针对 U-HRNet-W48U-HRNet-W18-small 的两种方案。同时我们也提供了基于 ocr head 的训练配置,分数还会进一步上涨。

U-HRNet-W18-small:
模型位置: output_w18_4_gpus_120k/best_model
mIoU: mIoU: 0.7886 Acc: 0.9642 Kappa: 0.9536 
Class IoU: [0.9843 0.868  0.9312 0.6085 0.6496 0.6806 0.7141 0.7916 0.9295 0.6752 0.9516 0.8232 0.6275 0.9533 0.8042 0.8559 0.7366 0.6296 0.7693]
Class Acc: [0.9931 0.9257 0.9613 0.8223 0.7997 0.8289 0.8296 0.9068 0.9595 0.8469 0.9713 0.8988 0.7623 0.9731 0.9276 0.9282 0.878  0.8117 0.8631]

U-HRNet-W48:
模型位置: output_w48_4_gpus_120k/best_model
mIoU: 0.8206 Acc: 0.9677 Kappa: 0.9581 
Class IoU: [0.9855 0.8824 0.9373 0.6497 0.6827 0.7154 0.7584 0.8277 0.9317 0.6794 0.9545 0.8474 0.6691 0.9599 0.861  0.9099 0.8631 0.6784 0.7984]
Class Acc: [0.993  0.9353 0.9669 0.8325 0.8434 0.8459 0.85   0.9186 0.9598 0.8376 0.9746 0.915  0.7899 0.9781 0.9423 0.9666 0.9425 0.8163 0.8813]

这里以 U-HRNet-W18-small 为例。首先,在启动模型训练之前,可以修改配置文件中相关内容, 包括显卡使用数量、预训练模型路径、模型输出路径。对应到配置文件中的位置如下所示:

U-HRNet-W18-small
// 项目基础配置配置,包括数据增强、路径、优化器等信息
_base_: 	'../_base_/cityscapes.yml'

batch_size: 	3
iters: 		120000

model:
  type: 	FCN
  backbone:
    type: 		UHRNet_W18_Small_V2
    align_corners: 	False
    // 预训练模型
    pretrained: 	pretrained_model/uhrnetw18_small_v2_imagenet/model.pdparams
  num_classes: 		19
  pretrained: 		Null
  backbone_indices: 	[-1]

optimizer:
  weight_decay: 0.0005

项目中涉及多个配置文件信息,它们分别为

  • train.py

  • configs/fcn/fcn_uhrnetw18_small_v2_cityscapes_1024x512_120k.yml

  • configs/_base_/cityscapes.yml

还有一些其他的训练时配置诸如 save_intervalnum_workerslog_iters 等,可以在 train.py 文件中调整。# U-HRNet-W18-small
! bash train_w18_4gpus.sh# U-HRNet-W48
! bash train_w48_4gpus.sh

6. 模型评估

评估默认配置:configs/fcn/fcn_uhrnetw48_cityscapes_1024x512_120k.yml。

具体配置可以到 yml 文件中查看,这里提供简单内容展���。

_base_: '../_base_/cityscapes.yml'

// 批大小
batch_size: 3
// 迭代次数
iters: 120000

model:
  // 网络类型
  type: FCN
  // 主干网络
  backbone:
    type: UHRNet_W18_Small_V2
    align_corners: False
    // 预训练模型
    pretrained: pretrained_model/uhrnetw18_small_v2_imagenet/model.pdparams
  num_classes: 19
  pretrained: Null
  backbone_indices: [-1]

optimizer:
  weight_decay: 0.0005
```! bash eval.sh评估结果如下:

**W18-small 版本**

Images: 500 mIoU: 0.7886 Acc: 0.9642 Kappa: 0.9536
Class IoU:
[0.9843 0.868  0.9312 0.6085 0.6496 0.6806 0.7141 0.7916 0.9295 0.6752
0.9516 0.8232 0.6275 0.9533 0.8042 0.8559 0.7366 0.6296 0.7693]
Class Acc:
[0.9931 0.9257 0.9613 0.8223 0.7997 0.8289 0.8296 0.9068 0.9595 0.8469
0.9713 0.8988 0.7623 0.9731 0.9276 0.9282 0.878  0.8117 0.8631]

**W48 版本**

Images: 500 mIoU: 0.8206 Acc: 0.9677 Kappa: 0.9581
Class IoU:
[0.9855 0.8824 0.9373 0.6497 0.6827 0.7154 0.7584 0.8276 0.9317 0.6794
0.9545 0.8474 0.6691 0.9599 0.861 0.9099 0.8631 0.6784 0.7984]
Class Acc:
[0.993  0.9353 0.9669 0.8325 0.8434 0.8459 0.85   0.9186 0.9598 0.8376
0.9746 0.915  0.7899 0.9781 0.9423 0.9666 0.9425 0.8164 0.8812]

7. 推理可视化

还是以 U-HRNet-W18-small 为例,我们选用训练时的数据集配置和得到的最优模型。输出路径默认为 output/result。! bash predict.sh



图 6 - 原始图片

 

图 7 - 推理结果

8. 模型导出

导出推理模型

PaddlePaddle框架保存的权重文件分为两种:支持前向推理和反向梯度的训练模型 和 只支持前向推理的推理模型。二者的区别是推理模型针对推理速度和显存做了优化,裁剪了一些只在训练过程中才需要的tensor,降低显存占用,并进行了一些类似层融合,kernel选择的速度优化。因此可执行如下命令导出推理模型。

默认导出到 freezed_models 目录。! bash export_model.sh关于 PaddleSeg 的更多细节,可参考 PaddleSeg 全流程跑通

9. 模型部署

使用飞桨原生推理库paddle-inference,用于服务端模型部署

总体上分为三步:

  1. 创建PaddlePredictor,设置所导出的模型路径

  2. 创建输入用的 PaddleTensor,传入到 PaddlePredictor 中

  3. 获取输出的 PaddleTensor ,将结果取出

#include "paddle_inference_api.h"
 // 创建一个 config,并修改相关设置paddle::NativeConfig config;
config.model_dir = "xxx";
config.use_gpu = false;// 创建一个原生的 PaddlePredictorauto predictor =
      paddle::CreatePaddlePredictor<paddle::NativeConfig>(config);// 创建输入 tensorint64_t data[4] = {1, 2, 3, 4};
paddle::PaddleTensor tensor;
tensor.shape = std::vector<int>({4, 1});
tensor.data.Reset(data, sizeof(data));
tensor.dtype = paddle::PaddleDType::INT64;// 创建输出 tensor,输出 tensor 的内存可以复用std::vector<paddle::PaddleTensor> outputs;// 执行预测CHECK(predictor->Run(slots, &outputs));// 获取 outputs ...

更多内容详见 > C++ 预测 API介绍


 
 
更多>同类产业范例库

推荐产业范例库
点击排行

北京人工智能高质量数据集服务平台

创新数据服务,积极推进数据拓展应用

关于我们

联系我们