使用VisualDL可视化车道线分割模型训练过程

使用VisualDL可视化车道线分割模型训练过程

VisualDL 是一个面向深度学习任务设计的可视化工具。VisualDL 利用了丰富的图表来展示数据,用户可以更直观、清晰地查看数据的特征与变化趋势,有助于分析数据、及时发现错误,进而改进神经网络模型的设计。

目前,VisualDL 支持 scalar, image, audio, graph, histogram, pr curve, high dimensional 七个组件,项目正处于高速迭代中,敬请期待新组件的加入。

本次项目使用scalar,image和graph进行可视化分析。

github首页:https://github.com/PaddlePaddle/VisualDL

官网:https://www.paddlepaddle.org.cn/paddle/visualdl

aistudio项目:https://aistudio.baidu.com/aistudio/projectdetail/502834

https://aistudio.baidu.com/aistudio/projectdetail/622772

aistudio论坛:https://ai.baidu.com/forum/topic/show/960053?pageNo=2

欢迎大家在GitHub上点赞~

项目简介

本文介绍使用fast_scnn模型进行车道线检测迁移学习的方法。

0.1 分割任务

利用提供的训练数据,设计一个车道线检测和分类模型,来检测测试数据中车道线的具体位置和类别。 样例示范:使用VisualDL可视化车道线分割模型训练过程

0.2 数据集描述

数据集包括x张手机拍摄的道路图片数据,并对这些图片数据标注了车道线的区域和类别,其中标注数据以灰度图的方式存储。

标注数据是与原图尺寸相同的单通道灰度图,其中背景像素的灰度值为0,不同类别的车道线像素分别为不同的灰度值,具体如下表所示:

车道线类型 灰度值 图例
单线-虚线-白 1 使用VisualDL可视化车道线分割模型训练过程
单线-虚线-黄 2 使用VisualDL可视化车道线分割模型训练过程
单线-实线-白 3 使用VisualDL可视化车道线分割模型训练过程
单线-实线-黄 4 使用VisualDL可视化车道线分割模型训练过程
双线-虚线-白 5 使用VisualDL可视化车道线分割模型训练过程
双线-虚线-黄 6 使用VisualDL可视化车道线分割模型训练过程
双线-实线-白 7 使用VisualDL可视化车道线分割模型训练过程
双线-实线-黄 8 使用VisualDL可视化车道线分割模型训练过程
双线-左虚右实 9 使用VisualDL可视化车道线分割模型训练过程
双线-左实右虚 10 使用VisualDL可视化车道线分割模型训练过程
四线-虚线(无栅栏) 11 使用VisualDL可视化车道线分割模型训练过程
四线-实线(无栅栏) 12 使用VisualDL可视化车道线分割模型训练过程
有栅栏-全压线/无线 13 使用VisualDL可视化车道线分割模型训练过程
有栅栏-伸出来实线 14 使用VisualDL可视化车道线分割模型训练过程
有栅栏-伸出来虚线 15 使用VisualDL可视化车道线分割模型训练过程
有栅栏-伸出来左虚右实 16 使用VisualDL可视化车道线分割模型训练过程
有栅栏-伸出来左实右虚 17 使用VisualDL可视化车道线分割模型训练过程
有栅栏-空白 18 使用VisualDL可视化车道线分割模型训练过程
减速线 19 使用VisualDL可视化车道线分割模型训练过程

标注样例数据如下:

原始数据 标注数据(灰度值放大20倍)
使用VisualDL可视化车道线分割模型训练过程 使用VisualDL可视化车道线分割模型训练过程

0.3 评审规则

采用 mIoU 来评估结果。对于每一类,利用预测图像和真值图像,mIoU 可以计算如下:

使用VisualDL可视化车道线分割模型训练过程

其中,C是分类数,在本任务中就是车道线的类别数,TP, FP 和TN 表示true positive, false positive and false negative。详细的计算信息请参考 Cityscapes 数据集的评估方法。

1. 下载PaddleSeg

In [1]:

!git clone https://gitee.com/paddlepaddle/PaddleSeg.git

In [7]:

!pip install -r requirements.txt

2. 解压数据集

In [9]:

!mkdir ./dataset/road

In [10]:

