一、第十七届全国大学生智能汽车竞赛:完全模型组线上资格赛

比赛地址:https://aistudio.baidu.com/aistudio/competition/detail/131/0/task-definition

1.比赛简介

车辆的普及和人们对出行体验的重视,对地图导航提出了更高的要求。基于车载影像的AR导航系统能够精准快速的识别车道线、行驶区域,不仅能够辅助驾驶系统进行高效的决策,同时结合终端渲染与语音技术,也能够为用户带来更为智能精准的导航体验。

作为『新一代人工智能地图』的百度地图,秉承着『用科技让出行更简单』的使命,借助于图像识别、语音识别、大数据处理等人工智能技术,大幅提升地图数据采集和处理的自动化程度,实现道路覆盖超过1000万公里,已成为业内AI化水平最高、搭载的AI技术最强最丰富的地图数据厂商。本次比赛数据由百度地图提供,要求在统一的计算资源下,能够对车载影像中实车道线、虚车道线和斑马线等区域进行快速精准的识别。

本次竞赛的题目和数据由百度地图数据引擎部提供,模型和基线相关技术支持由深度学习技术平台部提供,一站式AI开发平台AI Studio由百度AI技术生态部提供。期待参赛者们能够以此为契机,共同推进智能交通领域的发展。

2.比赛任务

