基于深度学习的无人驾驶道路检测

2023-10-31

 

最近在自学深度学习,网上有很多计算机视觉比赛和资源,比如kaggle,天池 ,百度飞浆,paddle现在做得越来越好,于是我就选择了百度飞浆,支持国产开源框架,也自己跑通了代码,以此记录一下学习过程,若有纰漏,恳请各位大佬多多指点。

目录

一、配置好 paddle的GPU环境  

二、从官网下载好数据集图片

三、下载好源码,并把项目导入到 Pycharm

1.process_labels.py文件

 2.make_lists.py和data_feeder文件

 make_lists.py文件的一些提醒:

3.val_inference.py文件

4.train.py文件

5.ensemble.py文件 


一、配置好 paddle的GPU环境  

参考以下链接安装好环境 

飞浆安装教程

温馨提醒:

  1. 最好用conda安装,由于本人当时安装的环境是win7+cuda 9.0的环境,安装过程也遇到不少坑,当时安装过程有些截图没及时保存,所以大家自行查找一下,网上有很多教程,问题不大。   
  2. 配置cuda+cudnn,根据自己电脑显卡的配置信息来安装,一般情况下电脑是cuda9.2,去英伟达官网安装cuda 9.0+对应的cudnn版本都可以兼容,以此类推
  3. 如果下载英伟达驱动安装包,网速很慢,建议不要用无线,用有线下载,之前被坑了一次

二、从官网下载好数据集图片

无人车车道线检测挑战赛

数据集分为训练集 +测试集,大概有5万多张图片 ,文件还是蛮大哦!

三、下载好源码,并把项目导入到 Pycharm

代码参考以下链接:百度无人车车道线检测源码,里面有仔细的说明与代码结构图,但是接下来的补充是我运行过程的一些理解 

1.process_labels.py文件

这个标签图是把图片中不同物体类别进行分类 ,ignoreInEval的含义是否可以忽略,True置为0(归为背景),False置为1,原本是0-8个属性 ID(catid )一共9类,仔细分析catid=4时,ignoreInEval=True,所以这个属性可以忽略,所以就剩下8个类别。

这个程序是涉及到one-hot编码,具体的原理可以自行查一下。本程序其实可以弄一个数组+一个for循环赋值,这样可以简洁一些,当然这些是每个人编写程序的风格不一样而已。

"""
Description: Encode & Decode Labels for Lane Segmentation Competition
NOTE: For 8 classes
"""
import numpy as np

def encode_labels(color_mask):
    encode_mask = np.zeros((color_mask.shape[0], color_mask.shape[1]))
    # 0
    encode_mask[color_mask == 0] = 0
    encode_mask[color_mask == 249] = 0
    encode_mask[color_mask == 255] = 0
    # 1
    encode_mask[color_mask == 200] = 1
    encode_mask[color_mask == 204] = 1
    encode_mask[color_mask == 213] = 0
    encode_mask[color_mask == 209] = 1
    encode_mask[color_mask == 206] = 0
    encode_mask[color_mask == 207] = 0
    # 2
    encode_mask[color_mask == 201] = 2
    encode_mask[color_mask == 203] = 2
    encode_mask[color_mask == 211] = 0
    encode_mask[color_mask == 208] = 0
    # 3
    encode_mask[color_mask == 216] = 0
    encode_mask[color_mask == 217] = 3
    encode_mask[color_mask == 215] = 0

    # 4 In the test, it will be ignored
    encode_mask[color_mask == 218] = 0
    encode_mask[color_mask == 219] = 0

    # 4
    encode_mask[color_mask == 210] = 4
    encode_mask[color_mask == 232] = 0
    # 5
    encode_mask[color_mask == 214] = 5
    # 6
    encode_mask[color_mask == 202] = 0
    encode_mask[color_mask == 220] = 6
    encode_mask[color_mask == 221] = 6
    encode_mask[color_mask == 222] = 6
    encode_mask[color_mask == 231] = 0
    encode_mask[color_mask == 224] = 6
    encode_mask[color_mask == 225] = 6
    encode_mask[color_mask == 226] = 6
    encode_mask[color_mask == 230] = 0
    encode_mask[color_mask == 228] = 0
    encode_mask[color_mask == 229] = 0
    encode_mask[color_mask == 233] = 0
    # 7
    encode_mask[color_mask == 205] = 7
    encode_mask[color_mask == 212] = 0
    encode_mask[color_mask == 227] = 7
    encode_mask[color_mask == 223] = 0
    encode_mask[color_mask == 250] = 7

    return encode_mask

#看代码要独立思考,注意跳坑(id<---对应--->trainid )
def decode_labels(labels):
    deocde_mask = np.zeros((labels.shape[0], labels.shape[1]), dtype='uint8')
    # 0
    deocde_mask[labels == 0] = 0
    # 1
    deocde_mask[labels == 1] = 204
    # 2
    deocde_mask[labels == 2] = 203
    # 3
    deocde_mask[labels == 3] = 217
    # 4
    deocde_mask[labels == 4] = 210
    # 5
    deocde_mask[labels == 5] = 214
    # 6
    deocde_mask[labels == 6] = 224
    # 7
    deocde_mask[labels == 7] = 227

    return deocde_mask

def decode_color_labels(labels):
    decode_mask = np.zeros((3, labels.shape[0], labels.shape[1]), dtype='uint8')
    # 0
    decode_mask[0][labels == 0] = 0
    decode_mask[1][labels == 0] = 0
    decode_mask[2][labels == 0] = 0
    # 1
    decode_mask[0][labels == 1] = 70
    decode_mask[1][labels == 1] = 130
    decode_mask[2][labels == 1] = 180
    # 2
    decode_mask[0][labels == 2] = 0
    decode_mask[1][labels == 2] = 0
    decode_mask[2][labels == 2] = 142
    # 3
    decode_mask[0][labels == 3] = 153
    decode_mask[1][labels == 3] = 153
    decode_mask[2][labels == 3] = 153
    # 4
    decode_mask[0][labels == 4] = 128
    decode_mask[1][labels == 4] = 64
    decode_mask[2][labels == 4] = 128
    # 5
    decode_mask[0][labels == 5] = 190
    decode_mask[1][labels == 5] = 153
    decode_mask[2][labels == 5] = 153
    # 6
    decode_mask[0][labels == 6] = 0
    decode_mask[1][labels == 6] = 0
    decode_mask[2][labels == 6] = 230
    # 7
    decode_mask[0][labels == 7] = 255
    decode_mask[1][labels == 7] = 128
    decode_mask[2][labels == 7] = 0

    return decode_mask


