# 车道线检测深度学习方法
# 任务
车道线检测 (Lane Detetction) :需要将视频中出现的车道线检测出来。任务要求如下:
-
查询车道线检测的相关综述,包括
传统视觉
和深度学习
的方案 - 通常需要检测四条车道线:左车道、自车道、右车道。
- 需要判断双黄线、白色虚线、白色实线
- 如果车道线终止,需要判断出结束位置
- 车道线需要拟合成曲线,检测的车道线要求稳定,不能发生连续帧之间突变的情况
# 项目
项目是基于 Ultra Fast Lane Detection open in new window
# 配置环境
conda create -n lanedet python=3.8 -y
conda activate lanedet
安装 Pytorch open in new window 依赖,需要 CUDA 11.8
pip3 install torch torchvision --index-url https://download.pytorch.org/whl/cu118
安装其他依赖
pip3 install -r requirements.txt
# 数据集准备
车道线检测常用的公开数据集:
- CULane open in new window
- TuSimple open in new window
- CurveLanes open in new window :华为数据集 这里我们选择 CULane open in new window 作为参考进行实验、制作自己的数据集
CULane 数据集处理和制作参考 CULane文档
无论是使用
CULane 数据集
还是
自制数据集
,都需要设置环境变量
$CULANEROOT
# ~/.bashrc
export CULANEROOT=/path/to/culane
# 训练
首先,修改配置文件
configs/culane.py
中重要的参数(复制一份配置文件到
temp/culane.py
修改,而不是修改原始的配置文件),包括:
-
data_root
是 CULane 数据集路径 -
log_path
是输出的模型路径,这里默认为tmps
-
训练中的超参数,比如
epoch
,batch_size
,steps
等 -
resume
是预训练权重,如果需要加载预训练权重,可以下载官方的预训练权重: GoogleDrive open in new window / BaiduDrive open in new window ,官方的预训练权重基于 resnet18,如果希望替换成其他 backbone,需要从头训练
确认配置文件无误后启动训练脚本,需要修改脚本
temp/culane.py
内
python3 train.py temp/culane.py # 单 GPU 训练
bash scripts/train-dist.sh # 多 GPU 训练
# 测试
训练完成后,需要对模型进行测试,这里是对
$CULANEROOT
进行测试,如果只希望对单张图像进行测试,在下文提到。需要修改
temp/culane.py
中
test_model
(待测试的模型权重文件) 和
test_work_dir
(测试结果输出的目录,默认
tmps
),然后运行
python3 test.py temp/culane.py
单张图像测试,需要配置的内容与上述结果相同,但是需要修改文件中
test_img = "datasets/CULane/images/04980.jpg"
为指定的图像
python3 infer-torch.py temp/culane.py
# 部署
部署分为两种方式:
- ONNX 部署 :将 pytorch 模型转化为 ONNX 模型,然后使用 ONNXRuntime 进行推理
- TensorRT 部署 ::将 pytorch 模型转化为 ONNX/Engine 模型,然后使用 TensorRT 进行推理
这里给出一种推理速度参考
推理方式 | 平均推理时间 |
---|---|
Pytorch | 30.9649 ms |
ONNXRuntime | 19.9175 ms |
TensorRT Engine | 6.5350 ms |
TensorRT 部署在 Jetson 上需要考虑系统环境,例如 Jetson Nano open in new window 系统中包含 JetPack 4.6.1 open in new window :
- OS : Ubuntu 18.04, Linux kernel 4.9
- TensorRT 8.2.1 open in new window
- cuDNN 8.2.1
- CUDA 10.2 open in new window
# 1. ONNX 部署
修改配置文件
temp/culane.py
中
fintune
为 pytorch 模型的权重,运行脚本后会在相同目录下生成同名的
.onnx
文件
python3 export.py temp/culane.py
得到
.onnx
文件后,修改推理脚本
infer-onnx.py
中的 onnx 模型权重
onnx_file
和待测试视频
video
,然后运行如下
python3 infer-onnx.py
# 2. TensorRT 部署
参考 TensorRT 官方文档 open in new window ,部署有两种方式:
- 使用 TensorRT 推理 ONNX 模型
- 将 ONNX 转化为 Engine 模型并使用 TensorRT 推理
TensorRT官方文档 "NVIDIA Official Documentation" open in new window
# 安装 TensorRT 环境
必须 Ubuntu + Nvidia GPU 环境
- 安装 CUDA、cuDNN、TensorRT,参考 官方文档 open in new window ,需要注册 Nvidia 账号 open in new window ,并登陆
-
安装 CUDA
进入 CUDA 下载页面 open in new window 并选择需要的版本,根据电脑的配置依次选择各项,最后选择
deb(local)
安装方式,将出现的命令依次复制到终端中执行。注意 : JetPack 4.6.1 CUDA 10.2 open in new window ,但是 10.2 不支持 Ubuntu20,所以下载 CUDA 11.4 open in new window
-
安装 cuDNN
进入 cuDNN 下载页面 open in new window ,根据 CUDA 版本 和 系统架构 选择对应的版本的 Tar 文件,下载以下内文件:
-
cuDNN v8.2.1, for CUDA 10.2, for Linux (x86)
open in new window : 安装在 Jetson Nano 上用于转换 Engine 模型 -
cuDNN v8.2.1, for CUDA 11.x, for Linux (x86)
open in new window : 安装在电脑上用于转换 Engine 模型和测试,这一步是为了在电脑上编写推理代码和测试,如果推理代码已经写好,可以不用安装 -
cuDNN8.9.0 + CUDA 11.8 + Linux x86_64 (Tar)
open in new window : 最新版本
下载后得到压缩包
cudnn-${version}.tar.xz
,将压缩包解压后得到同名的目录,但是8.2.1 解压后得到的是 cuda 目录,建议改名tar -xf cudnn-${version}.tar.xz
-
-
安装 TensorRT
进入 下载页面 open in new window ,点击 Download Now 的入口,选择版本的 Tar 文件下载:
下载后得到压缩包
TensorRT-${version}.tar.gz
,将压缩包解压后得到同名的目录tar -xf TensorRT-${version}.tar.gz
在系统环境变量中添加 CUDA, cuDNN,TensorRT 相关的路径(修改为真实路径
$xxx_HOME
)。添加完成后,
source ~/.bashrc
使环境变量生效
# ~/.bashrc
# ------ CUDA ------
CUDA_VERSION=11.8
export CUDA_HOME=/usr/local/cuda-${CUDA_VERSION}
export PATH=$PATH:$CUDA_HOME/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$CUDA_HOME
/lib64
# ------ cuDNN 8.2.1 ------
export CUDNN_HOME=path/to/cudnn-<version>
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$CUDNN_HOME/lib64 # 新版本为 lib 目录,建议自己检查一下
# ------ TensorRT 8.2.1 ------
export TENSORRT_HOME=path/to/TensorRT-<version>
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$TENSORRT_HOME/lib
export PATH=$PATH:$TENSORRT_HOME/bin
- 安装 python相关环境
参考官方文档
"Python Package Index Installation"
open in new window
安装 python 的
tensorrt
open in new window
# 根据 python 版本选择对应的 .whl 文件
python3 -m pip install --upgrade $TENSORRT_HOME/python/tensorrt-<version>.whl
python3 -m pip install --upgrade pycuda>=2020.1 # 已写入 requirements.txt
# 1. TensorRT 推理 ONNX 模型
参考官方 Python API open in new window
python3 -m pip install --upgrade pip
# 2. TensorRT 推理 Engine 模型
参考官方文档 "Exporting To ONNX From PyTorch"/"Converting ONNX To A TensorRT Engine" open in new window 这种方式的部署流程是:首先将 ONNX 模型转化为 TensorRT Engine 模型,再使用 TensorRT API 推理 Engine 模型
转换过程中需要考虑到 TensorRT 支持的 ONNX 版本,具体可以参考
TensorRT(8.2.1) 源码
open in new window
中的
requirements.txt
open in new window
文件,所以需要重新安装 ONNX 再重新转换
python3 -m pip install onnx==1.9.0 # 已写入 requirements.txt
python3 export.py temp/culane.py
在转换之前,确保有
**-INT32.onnx
模型,因为 TensorRT 支持 INT32 而不支持 INT64。如果没有,可以使用
onnxsim
工具进行转换
python3 -m onnxsim weights/culane_18.onnx weights/culane_18-sim.onnx
上述操作都可以在电脑上完成,但是如果需要在 Jetson Nano 上推理,则需要将 onnx 转换为 Engine 模型需要在 Jetson Nano 上完成,否则会出现 " 不匹配设备的报错 " ,但是后面的步骤可以在电脑上测试没有问题再在 Jetson Nano 上部署。
Jetpack 自带的库在
/usr/src
,因此在 Jetson Nano 的系统环境变量中添加如下内容,然后
source ~/.bashrc
使环境变量生效
# ~/.bashrc
# ------ CUDA 10.2 ------
CUDA_VERSION=10.2
export CUDA_HOME=/usr/local/cuda-${CUDA_VERSION}
export PATH=$PATH:$CUDA_HOME/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$CUDA_HOME/lib64
# ------ TensorRT 8.2.1 ------
export TENSORRT_HOME=/usr/src/tensorrt
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$TENSORRT_HOME/lib
export PATH=$PATH:$TENSORRT_HOME/bin
使用官方提供的转换工具进行转换,如果 TensorRT 环境配置正确,将
**-INT32.onnx
转化为
**-INT32.engine
。转换过程中可能出现的bug以及解决方案记录在
"Tensor RT Engine 转换过程中的问题"
中,这里提供一个
输出细节参考
python3 export.py configs/culane.py
trtexec --verbose --fp16 \
--onnx=weights/culane_18-INT32.onnx \
--saveEngine=weights/culane_18-INT32.engine
-
--workspace=N
: Set workspace size in megabytes (default = 16) -
--fp16
: Enable fp16 precision, in addition to fp32 (default = disabled) -
--int8
: Enable int8 precision, in addition to fp32 (default = disabled) -
--verbose
: Use verbose logging (default = false) -
--exportTimes=<file>
:Write the timing results in a json file (default = disabled) -
--exportOutput=<file>
: Write the output tensors to a json file (default = disabled) -
--exportProfile=<file>
: Write the profile information per layer in a json file (default = disabled)
实际上,NV 官方提供了
torch2trt
open in new window 转换工具可以直接完成PyTroch -> Engine
,但是在 Jetson Nano 上部署的时候,需要在 Jetson Nano 上完成模型转换,否则在实际使用时会出现 不匹配设备的报错 ,那么将完整的 torch 项目直接安装在 Jetson Nano 上可能会遇到很多问题,因此,这里先在电脑上完成PyTroch -> ONNX
转换,然后将转换好的ONNX
复制到 Jetson Nano 上使用trtexec
完成ONNX -> Engine
转换,可以避免在 Jetson Nano 上安装 torch 环境和项目的一些其他环境。
运行前需要安装
pycuda
python3 -m pip install pycuda>=2020.1
然后修改
deploy/infer-trtEngine.py
中的
TRT_MODEL_PATH
为
**-INT32.engine
的路径,运行
cd deploy
python3 infer-trtEngine.py
# 问题与解决方案
# Tensor RT Engine 转换过程中的问题
-
报错如下
[07/13/2023-11:01:12] [E] Error[1]: [caskUtils.cpp::trtSmToCask::147] Error Code 1: Internal Error (Unsupported SM: 0x809) [07/13/2023-11:01:12] [E] Error[2]: [builder.cpp::buildSerializedNetwork::609] Error Code 2: Internal Error (Assertion enginePtr != nullptr failed. )