要求参赛者利用提供的训练数据,在统一的计算资源下,实现一个能够识别虚车道线、实车道线和斑马线具体位置和类别的深度学习模型,不限制深度学习任务。 样例示范:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LiuLLf53-1642855745311)(http://bj.bcebos.com/v1/ai-studio-match/file/21b27164efa64b3bb2f5efed6d956730fc61e11be86849f1ae35ab44c4ba580d?authorization=bce-auth-v1%2F0ef6765c1e494918bc0d4c3ca3e5c6d1%2F2022-01-14T08%3A09%3A49Z%2F-1%2F%2F8b281f827158c1dcf0873706ca47286209ceee2e9c3935906876a9a226c9d68c)]

3.比赛数据

数据集描述
本届赛题数据集包括16000张可以直接用于训练的车载影像数据,官方采用分割连通域标注方法,对这些图片数据标注了虚车道线、实车道线和斑马线的区域和类别,其中标注数据以灰度图的方式存储。 标注数据是与原图尺寸相同的单通道灰度图,其中背景像素的灰度值为0,不同类别的目标像素分别为不同的灰度值。实车道线、虚车道线和斑马线类别编号分别为1、2和3。选手报名之后,可在「数据集介绍」tab中下载数据集。

图像与标注数据依文件名编号对应,组织结构如下:

| -- train
| | -- image
| | |-- 00001.jpg
| | |-- …
| | |-- 08000.jpg
| | -- label
| | |-- 00001.png
| | |-- …
| | | -- 08000.png 

需注意的是,灰度值较低仅影响肉眼可见性,并不影响深度学习训练。如需要观测标注图像,可以将其拉伸至0~255的RGB图像。

4.提交要求

本次比赛要求选手使用飞桨PaddlePaddle2.1及以上版本生成端到端深度学习模型。

选手需上传训练模型、预测代码及环境库(可选)的zip形式压缩包到AI Studio平台进行自动评测。其中,预测代码需命名为predict.py,model目录不超过200M(不压缩),整体压缩包不超过1G,目录结构约定如下:

| -- model
| | -- xxx.pb
| | … 
| -- env
| | -- xxx.lib
| |…
| -- predict.py
| -- …

二、环境准备

此次计划用PaddleSeg动态图API模式,让大家好用看得见。具体文档见https://github.com/PaddlePaddle/PaddleSeg/tree/develop/docs/apis

!pip install -U pip 
!pip install -U paddleseg 

三、数据准备

1.数据解压缩

!unzip -qoa data/data125511/软件杯_data_2022.zip -d data

2.数据查看

!ls data/软件杯_data_2022/ -l 
!head data/软件杯_data_2022/train_list.txt
!head data/软件杯_data_2022/val_list.txt
from PIL import Image
img=Image.open('data/软件杯_data_2022/JPEGImages/07535.jpg')
print(img.size)
img=img.resize((600,400))
img
from PIL import Image
import numpy as np


img=Image.open('data/软件杯_data_2022/Annotations/07535.png')
print(img.size)
img=np.array(img)
img=Image.fromarray(img.astype('uint8'))
img=img.resize((600,400))
img
!wc -l data/软件杯_data_2022/train_list.txt  data/软件杯_data_2022/val_list.txt

可见训练集12800,测试集3200,总计16000

import cv2, os
import numpy as np

#amount of classer
CLASSES_NUM = 15

#find imagee in folder dir
def findImages(dir,topdown=True):
    im_list = []
    if not os.path.exists(dir):
        print("Path for {} not exist!".format(dir))
        raise
    else:
        for root, dirs, files in os.walk(dir, topdown):
            for fl in files:
                im_list.append(fl)
    return im_list

# amount of images corresponding to each classes
images_count = [0]*CLASSES_NUM
# amount of pixels corresponding to each class
class_pixels_count = [0]*CLASSES_NUM
# amount of pixels corresponding to the images of each class
image_pixels_count = [0]*CLASSES_NUM

image_folder = './data/软件杯_data_2022/Annotations'
im_list = findImages(image_folder) 

for im in im_list:
    print(im)
    cv_img = cv2.imread(os.path.join(image_folder, im), cv2.IMREAD_UNCHANGED)
    size_img = cv_img.shape
    colors = set([])
    for i in range(size_img[0]):
        for j in range(size_img[1]):
            p_value = cv_img.item(i,j)
            if not p_value < CLASSES_NUM: # check
                print(p_value)
            else:
                class_pixels_count[p_value] = class_pixels_count[p_value] + 1
                colors.add(p_value)
    im_size = size_img[0]*size_img[1]
    for n in range(CLASSES_NUM):
        if n in colors:
            images_count[n] = images_count[n] + 1
            image_pixels_count[n] = image_pixels_count[n] + im_size

print(images_count)
print(class_pixels_count)
print(image_pixels_count)

3.构建训练集

import paddleseg.transforms as T
from paddleseg.datasets import Dataset
dir(T)
['Compose',
 'Image',
 'LimitLong',
 'Normalize',
 'Padding',
 'PaddingByAspectRatio',
 'RandomAffine',
 'RandomBlur',
 'RandomDistort',
 'RandomHorizontalFlip',
 'RandomNoise',
 'RandomPaddingCrop',
 'RandomRotation',
 'RandomScaleAspect',
 'RandomVerticalFlip',
 'Resize',
 'ResizeByLong',
 'ResizeByShort',
 'ResizeRangeScaling',
 'ResizeStepScaling',
 'ScalePadding',
 '__builtins__',
 '__cached__',
 '__doc__',
 '__file__',
 '__loader__',
 '__name__',
 '__package__',
 '__path__',
 '__spec__',
 'cv2',
 'functional',
 'manager',
 'math',
 'np',
 'random',
 'transforms']
help(Dataset)
# 构建训练用的transforms

transforms = [
    T.Resize(target_size=(512, 512)),
    T.RandomHorizontalFlip(),
    T.RandomNoise(),
    T.RandomBlur(),
    T.Normalize()
]

# 构建训练集

train_dataset = Dataset(
    dataset_root='data/软件杯_data_2022/',
    train_path='data/软件杯_data_2022/train_list.txt',
    transforms=transforms,
    num_classes=4,
    mode='train'
)

4.构建验证集

# 构建训练用的transforms

transforms = [
    T.Resize(target_size=(512, 512)),
    T.Normalize()
]

# 构建训练集

val_dataset = Dataset(
    dataset_root='data/软件杯_data_2022/',
    val_path='data/软件杯_data_2022/val_list.txt',
    transforms=transforms,
    num_classes=4,
    mode='val'
)

四、模型训练

import paddleseg.models as M
dir(M)

1.模型配置

基于 PaddlePaddle 实现的 BiSeNet V2。 BiSeNetV2
原文请参考:
Yu, Changqian, et al. “BiSeNet V2: Bilateral Network with Guided Aggregation for Real-time Semantic Segmentation”

参数

  • num_classes (int): 相互独立的目标类别的数量。
  • lambd (float, optional): 控制语义分支通道大小的因素。默认:0.25
  • pretrained (str, optional): 预训练模型的url或path。 默认:None
help(M.BiSeNetV2)
model = M.BiSeNetV2(num_classes=4,
                 lambd=0.25,
                 align_corners=False,
                 pretrained=None)

2.构建优化器

import paddle
# 设置学习率
base_lr = 0.01
lr = paddle.optimizer.lr.PolynomialDecay(base_lr, power=0.9, decay_steps=1000, end_lr=0)

optimizer = paddle.optimizer.Momentum(lr, parameters=model.parameters(), momentum=0.9, weight_decay=4.0e-5)

3. 构建损失函数

为了适应多路损失,损失函数应构建成包含’types’和’coef’的dict,如下所示。 其中losses[‘type’]表示损失函数类型, losses[‘coef’]为对应的系数。需注意len(losses[‘types’])应等于len(losses[‘coef’])。


from paddleseg.models.losses import CrossEntropyLoss
losses = {}
losses['types'] = [CrossEntropyLoss()] * 5
losses['coef'] = [1]* 5

4…训练

from paddleseg.core import train
help(train)
train(
    model=model,
    train_dataset=train_dataset,
    val_dataset=val_dataset,
    optimizer=optimizer,
    save_dir='output',
    iters=2000,
    batch_size=86, 
    save_interval=200,
    log_iters=10,
    num_workers=0,
    losses=losses,
    use_vdl=True)

五、模型评估

# 加载模型
model_path = 'output/best_model/model.pdparams'
if model_path:
    para_state_dict = paddle.load(model_path)
    model.set_dict(para_state_dict)
    print('Loaded trained params of model successfully')
else: 
    raise ValueError('The model_path is wrong: {}'.format(model_path))
from paddleseg.core import evaluate
help(evaluate)
evaluate(
        model,
eg.core import evaluate
help(evaluate)
evaluate(
        model,
        val_dataset)
Logo

学大模型,用大模型上飞桨星河社区!每天8点V100G算力免费领!免费领取ERNIE 4.0 100w Token >>>

更多推荐