#统计Label的类别
def verify_labels(labels):
    pixels = [0]
    for x in range(labels.shape[0]):
        for y in range(labels.shape[1]):
            pixel = labels[x, y]
            if pixel not in pixels:
                pixels.append(pixel)
    print('The Labels Has Value:', pixels)

 2.make_lists.py和data_feeder文件

我在代码文件添加了一些注释,辅助理解

# Description: Make Data Lists for Lane Segmentation Competition(csv文件只保存图像文件位置和对应关系)

import os
import pandas as pd  #csv文件的创建和读取
from sklearn.utils import shuffle #打散数据
import shutil   #文件复制删除等操作
import numpy as np
import cv2  #建议没有必要使用cv2,例如PIL

#怎样引入本地文件?模块名严格对应路径和文件名(不要py后缀)
from utils.process_labels import encode_labels, decode_color_labels


#================================================
# make train & validation lists
#================================================
label_list = []
image_list = []

#根据自己的路径修改,用绝对路径
#制作train.csv
# image_dir = 'E:/PaddleXinstallation/data/chusai_data/Image_Data/'
# label_dir = 'E:/PaddleXinstallation/data/chusai_data/Gray_Label/'

#制作val.csv
image_dir = 'E:/PaddleXinstallation/data/chusai_data/Val_Data/'
label_dir = 'E:/PaddleXinstallation/data/chusai_data/Gray_Label/'


# image_dir = '/home/gujingxiao/projects/PaddlePaddle/Image_Data/'
# label_dir = '/home/gujingxiao/projects/PaddlePaddle/Gray_Label/'


#同步遍历image和label两个目录,建立对应关系
# os.path.join(path1[,path2[,......]]) 返回值:将多个路径组合后返回
#os.listdir()描述:返回指定路径下的文件和文件夹列表
# lower() 返回将字符串中所有大写字符转换为小写后生成的字符串

for s1 in os.listdir(image_dir):
    image_sub_dir1 = os.path.join(image_dir, s1)
    label_sub_dir1 = os.path.join(label_dir, 'Label_' + str.lower(s1), 'Label')
    # print(image_sub_dir1, label_sub_dir1)

    for s2 in os.listdir(image_sub_dir1):
        image_sub_dir2 = os.path.join(image_sub_dir1, s2)
        label_sub_dir2 = os.path.join(label_sub_dir1, s2)
        # print(image_sub_dir2, label_sub_dir2)

        for s3 in os.listdir(image_sub_dir2):
            image_sub_dir3 = os.path.join(image_sub_dir2, s3)
            label_sub_dir3 = os.path.join(label_sub_dir2, s3)
            # print(image_sub_dir3, label_sub_dir3)

            for s4 in os.listdir(image_sub_dir3):
                s44 = s4.replace('.jpg','_bin.png')#生成label文件名
                image_sub_dir4 = os.path.join(image_sub_dir3, s4)
                label_sub_dir4 = os.path.join(label_sub_dir3, s44)
                if not os.path.exists(image_sub_dir4):
                    print(image_sub_dir4)
                if not os.path.exists(label_sub_dir4):
                    print(label_sub_dir4)
                # print(image_sub_dir4, label_sub_dir4)
                image_list.append(image_sub_dir4)
                label_list.append(label_sub_dir4)
print(len(image_list), len(label_list))

save = pd.DataFrame({'image':image_list, 'label':label_list})  #生成CSV文件格式
save_shuffle = shuffle(save)     #打散数据

#制作train.csv
#save_shuffle.to_csv('E:/PaddleXinstallation/data/Lane-Segmentation-Solution-For-BaiduAI-Autonomous-Driving-Competition-master/data_list/train.csv', index=False)


#制作val.csv
#save_shuffle.to_csv('../data_list/train.csv', index=False)
save_shuffle.to_csv('E:/PaddleXinstallation/data/Lane-Segmentation-Solution-For-BaiduAI-Autonomous-Driving-Competition-master/data_list/val.csv', index=False)

# Description: Data Generator for Lane Segmentation Competition

import os
import cv2
import numpy as np
from paddle.fluid import core
from utils.process_labels import encode_labels, verify_labels
from utils.image_process import crop_resize_data, crop_val_resize_data

# Feed Data into Tensor
def get_feeder_data(data, place, for_test=False):
    feed_dict = {}
    image_t = core.LoDTensor()
    image_t.set(data[0], place)
    feed_dict["image"] = image_t

    # if not test, feed label also
    # Otherwise, only feed image
    if not for_test:
        labels_t = core.LoDTensor()
        labels_t.set(data[1], place)
        feed_dict["label"] = labels_t

    return feed_dict