!unzip ./data/data57561/lab_train.zip -d ./dataset/road/
!unzip ./data/data57561/img_train.zip -d ./dataset/road/
!unzip ./data/data57561/img_testA.zip -d ./dataset/road/
  inflating: ./dataset/road/test/10007282.jpg  

将./dataset/road/路径下的test改为testA

3. 数据处理

通过观察,发现这些数据有一个共同的特点,就是图片的上2分之一部分都是天空,是没有车道线存在的,知道了这点后,我们就可以进行一个裁剪的过程,一下子就可以节省下2分之一的显存。

In [11]:

from PIL import Image
def crop_data(input_path,output_path):
    img = Image.open(input_path)
    print(img.size)
    # 裁剪掉图片的上半部分
    cropped = img.crop((0, (img.height/2), img.width, img.height))  # (left, upper, right, lower)
    print(cropped.size)
    cropped.save(output_path)

In [12]:

import numpy as np
import os

base = './dataset/road/'

with open('dataset/road/labels.txt', 'w') as f:
    for i in range(20):
        f.write(str(i)+'\n')

imgs = os.listdir(base+'train_pic/')
np.random.seed(42)
np.random.shuffle(imgs)
val_num = int(0.1 * len(imgs))

with open(os.path.join('dataset/road/train_list.txt'), 'w') as f:
    for pt in imgs[:-val_num]:
        img = 'train_pic/'+pt
        ann = 'train_label/'+pt.replace('.jpg', '.png')
        info = img + ' ' + ann + '\n'
        crop_data(os.path.join(base,img), os.path.join(base,img))
        crop_data(os.path.join(base,ann), os.path.join(base,ann))
        f.write(info)

with open(os.path.join('dataset/road/val_list.txt'), 'w') as f:
    for pt in imgs[-val_num:]:
        img = 'train_pic/'+pt
        ann = 'train_label/'+pt.replace('.jpg', '.png')
        info = img + ' ' + ann + '\n'
        crop_data(os.path.join(base,img), os.path.join(base,img))
        crop_data(os.path.join(base,ann), os.path.join(base,ann))
        f.write(info)

with open(os.path.join('dataset/road/test_list.txt'), 'w') as f:
    for pt in os.listdir(base+'test_pic/'):
        img = 'testA/'+pt
        ann = 'test_tag/'+pt.replace('.jpg', '.png')
        info = img + ' ' + ann + '\n'
        f.write(info)
(1280, 360)

4. 开始训练

4.1 注意事项

训练时需要注意,默认PaddleSeg v0.6在Paddlepaddle 1.8.4的框架版本下paddle.enable_static()这句代码会报错,解决办法就是将pdseg/train.py中这行代码注释掉;后面pdseg/vis.pypdseg/eval.py也需要进行相同操作。

if __name__ == '__main__':
    # paddle.enable_static()
    args = parse_args()
    if fluid.core.is_compiled_with_cuda() != True and args.use_gpu == True:
        print(
            "You can not set use_gpu = True in the model because you are using paddlepaddle-cpu."
        )
        print(
            "Please: 1. Install paddlepaddle-gpu to run your models on GPU or 2. Set use_gpu=False to run models on CPU."
        )
        sys.exit(1)
    main(args)

4.3 fast_scnn模型finetune

这里参考文档的DeepLabv3+模型使用教程进行设置,参考config文件如下

EVAL_CROP_SIZE: (1920, 1080) # (width, height), for unpadding rangescaling and stepscaling
TRAIN_CROP_SIZE: (1920, 540) # (width, height), for unpadding rangescaling and stepscaling
AUG:
    AUG_METHOD: "stepscaling" # choice unpadding rangescaling and stepscaling
    FIX_RESIZE_SIZE: (640, 640) # (width, height), for unpadding
    INF_RESIZE_VALUE: 500  # for rangescaling
    MAX_RESIZE_VALUE: 600  # for rangescaling
    MIN_RESIZE_VALUE: 400  # for rangescaling
    MAX_SCALE_FACTOR: 2.0  # for stepscaling
    MIN_SCALE_FACTOR: 0.5  # for stepscaling
    SCALE_STEP_SIZE: 0.25  # for stepscaling
    MIRROR: True
    FLIP: False
    FLIP_RATIO: 0.2
    RICH_CROP:
        ENABLE: True
        ASPECT_RATIO: 0.0
        BLUR: False
        BLUR_RATIO: 0.1
        MAX_ROTATION: 0
        MIN_AREA_RATIO: 0.0
        BRIGHTNESS_JITTER_RATIO: 0.4
        CONTRAST_JITTER_RATIO: 0.4
        SATURATION_JITTER_RATIO: 0.4
