README.md 7.9 KB
Newer Older
E
Exception-star 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
# [Dual Attention Network for Scene Segmentation (CVPR2019)](https://arxiv.org/pdf/1809.02983.pdf)

本项目是[DANet](https://arxiv.org/pdf/1809.02983.pdf)的 PaddlePaddle(>=1.5.2) 实现, 包含模型训练,验证等内容。

## 模型简介
![net](img/Network.png)
骨干网络使用ResNet,为更好地进行语义分割任务,作者对ResNet做出以下改动:

    1、将最后两个layer的downsampling取消,使得特征图是原图的1/8,保持较高空间分辨率。
    2、最后两个layer采用空洞卷积扩大感受野。
然后接上两个并行的注意力模块(位置注意力和通道注意力),最终将两个模块的结果进行elementwise操作,之后再接一层卷积输出分割图。

### 位置注意力

![position](img/position.png)

A是骨干网络ResNet输出经过一层卷积生成的特征图,维度为CHW;
A经过3个卷积操作输出维度均为CHW的B、C、D。将B、C、D都reshape到CN(N = H*W);
然后将B reshape后的结果转置与C相乘,得到N * N的矩阵, 对于矩阵的每一个点进行softmax;
然后将D与softmax后的结果相乘并reshape到CHW,再与A进行elementwise。

### 通道注意力
![channel](img/channel.png)


A是骨干网络ResNet输出经过一层卷积生成的特征图,维度为CHW;
A经过3个reshape操作输出维度均为CN(N = H*W)的B、C、D;
然后将B转置与C相乘,得到C * C的矩阵,对于矩阵的每一个点进行softmax;
然后将D与softmax后的结果相乘并reshape到CHW,再与A进行elementwise。



## 数据准备

公开数据集:Cityscapes

训练集2975张,验证集500张,测试集1525张,图片分辨率都是1024*2048。

数据集来源:AIstudio数据集页面上[下载](https://aistudio.baidu.com/aistudio/datasetDetail/11503),  cityscapes.zip解压至dataset文件夹下,train.zip解压缩到cityscapes/leftImg8bit,其目录结构如下:
```text
dataset
  ├── cityscapes               # Cityscapes数据集
         ├── gtFine            # 精细化标注的label
         ├── leftImg8bit       # 训练,验证,测试图片
         ├── trainLabels.txt   # 训练图片路径
         ├── valLabels.txt     # 验证图片路径
              ...               ...
```
## 训练说明

#### 数据增强策略
    1、随机尺度缩放:尺度范围0.75到2.0
    2、随机左右翻转:发生概率0.5
    3、同比例缩放:缩放的大小由选项1决定。
    4、随机裁剪:
    5、高斯模糊:发生概率0.3(可选)
    6、颜色抖动,对比度,锐度,亮度; 发生概率0.3(可选)
###### 默认1、2、3、4、5、6都开启

#### 学习率调节策略
    1、使用热身策略,学习率由0递增到base_lr,热身轮数(epoch)是5
    2、在热身策略之后使用学习率衰减策略(poly),学习率由base_lr递减到0

#### 优化器选择
	Momentum: 动量0.9,正则化系数1e-4

#### 加载预训练模型
	设置 --load_pretrained_model(默认为False)
	预训练文件:
	    checkpoint/DANet50_pretrained_model_paddle1.6.pdparams
        checkpoint/DANet101_pretrained_model_paddle1.6.pdparams

#### 加载训练好的模型
	设置 --load_better_model(默认为False)
	训练好的文件:
		checkpoint/DANet101_better_model_paddle1.6.pdparams
##### 【注】
    训练时paddle版本是1.5.2,代码已转为1.6版本(兼容1.6版本),预训练参数、训练好的参数来自1.5.2版本

#### 配置模型文件路径
[预训练参数、最优模型参数下载](https://paddlemodels.bj.bcebos.com/DANet/DANet_models.tar)

其目录结构如下:
```text
checkpoint
    ├── DANet50_pretrained_model_paddle1.6.pdparams       # DANet50预训练模型,需要paddle >=1.6.0
    ├── DANet101_pretrained_model_paddle1.6.pdparams      # DANet101预训练模型,需要paddle >=1.6.0
    ├── DANet101_better_model_paddle1.6.pdparams          # DANet101训练最优模型,需要paddle >=1.6.0
    ├── DANet101_better_model_paddle1.5.2                 # DANet101在1.5.2版本训练的最优模型,需要paddle >= 1.5.2

```

## 模型训练

```sh
cd danet
export PYTHONPATH=`pwd`:$PYTHONPATH
# open garbage collection to save memory
export FLAGS_eager_delete_tensor_gb=0.0
# setting visible devices for train
export CUDA_VISIBLE_DEVICES=0,1,2,3
```

executor执行以下命令进行训练
```sh
python train_executor.py --backbone resnet101 --base_size 1024 --crop_size 768 --epoch_num 350 --batch_size 2 --lr 0.003 --lr_scheduler poly --warm_up --warmup_epoch 2 --cuda --use_data_parallel --load_pretrained_model --save_model checkpoint/DANet101_better_model_paddle1.5.2 --multi_scales --flip --dilated --multi_grid --scale --multi_dilation 4 8 16
```
参数含义: 使用ResNet101骨干网络,训练图片基础大小是1024,裁剪大小是768,训练轮数是350次,batch size是2
学习率是0.003,学习率衰减策略是poly,使用学习率热身,热身轮数是2轮,使用GPU,使用数据并行, 加载预训练模型,设置加载的模型地址,使用多尺度测试, 使用图片左右翻转测试,使用空洞卷积,使用multi_grid,multi_dilation设置为4 8 16,使用多尺度训练
##### Windows下训练需要去掉 --use_data_parallel
#### 或者
dygraph执行以下命令进行训练
```sh
python train_dygraph.py --backbone resnet101 --base_size 1024 --crop_size 768 --epoch_num 350 --batch_size 2 --lr 0.003 --lr_scheduler poly --cuda --use_data_parallel --load_pretrained_model --save_model checkpoint/DANet101_better_model_paddle1.6 --multi_scales --flip --dilated --multi_grid --scale --multi_dilation 4 8 16
```
参数含义: 使用ResNet101骨干网络,训练图片基础大小是1024,裁剪大小是768,训练轮数是350次,batch size是2,学习率是0.003,学习率衰减策略是poly,使用GPU, 使用数据并行,加载预训练模型,设置加载的模型地址,使用多尺度测试,使用图片左右翻转测试,使用空洞卷积,使用multi_grid,multi_dilation设置4 8 16,使用多尺度训练

#### 【注】
##### train_executor.py使用executor方式训练(适合paddle >= 1.5.2),train_dygraph.py使用动态图方式训练(适合paddle >= 1.6.0),两种方式都可以
##### 动态图方式训练暂时不支持学习率热身

#### 在训练阶段,输出的验证结果不是真实的,需要使用eval.py来获得验证的最终结果。

 ## 模型验证
```sh
# open garbage collection to save memory
export FLAGS_eager_delete_tensor_gb=0.0
# setting visible devices for prediction
export CUDA_VISIBLE_DEVICES=0

python eval.py --backbone resnet101 --base_size 2048 --crop_size 1024 --cuda --use_data_parallel --load_better_model --save_model checkpoint/DANet101_better_model_paddle1.6 --multi_scales --flip --dilated --multi_grid --multi_dilation 4 8 16
```
##### 如果需要把executor训练的参数转成dygraph模式下进行验证的话,请在命令行加上--change_executor_to_dygraph

## 验证结果
评测指标:mean IOU(平均交并比)


| 模型 | 单尺度 | 多尺度 |
| :---:|:---:| :---:|
|DANet101|0.8043836|0.8138021

##### 具体数值
| 模型 | cls1 | cls2 | cls3 | cls4 | cls5 | cls6 | cls7 | cls8 | cls9 | cls10 | cls11 | cls12 | cls13 | cls14 | cls15 | cls16 |cls17 | cls18 | cls19 |
| :---:|:---: | :---:| :---:|:---: | :---:| :---:|:---: | :---:| :---:|:---:  |:---: |:---:  |:---:  | :---: | :---: |:---:  | :---:| :---: |:---:  |
|DANet101-SS|0.98212|0.85372|0.92799|0.59976|0.63318|0.65819|0.72023|0.80000|0.92605|0.65788|0.94841|0.83377|0.65206|0.95566|0.87148|0.91233|0.84352|0.71948|0.78737|
|DANet101-MS|0.98047|0.84637|0.93084|0.62699|0.64839|0.67769|0.73650|0.81343|0.92942|0.67010|0.95127|0.84466|0.66635|0.95749|0.87755|0.92370|0.85344|0.73007|0.79742|

## 输出结果可视化
![val_1](img/val_1.png)
###### 输入图片
![val_gt](img/val_gt.png)
###### 图片label
![val_output](img/val_output.png)
###### DANet101模型输出