# Train Images Generator
def train_image_gen(train_list, batch_size=4, image_size=[1024, 384], crop_offset=690):
    # Arrange all indexes
    all_batches_index = np.arange(0, len(train_list))
    out_images = []
    out_masks = []
    image_dir = np.array(train_list['image'])
    label_dir = np.array(train_list['label'])
    while True:
        # Random shuffle indexes every epoch
        np.random.shuffle(all_batches_index)  #数据打散
        for index in all_batches_index:  #动态生成数据,读取数据
            if os.path.exists(image_dir[index]):
                ori_image = cv2.imread(image_dir[index])
                ori_mask = cv2.imread(label_dir[index], cv2.IMREAD_GRAYSCALE)
                # Crop the top part of the image
                # Resize to train size
                train_img, train_mask = crop_resize_data(ori_image, ori_mask, image_size, crop_offset)
                # Encode
                train_mask = encode_labels(train_mask)

                # verify_labels(train_mask)
                out_images.append(train_img)
                out_masks.append(train_mask)
                if len(out_images) >= batch_size:
                    out_images = np.array(out_images)
                    out_masks = np.array(out_masks)
                    out_images = out_images[:, :, :, ::-1].transpose(0, 3, 1, 2).astype(np.float32) / (255.0 / 2) - 1
                    out_masks = out_masks.astype(np.int64)
                    yield out_images, out_masks
                    out_images, out_masks = [], []
            else:
                print(image_dir, 'does not exist.')

# Validation Images Generator
def val_image_gen(val_list, batch_size=4, image_size=[1024, 384], crop_offset=690):
    all_batches_index = np.arange(0, len(val_list))

    out_images = []
    out_masks = []
    image_dir = np.array(val_list['image'])
    label_dir = np.array(val_list['label'])
    while True:
        np.random.shuffle(all_batches_index)
        for index in all_batches_index:
            if os.path.exists(image_dir[index]):
                ori_image = cv2.imread(image_dir[index])
                ori_mask = cv2.imread(label_dir[index], cv2.IMREAD_GRAYSCALE)
                val_img, val_mask = crop_val_resize_data(ori_image, ori_mask, image_size, crop_offset)
                val_mask = encode_labels(val_mask)
                out_images.append(val_img)
                out_masks.append(val_mask)
                if len(out_images) >= batch_size:
                    out_images = np.array(out_images)
                    out_masks = np.array(out_masks)
                    out_images = out_images[:, :, :, ::-1].transpose(0, 3, 1, 2).astype(np.float32) / (255.0 / 2) - 1
                    out_masks = out_masks.astype(np.int64)
                    yield out_images, out_masks
                    out_images, out_masks = [], []
            else:
                print(image_dir, 'does not exist.')

 make_lists.py文件的一些提醒:

3.val_inference.py文件

# Description: Val & Inference Code for Lane Segmentation Competition

import cv2
import sys
import os
import time

import paddle
import pandas as pd
import numpy as np
import paddle.fluid as fluid

from utils.process_labels import decode_color_labels
from utils.image_process import crop_resize_data, expand_resize_data
from utils.data_feeder import get_feeder_data, val_image_gen
from models.unet_base import unet_base
from models.unet_simple import unet_simple
from models.deeplabv3p import deeplabv3p

paddle.enable_static()

def mean_iou(pred, label, num_classes):
    pred = fluid.layers.argmax(pred, axis=1)
    pred = fluid.layers.cast(pred, 'int32')
    label = fluid.layers.cast(label, 'int32')
    miou, wrong, correct = fluid.layers.mean_iou(pred, label, num_classes)
    return miou

no_grad_set = []
def create_loss(predict, label, num_classes):
    predict = fluid.layers.transpose(predict, perm=[0, 2, 3, 1])
    predict = fluid.layers.reshape(predict, shape=[-1, num_classes])
    predict = fluid.layers.softmax(predict)
    label = fluid.layers.reshape(label, shape=[-1, 1])
    bce_loss = fluid.layers.cross_entropy(predict, label)
    no_grad_set.append(label.name)
    loss = bce_loss
    miou = mean_iou(predict, label, num_classes)
    return fluid.layers.reduce_mean(loss), miou

def create_network(train_image, train_label, classes, network='unet_simple', image_size=(1024, 384), for_test=False):
    if network == 'unet_base':
        predict = unet_base(train_image, classes, image_size)
    elif network == 'unet_simple':
        predict = unet_simple(train_image, classes, image_size)
    elif network == 'deeplabv3p':
        predict = deeplabv3p(train_image, classes)
    else:
        raise Exception('Not support this model:', network)
    print('The program will run', network)

    if for_test == False:
        loss, miou = create_loss(predict, train_label, classes)
        return loss, miou, predict
    elif for_test == True:
        return predict
    else:
        raise Exception('Wrong Status:', for_test)


# The main method
def main():
    IMG_SIZE =[1536, 512]
    SUBMISSION_SIZE = [3384, 1710]