BATCH_SIZE: 16
MEAN: [0.5, 0.5, 0.5]
STD: [0.5, 0.5, 0.5]
DATASET:
    DATA_DIR: "./dataset/road/"
    IMAGE_TYPE: "rgb"  # choice rgb or rgba
    NUM_CLASSES: 20
    TEST_FILE_LIST: "dataset/road/val_list.txt"
    TRAIN_FILE_LIST: "dataset/road/train_list.txt"
    VAL_FILE_LIST: "dataset/road/val_list.txt"
    VIS_FILE_LIST: "dataset/road/val_list.txt"
    IGNORE_INDEX: 255
FREEZE:
    MODEL_FILENAME: "model"
    PARAMS_FILENAME: "params"
MODEL:
    DEFAULT_NORM_TYPE: "bn"
    MODEL_NAME: "fast_scnn"

TEST:
    TEST_MODEL: "snapshots/cityscape_fast_scnn/1/"
TRAIN:
    PRETRAINED_MODEL_DIR: "./pretrained_model/fast_scnn_cityscapes"
    MODEL_SAVE_DIR: "snapshots/cityscape_fast_scnn/"
    SNAPSHOT_EPOCH: 10
SOLVER:
    LR: 0.001
    LR_POLICY: "poly"
    OPTIMIZER: "sgd"
    NUM_EPOCHS: 100
    LOSS: ["lovasz_softmax_loss","softmax_loss"]
    LOSS_WEIGHT:
        LOVASZ_SOFTMAX_LOSS: 0.2
        SOFTMAX_LOSS: 0.8
    CROSS_ENTROPY_WEIGHT: [0.1, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]

In [14]:

# 下载预训练模型
!python pretrained_model/download_model.py fast_scnn_cityscapes
Downloading fast_scnn_cityscape.tar
[==================================================] 100.00%
Uncompress fast_scnn_cityscape.tar
[==================================================] 100.00%
Pretrained Model download success!

如果只是体验一下VisualDL的功能,建议将训练集设置的小一点,否则模型生成的太慢,image模块显示的图片太多加载的也很慢。

In [16]:

# 指定GPU卡号(以0号卡为例)
!export CUDA_VISIBLE_DEVICES=0
# 训练
!python pdseg/train.py --use_gpu --cfg ./configs/cityscape_fast_scnn.yaml --use_vdl --vdl_log_dir vdl_log_dir
Save model checkpoint to snapshots/cityscape_fast_scnn/final

用VisualDL进行可视化分析

在可视化模块中配置logdir路径为./vdl_log_dir 可对训练过程进行监控 模型训练时生成日志和模型文件,按照下面的步骤就可以在aistudio上使用VisualDL进行可视化。

使用VisualDL可视化车道线分割模型训练过程

使用VisualDL可视化车道线分割模型训练过程

按照上面操作完成后就可以点击启动VisualDL服务了(不建议使用360极速浏览器,因为它不显示可视化信息。)

训练过程可视化

在可视化模块中配置logdir路径为PaddleSeg/vdl_log_dir可对训练过程进行监控使用VisualDL可视化车道线分割模型训练过程

scalar功能

使用VisualDL可视化车道线分割模型训练过程

上图中的横坐标代表loss纵坐标代表step.通过scala可以很明显的看到loss是否在下降与下降的速度,这样很方便我们做相应参数的调整。

image功能

使用VisualDL可视化车道线分割模型训练过程

image功能显示了训练过程中用到的样本数据

graph功能

使用VisualDL可视化车道线分割模型训练过程

VisualDL相关资料

github首页:https://github.com/PaddlePaddle/VisualDL

官网:https://www.paddlepaddle.org.cn/paddle/visualdl

aistudio项目:https://aistudio.baidu.com/aistudio/projectdetail/502834

https://aistudio.baidu.com/aistudio/projectdetail/622772

aistudio论坛:https://ai.baidu.com/forum/topic/show/960053?pageNo=2

欢迎大家在GitHub上点赞~