#当False时,仅保存单模型预测结果的png;如果是True,将会保存单模型预测结果的npy文件,用于最终ensemble使用
    #save_test_logits = False
    save_test_logits = True

    num_classes = 8
    batch_size = 4
    log_iters = 100
    #network = 'unet_simple'
    network ='deeplabv3p'

    # Define paths for each model
    if network == 'deeplabv3p':
        #model_path = "./model_weights/paddle_deeplabv3p_8_end_060223"
        #npy_dir = '/npy_save/deeplabv3p/'
        model_path = "E:/PaddleXinstallation/data/Lane-Segmentation-Solution-For-BaiduAI-Autonomous-Driving-Competition-master/model_weights/paddle_deeplabv3p_8_end_060223"
        npy_dir = 'E:/PaddleXinstallation/data/Lane-Segmentation-Solution-For-BaiduAI-Autonomous-Driving-Competition-master/npy_save/deeplabv3p/'

    elif network == 'unet_base':
        # model_path = "./model_weights/paddle_unet_base_10_end_059909"
        # npy_dir = '/npy_save/unet_base/'
        model_path = "E:/PaddleXinstallation/data/Lane-Segmentation-Solution-For-BaiduAI-Autonomous-Driving-Competition-master/model_weights/paddle_unet_base_0_2000"
        npy_dir = 'E:/PaddleXinstallation/data/Lane-Segmentation-Solution-For-BaiduAI-Autonomous-Driving-Competition-master/npy_save/unet_base/'

    elif network == 'unet_simple':
        # model_path = "./model_weights/paddle_unet_simple_12_end_060577"
        # npy_dir = '/npy_save/unet_simple/'
        model_path = "./model_weights/paddle_unet_simple_12_end_060577"
        npy_dir = 'E:/PaddleXinstallation/data/Lane-Segmentation-Solution-For-BaiduAI-Autonomous-Driving-Competition-master/npy_save/unet_simple/'

    program_choice = 2 # 1 - Validtion; 2 - Test
    show_label = False
    crop_offset = 690
    data_dir = 'E:/PaddleXinstallation/data/Lane-Segmentation-Solution-For-BaiduAI-Autonomous-Driving-Competition-master/data_list/val.csv'
    #data_dir = './data_list/val.csv'
    test_dir = 'E:/PaddleXinstallation/data/chusai_data/TestSet/ColorImage/'
    #test_dir = '../PaddlePaddle/TestSet_Final/ColorImage/'


    sub_dir = 'E:/PaddleXinstallation/data/Lane-Segmentation-Solution-For-BaiduAI-Autonomous-Driving-Competition-master/test_submission/'

    # Get data list and split it into train and validation set.
    val_list = pd.read_csv(data_dir)

    #Initialization
    images = fluid.layers.data(name='image', shape=[3, IMG_SIZE[1], IMG_SIZE[0]], dtype='float32')
    labels = fluid.layers.data(name='label', shape=[1, IMG_SIZE[1], IMG_SIZE[0]], dtype='float32')

    iter_id = 0
    total_loss = 0.0
    total_miou = 0.0
    prev_time = time.time()
    # Validation
    if program_choice == 1:
        val_reader = val_image_gen(val_list, batch_size=batch_size, image_size=IMG_SIZE, crop_offset=crop_offset)
        reduced_loss, miou, pred = create_network(images, labels, num_classes, network=network, image_size=(IMG_SIZE[1], IMG_SIZE[0]), for_test=False)
        place = fluid.CUDAPlace(0)
        exe = fluid.Executor(place)
        exe.run(fluid.default_startup_program())
        fluid.io.load_params(exe, model_path)
        print("loaded model from: %s" % model_path)

        # Parallel Executor to use multi-GPUs
        exec_strategy = fluid.ExecutionStrategy()
        exec_strategy.allow_op_delay = True
        build_strategy = fluid.BuildStrategy()
        build_strategy.reduce_strategy = fluid.BuildStrategy.ReduceStrategy.Reduce
        train_exe = fluid.ParallelExecutor(use_cuda=True, build_strategy=build_strategy, exec_strategy=exec_strategy)

        print('Start Validation!')
        for iteration in range(int(len(val_list) / batch_size)):
            val_data = next(val_reader)
            results = train_exe.run(
                feed=get_feeder_data(val_data, place),
                fetch_list=[reduced_loss.name, miou.name, pred.name])
            if iter_id % log_iters == 0:
                print('Finished Processing %d Images.' %(iter_id * batch_size))
            iter_id += 1
            total_loss += np.mean(results[0])
            total_miou += np.mean(results[1])
            # label to mask
            if show_label == True:
                label_image = val_data[1][0]
                color_label_mask = decode_color_labels(label_image)
                color_label_mask = np.transpose(color_label_mask, (1, 2, 0))
                cv2.imshow('gt_label', cv2.resize(color_label_mask, (IMG_SIZE[0], IMG_SIZE[1])))

                prediction = np.argmax(results[2][0], axis=0)
                color_pred_mask = decode_color_labels(prediction)
                color_pred_mask = np.transpose(color_pred_mask, (1, 2, 0))
                cv2.imshow('pred_label', cv2.resize(color_pred_mask, (IMG_SIZE[0], IMG_SIZE[1])))
                cv2.waitKey(0)

        end_time = time.time()
        print("validation loss: %.3f, mean iou: %.3f, time cost: %.3f s"
            % (total_loss / iter_id, total_miou / iter_id, end_time - prev_time))
    # Test
    elif program_choice == 2:
        predictions = create_network(images, labels, num_classes, network=network, image_size=(IMG_SIZE[1], IMG_SIZE[0]), for_test=True)
        place = fluid.CUDAPlace(0)
        # place = fluid.CPUPlace()
        exe = fluid.Executor(place)
        exe.run(fluid.default_startup_program())
        fluid.io.load_params(exe, model_path)
        print("loaded model from: %s" % model_path)

        print('Start Making Submissions!')
        test_list = os.listdir(test_dir)
        for test_name in test_list:
            test_ori_image = cv2.imread(os.path.join(test_dir, test_name))
            test_image = crop_resize_data(test_ori_image, label=None, image_size=IMG_SIZE, offset=crop_offset)
            out_image = np.expand_dims(np.array(test_image), axis=0)
            out_image = out_image[:, :, :, ::-1].transpose(0, 3, 1, 2).astype(np.float32) / (255.0 / 2) - 1

            feed_dict = {}
            feed_dict["image"] = out_image
            results_1 = exe.run(
                feed=feed_dict,
                fetch_list=[predictions])

            if iter_id % 20 == 0:
                print('Finished Processing %d Images.' %(iter_id))
            iter_id += 1
            prediction = np.argmax(results_1[0][0], axis=0)

            # Save npy files
            if save_test_logits == True:
                np.save(npy_dir + test_name.replace('.jpg', '.npy'), results_1[0][0])

            # Save Submission PNG
            submission_mask = expand_resize_data(prediction, SUBMISSION_SIZE, crop_offset)
            cv2.imwrite(os.path.join(sub_dir, test_name.replace('.jpg', '.png')), submission_mask)

            # Show Label
            if show_label == True:
                cv2.imshow('test_image', cv2.resize(test_ori_image,(IMG_SIZE[0], IMG_SIZE[1])))
                cv2.imshow('pred_label', cv2.resize(submission_mask,(IMG_SIZE[0], IMG_SIZE[1])))
                cv2.waitKey(0)
        sys.stdout.flush()

# Main
if __name__ == "__main__":
    main()

模型权重文件

4.train.py文件

PS:注意单卡与双卡训练的代码区别,我猜测作者运行的环境应该是在Ubuntu系统下运行的,因为作者说明了是用paddlepaddle-gpu 1.3.0.post97,就是paddle 1.3.0版本+cuda9.0+cudnn v7+双卡训练(paddle只有linux系统才支持双卡训练,Windows仅支持单卡训练)

  • 当然目前paddle已经更新到2.1了,可能有些语法上的不兼容之类的,自己根据实际报错来找答案
  • 此处labels的类型由float32改为int32目的是,当时是报了一个数据类型的错误,后面咨询了别人才知道修改
  • #labels = fluid.layers.data(name='label', shape=[1, IMG_SIZE[1], IMG_SIZE[0]], dtype='float32')
  •  

# Description: Train Code for Lane Segmentation Competition

import time

import paddle
import pandas as pd
import numpy as np
import paddle.fluid as fluid
import os

from utils.data_feeder import get_feeder_data, train_image_gen
from models.unet_base import unet_base
from models.unet_simple import unet_simple
from models.deeplabv3p import deeplabv3p

paddle.enable_static()
os.environ['CUDA_VISIBLE_DEVICES'] = '1,2' #以防GPU出问题


# Compute Mean Iou
def mean_iou(pred, label, num_classes=8):
    pred = fluid.layers.argmax(pred, axis=1)
    pred = fluid.layers.cast(pred, 'int32')
    label = fluid.layers.cast(label, 'int32')
    miou, wrong, correct = fluid.layers.mean_iou(pred, label, num_classes)
    return miou

# Get Loss Function
no_grad_set = []
def create_loss(predict, label, num_classes):
    predict = fluid.layers.transpose(predict, perm=[0, 2, 3, 1])
    predict = fluid.layers.reshape(predict, shape=[-1, num_classes])
    predict = fluid.layers.softmax(predict)
    label = fluid.layers.reshape(label, shape=[-1, 1])
    # BCE with DICE
    bce_loss = fluid.layers.cross_entropy(predict, label)
    dice_loss = fluid.layers.dice_loss(predict, label)
    no_grad_set.append(label.name)
    loss = bce_loss + dice_loss
    miou = mean_iou(predict, label, num_classes)
    return fluid.layers.reduce_mean(loss), miou

def create_network(train_image, train_label, classes, network='unet_simple', image_size=(1024, 384), for_test=False):
    if network == 'unet_base':
        predict = unet_base(train_image, classes, image_size)
    elif network == 'unet_simple':
        predict = unet_simple(train_image, classes, image_size)
    elif network == 'deeplabv3p':
        predict = deeplabv3p(train_image, classes)
    else:
        raise Exception('Not support this model:', network)
    print('The program will run', network)

    if for_test == False:
        loss, miou = create_loss(predict, train_label, classes)
        return loss, miou, predict
    elif for_test == True:
        return predict
    else:
        raise Exception('Wrong Status:', for_test)

# The main method
def main():
    IMG_SIZE =[1536, 512]
    SUBMISSION_SIZE = [3384, 1710]
    add_num = 13
    num_classes = 8
    #batch_size = 2 #双卡训练为偶数
    batch_size = 1
    log_iters = 100
    base_lr = 0.001
    #base_lr = 0.0006
    save_model_iters = 2000
    #use_pretrained = True
    use_pretrained = False
    #network = 'deeplabv3p'
    network = 'unet_base'
    save_model_path ="E:/PaddleXinstallation/data/Lane-Segmentation-Solution-For-BaiduAI-Autonomous-Driving-Competition-master/model_weights/paddle_" + network + "_"
    model_path ="E:/PaddleXinstallation/data/Lane-Segmentation-Solution-For-BaiduAI-Autonomous-Driving-Competition-master/models" + network + "_12_end"
    #save_model_path = "./model_weights/paddle_" + network + "_"
    #model_path = "./model_weights/paddle_" + network + "_12_end"
    epoches = 2
    crop_offset = 690
    data_dir = 'E:/PaddleXinstallation/data/Lane-Segmentation-Solution-For-BaiduAI-Autonomous-Driving-Competition-master/data_list/train.csv'


    # Get data list and split it into train and validation set.
    train_list = pd.read_csv(data_dir)

    #Initialization
    images = fluid.layers.data(name='image', shape=[3, IMG_SIZE[1], IMG_SIZE[0]], dtype='float32')
    labels = fluid.layers.data(name='label', shape=[1, IMG_SIZE[1], IMG_SIZE[0]], dtype='int32')
    #labels = fluid.layers.data(name='label', shape=[1, IMG_SIZE[1], IMG_SIZE[0]], dtype='float32')

    iter_id = 0
    total_loss = 0.0
    total_miou = 0.0
    prev_time = time.time()
    # Train
    print('Train Data Size:', len(train_list))
    train_reader = train_image_gen(train_list, batch_size, IMG_SIZE, crop_offset) #数据生成器
    # Create model and define optimizer
    reduced_loss, miou, pred = create_network(images, labels, num_classes, network=network, image_size=(IMG_SIZE[1], IMG_SIZE[0]), for_test=False)
    optimizer = fluid.optimizer.AdamOptimizer(learning_rate=base_lr)
    optimizer.minimize(reduced_loss, no_grad_set=no_grad_set)

    # Whether load pretrained model(单卡执行的程序)
    place = fluid.CUDAPlace(0)
    exe = fluid.Executor(place)
    exe.run(fluid.default_startup_program())
    if use_pretrained == True:
        fluid.io.load_params(exe, model_path)
        print("loaded model from: %s" % model_path)
    else:
        print("Train from initialized model.")

    # Parallel Executor to use multi-GPUs(这个是多卡执行的程序)
    #若是单卡训练,直接屏蔽掉以下程序
    # exec_strategy = fluid.ExecutionStrategy()
    # exec_strategy.allow_op_delay = True
    # build_strategy = fluid.BuildStrategy()
    # build_strategy.reduce_strategy = fluid.BuildStrategy.ReduceStrategy.Reduce
    # train_exe = fluid.ParallelExecutor(use_cuda=True, loss_name=reduced_loss.name,
    #                                    build_strategy=build_strategy, exec_strategy=exec_strategy)

    # Training
    for epoch in range(epoches):
        print('Start Training Epoch: %d'%(epoch + 1))
        train_length = len(train_list)
        for iteration in range(int(train_length / batch_size)):
            train_data = next(train_reader)
            #以下是单卡训练(与上面的训练器代码对应)
            results = exe.run(
                feed=get_feeder_data(train_data, place),
                fetch_list=[reduced_loss.name, miou.name])

            #以下是多卡训练
            # results = train_exe.run(
            #     feed=get_feeder_data(train_data, place),
            #     fetch_list=[reduced_loss.name, miou.name])
            iter_id += 1
            total_loss += np.mean(results[0])
            total_miou += np.mean(results[1])

            if iter_id % log_iters == 0: # Print log
                end_time = time.time()
                print(
                "Iter - %d: train loss: %.3f, mean iou: %.3f, time cost: %.3f s"
                % (iter_id, total_loss / log_iters, total_miou / log_iters, end_time - prev_time))
                total_loss = 0.0
                total_miou = 0.0
                prev_time = time.time()

            if iter_id % save_model_iters == 0: # save model
                dir_name =save_model_path + str(epoch + add_num) + '_' + str(iter_id)
                fluid.io.save_params(exe, dirname=dir_name)
                print("Saved checkpoint: %s" % (dir_name))
        iter_id = 0
        dir_name = save_model_path + str(epoch + add_num) + '_end'
        fluid.io.save_params(exe, dirname=dir_name)
        print("Saved checkpoint: %s" % (dir_name))

# Main
if __name__ == "__main__":
    main()

5.ensemble.py文件 

该文件是模型融合代码,它是将三个算法模型训练好进行融合,进一步提升语义分割识别的准确率

import os
import numpy as np
import cv2
from paddle import fluid
from utils.image_process import expand_resize_data

# Create a bilineraNet to resize predictions to full size
def bilinearNet(predictions, submission_size, crop_offset):
    logit = fluid.layers.resize_bilinear(input=predictions, out_shape=(submission_size[0], submission_size[1] - crop_offset))
    return logit

# Main
if __name__ == "__main__":
    print('Start Making Ensemble Submissions!')
    #test_dir = '../PaddlePaddle/TestSet_Final/ColorImage/'
    #sub_dir = './test_submission/'

    test_dir = 'E:/PaddleXinstallation/data/chusai_data/TestSet_Final/ColorImage/'
    sub_dir = 'E:/PaddleXinstallation/data/Lane-Segmentation-Solution-For-BaiduAI-Autonomous-Driving-Competition-master/test_submission/'

    IMG_SIZE = [1536, 512]
    SUBMISSION_SIZE = [3384, 1710]
    crop_offset = 690
    # Ignore Class 4
    label_num = 8
    test_list = os.listdir(test_dir)

    # Three Folders which save npy files corresponding to all test images
    # ensemble index 1 0.61234

    # model_lists = ['/npy_save/deeplabv3p/',
    #                '/npy_save/unet_base/',
    #                '/npy_save/unet_simple/']

    model_lists = ['E:/PaddleXinstallation/data/Lane-Segmentation-Solution-For-BaiduAI-Autonomous-Driving-Competition-master/npy_save/deeplabv3p/',
                   'E:/PaddleXinstallation/data/Lane-Segmentation-Solution-For-BaiduAI-Autonomous-Driving-Competition-master/npy_save/unet_base/',
                   'E:/PaddleXinstallation/data/Lane-Segmentation-Solution-For-BaiduAI-Autonomous-Driving-Competition-master/npy_save/unet_simple/']

    # Build Model & Initialize Program
    images = fluid.layers.data(name='image', shape=[label_num, IMG_SIZE[1], IMG_SIZE[0]], dtype='float32')
    predictions = bilinearNet(images, SUBMISSION_SIZE, crop_offset)
    place = fluid.CUDAPlace(0)
    exe = fluid.Executor(place)
    exe.run(fluid.default_startup_program())

    for index in range(len(test_list)):
        test_name = test_list[index]
        print(index, test_name)

        # Load three diffirent npys and then do average
        model_logits1 = np.load(model_lists[0] + test_name.replace('.jpg', '.npy'))
        model_logits2 = np.load(model_lists[1] + test_name.replace('.jpg', '.npy'))
        model_logits3 = np.load(model_lists[2] + test_name.replace('.jpg', '.npy'))
        avg_model_logits = (model_logits1 + model_logits2 + model_logits3) / 3.0
        logits_input = np.expand_dims(np.array(avg_model_logits), axis=0)

        # Feed data & Run BilinearNet
        feed_dict = {}
        feed_dict["image"] = logits_input
        results = exe.run(
            feed=feed_dict,
            fetch_list=[predictions])

        prediction = np.argmax(results[0][0], axis=0)
        # Convert prediction to submission image
        submission_mask = expand_resize_data(prediction, SUBMISSION_SIZE, crop_offset)
        # Save submission png
        cv2.imwrite(os.path.join(sub_dir, test_name.replace('.jpg', '.png')), submission_mask)

以上就是这个项目源码的解剖分析 ,运行的结果如下:

【基于deeplabv3p模型的车道线检测(深度学习)】

如果自己电脑显卡不支持训练,也可以在线 GPU训练,欢迎关注百度飞浆

paddle在线GPU训练

【GPU训练与基于深度学习的车道线检测】

这期的文章就先更新到这里,后期会更新关于深度学习的相关技术原理,欢迎大家下方留言或者私信,有空都会回复

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于深度学习的无人驾驶道路检测 的相关文章

  • Python Pandas 滚动聚合一列列表

    我有一个简单的数据框 df 和一列列表lists 我想根据以下内容生成一个附加列lists The df好像 import pandas as pd lists 1 1 2 1 2 3 3 2 9 7 9 4 2 7 3 5 create
  • 熊猫按 n 最大总和分组

    我正在尝试使用groupby nlargest and sum在 Pandas 中一起运行 但在运行时遇到困难 State County Population Alabama a 100 Alabama b 50 Alabama c 40
  • GUI 测试工具 PyUseCase 与 Dogtail 相比如何?

    GUI测试工具如何Py用例 http pypi python org pypi PyUseCase重命名为故事文本 http pypi python org pypi StoryText 相比于Dogtail http en wikiped
  • DynamodB:如何更新排序键?

    该表有两个键 filename 分区键 和eventTime 排序键 我要更新eventTime对于某些filename Tried put item and update item 发送相同的filename与新的eventTime但这些
  • 如何通过 python 中的函数运行列表?

    我试图通过我创建的函数运行我的列表 但不断收到错误 我不知道出了什么问题 温度 F temp f 19 21 21 21 23 功能 def fahrToCelsius tempFahrenheit return tempFahrenhei
  • Python 不考虑 distutils.cfg

    我已经尝试了给出的所有内容 并且所有教程都指向相同的方向 即使用 mingw 作为 python 而不是 Visual C 中的编译器 我确实有 Visual C 和 mingw 当我想使用 pip 安装时 问题开始出现 它总是给Unabl
  • 如何用函数记录一个文件?

    我有一个带有函数 lib py 但没有类的python 文件 每个函数都有以下样式 def fnc1 a b c This fonction does something param a lalala type a str param b
  • 使用 Tkinter 打开网页

    因此 我的应用程序需要能够打开其中的单个网页 并且它必须来自互联网并且未保存 特别是我想使用 Tkinter GUI 工具包 因为它是我最熟悉的工具包 最重要的是 我希望能够在窗口中生成事件 例如单击鼠标 但无需实际使用鼠标 有什么好的方法
  • Python speedtest.net,或等效的[关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 是否有一个 Python 库可以实现 SpeedTest net 测试或等效的互联网连接速度测试 GitHub上有一个项目叫速度检查 https gi
  • 如何从 python 脚本执行 7zip 命令

    我试图了解如何使用 os system 模块来执行 7zip 命令 现在我不想用 Popen 或 subprocess 让事情变得复杂 我已经安装了 7zip 并将 7zip exe 复制到我的用户文件夹中 我只想提取我的测试文件 inst
  • Eclipse/PyDev 中未使用导入警告,尽管已使用

    我正在我的文件中导入一个绘图包 如下所示 import matplotlib pyplot as plt 稍后我会在我的代码中成功使用此导入 fig plt figure figsize 16 10 然而 Eclipse 告诉我 未使用的导
  • 如何将 URL 添加到 Telegram Bot 的 InlineKeyboardButton

    我想制作一个按钮 可以从 Telegram 聊天中在浏览器中打开 URL 外部超链接 目前 我只开发了可点击的操作按钮 update message reply text Subscribe to us on Facebook and Te
  • 根据标点符号列表替换数据框中的标点符号[重复]

    这个问题在这里已经有答案了 使用 Canopy 和 Pandas 我有数据框 a 其定义如下 a pd read csv text txt df pd DataFrame a df columns test test txt 是一个单列文件
  • 如何在引发异常时将变量传递给异常并在异常时检索它?

    现在我只有一个空白的异常类 我想知道如何在引发变量时给它一个变量 然后在 try except 中处理它时检索该变量 class ExampleException Exception pass 为其构造函数提供一个参数 将其存储为属性 然后
  • 类返回语句不打印任何输出

    我正在学习课程 但遇到了问题return语句 它是语句吗 我希望如此 程序什么也没有打印出来 它只是结束而不做任何事情 class className def createName self name self name name def
  • 从给定的项目列表创建子列表

    我首先要说的是以下问题不是为了家庭作业目的即使因为我几个月前就完成了软件工程师的工作 无论如何 今天我正在工作 一位朋友向我询问了这个奇怪的排序问题 我有一个包含 1000 行的列表 每行代表一个数字 我想创建 10 个子列表 每个子列表都
  • 用 pandas DataFrame 替换 mysql 数据库表中的行

    Python 版本 2 7 6 熊猫版本 0 17 1 MySQLdb 版本 1 2 5 在我的数据库中 PRODUCT 我有一张桌子 XML FEED 表 XML FEED 很大 数百万条记录 我有一个 pandas DataFrame
  • 检查 IP 地址是否在给定范围内

    我想检查一下是否有IP180 179 77 11位于特定范围之间 例如180 179 0 0 180 179 255 255 我编写了一个函数 它将每个 IP 八位字节与其他八位字节进行比较 def match mask IP min ip
  • Chrome 驱动程序和 Chromium 二进制文件无法在 aws lambda 上运行

    我陷入了一个问题 我需要在 AWS lambda 上做一些抓取工作 所以我按照下面提到的博客及其代码库作为起点 这非常有帮助 并且在运行时环境 Python 3 6 的 AWS lambda 上对我来说工作得很好 https manivan
  • 从 Django 运行 shell 命令

    我正在 Django 中开发一个网页 使用 apache 服务器 需要调用 shell 命令来启用 禁用一些守护进程 我尝试这样做 os system service httpd restart 1 gt HOME out 2 gt HOM

随机推荐

  • easyexcel 第一次导入导出会报错com.alibaba.excel.exception.ExcelAnalysisException,所以自定义excel导入导出表格

    报错原因 由于easyexcel导入导出时如果存在null会报错 跟踪源码com alibaba excel analysis v07 XlsxSaxAnalyser parseXmlSource 查看xmlReader parse 发现这
  • vi 操作

    vi filename c vi 457 filename c 打开文件同时跳至457行 exc 由输入状态退出到控制命令状态 shirt zz 保存并退出 w 保存退出 q 不保存退出 457 跳至457行 set nu 在前面列出行号
  • 大数据教育平台数据仓库系统搭建 附安装包与脚本

    一 数仓项目需求及架构设计 数据仓库是为企业所有级别的决策制定过程 提供所有类型数据支持的战略集合 数据仓库是出于分析报告和决策支持目的而创建的 为需要业务智能的企业 提供指导业务流程改进 监控时间 成本 质量以及控制 1 项目需求分析 数
  • Xilinx软件开发: 用仿真器在XSCT下加载u-boot

    XSCT介绍 XSCT全称叫做Xilinx Software Command Line Tool 顾名思义是Xilinx提供的软件命令行工具 完整的使用说明可以参考ug1208 xsct reference guide 我们平常调试裸机程序
  • Gradle 5.0 更新介绍

    Gradle 5 0正式版出来有几天了 这个工具的发展速度还真是惊人 前些天我看到gradle 5 rc版的时候还在想正式版什么时候出 没想到rc版没过几天正式版就出来了 那么正好 就来介绍一下gradle 5 0正式版加入的一些新功能吧
  • json字段 react_react 解析json

    Copyright 2013 2017 David Caldwell Permission to use copy modify and or distribute this software for any purpose with or
  • Python的sort函数和sorted、lambda和cmp

    1 sort和sorted 我们需要对List进行排序 Python提供了两个方法 对给定的List L进行排序 方法1 用List的成员函数sort进行排序 方法2 用built in函数sorted进行排序 从2 4开始 iterabl
  • STM32移植lwip之建立tcp服务器

    本篇目标 在之前能ping通pc机的工程基础上搭建tcp连接 并可以收发数据 在网络调试工具上显示 材料准备 基础工程 修改后能ping通pc机的工程 STM32官方移植lwip修改代码 调试工具 用来调试tcp连接下的数据接收 网络调试助
  • QT从入门到入土(七)——鼠标事件

    引言 个人认为 事件机制是Qt最难以理解且最为精妙的一部分 事件主要分为两种 在与用户交互时发生 比如按下鼠标 mousePressEvent 敲击键盘 keyPressEvent 等 系统自动发生 比如计时器事件 timerEvent 等
  • 嵌入式系统-CAT1025 EEPROM芯片自学报告

    一 芯片简介 CAT1025 是基于微控制器系统的存储器和电源监控的完全解决方案 它利用低功耗 CMOS 技术将 2K 位的串行 EEPOM 和用于掉电保护的系统电源监控电路集成在一块芯片内 存储器采用 400KHz 的 I2C 总线接口
  • 搜索引擎solr系列---高亮配置及问题总结

    solr的高亮配置有两种方式 一种是配置形式 具体是在配置文件中配置的 该方式我没有用过 所以我这里就不写它了 另一种就是以代码的形式 我只会用这种方式 所以只写这部分 其实还要一种就是自我实现 这个更简单粗暴 1 高亮的代码具体如下 pa
  • 数据结构—散列表(哈希表)的原理以及Java代码的实现

    本文详细介绍了散列表的概念 散列函数的选择 散列冲突的解决办法 并且最后提供了一种散列表的Java代码实现 数组的特点是寻址容易 插入和删除困难 而链表的特点是寻址困难 插入和删除容易 而对于tree结构 它们的查找都是先从根节点进行查找
  • ElasticSearch 简介及基本操作

    简介 什么是ElasticSearch ElasticSearch 简称 ES 是基于Apache Lucene构建的开源搜索引擎 是当前最流行的企业级搜索引擎 Lucene本身就可以被认为迄今为止性能最好的一款开源搜索引擎工具包 但是lu
  • vue+element-ui初体验入门拥有自己的前台项目以及配置文件讲解(1)vue项目创建

    阿丹 之前一直在写jsp页面 自从发现vue可以支持更好看更高级的页面效果之后开始研究一下 这篇文章 可以带领兄弟们简单的得到实现一个简易的自己vue项目 如果想部署服务器上 可以参考阿丹的部署vue的文章哈 准备工作 编译工具 idea
  • python后端学习(五)迭代器、生成器、协程

    迭代器 迭代是访问集合元素的一种方式 迭代器是一个可以记住遍历的位置的对象 迭代器对象从集合的第一个元素开始访问 直到所有的元素被访问完结束 迭代器只能往前不会后退 1 可迭代对象 我们已经知道可以对list tuple str等类型的数据
  • CoreData之MagicalRecord源码解读

    CoreData之MagicalRecord源码解读 CoreData 与SQLite 说到数据持久化 很难让人不想到又爱又恨的CoreData 说到CoreData可能大多数人就是想到的繁琐 最直接的原因就是使用CoreData涉及的类特
  • “极狐•华为HI版本”的尴尬与困境

    2021年4月上海汽车展 发生了一起震惊中国汽车界的营销事件 华为在车展的前4天 4月15日 发布了一段高级辅助驾驶的演示视频 图1 在4月15日发布的视频中 2块显示屏叠在一起 告诉我们这是测试车 这个视频当中 汽车的内饰是和普通的电动轿
  • Qt程序的打包案例

    1 在Qt内构建并运行release 2 在运行后生成的文件夹中找到 exe后缀文件 然后复制 到桌面创建一个新文件夹 如login文件夹 3 在桌面创建一个文件夹 名字可以随意取 equip system 把刚复制的exe粘贴到里边 4
  • Flink主要组件以及工作流程

    Flink简介 Flink 是一个框架和分布式处理引擎 用于对无界和有界数据流 批处理和流处理 进行有状态计算 并且 Flink 提供了数据分布 容错机制以及资源管理等核心功能 Flink提供了诸多高抽象层的API以便用户编写分布式任务 D
  • 基于深度学习的无人驾驶道路检测

    最近在自学深度学习 网上有很多计算机视觉比赛和资源 比如kaggle 天池 百度飞浆 paddle现在做得越来越好 于是我就选择了百度飞浆 支持国产开源框架 也自己跑通了代码 以此记录一下学习过程 若有纰漏 恳请各位大佬多多指点 目录 一