该示例为参考算法,仅作为在 J6 上模型部署的设计参考,非量产算法
性能精度指标
GANet模型配置:
数据集 | Input shape | Backbone | Neck | Head |
CULane | 1x3x320x800 | MixVarGENet | GaNetNeck | GaNetHead |
性能精度表现:
latency/ms | 双核FPS | CulaneF1Score | ||
infer | post-process | 浮点 | 量化 | |
1.099 | 0.96 | 2432.68 | 0.7949 | 0.7872 |
注:CULane数据集官方介绍:CULane
模型介绍
车道线检测是一项具有挑战性的任务,需要预测车道线的复杂拓扑形状并同时区分不同类型的车道。早期的工作将预定义的锚回归到各种形状的车道线中,由于锚的形状固定,因此缺乏足够的灵活性来适应复杂形状的车道。全局关联网络(Global Association Network,GANet)通过直接回归车道线关键点到车道线起始点的偏移,来完成对车道线关键点的并行聚合,从而实现高效且准确的车道线检测。
模型优化点
相对于官方实现,地平线对GANet做了如下优化:
将模型的backbone替换为与地平线软硬件极为友好的MixVarGENet,提升了在板端运行的性能;
去除了公版的LFA模块,因为使用了J6暂不支持的deformconv1d算子;
将attention里面的hidden_dim从64降低到16,模块个数从2个减少到1个,有利于提升模型性能;
将attention结构优化为全4维计算,有利于提升模型性能。
模型结构

GANet的总体架构如上图所示。给定前视图像作为输入,采用CNN backbone和FPN neck来提取输入图像的多层视觉特征。为了更好地进行特征学习,在backbone和neck之间进一步插入了自注意层,以获得丰富的上下文信息。在解码器中,利用关键点头部和偏移头部分别生成置信度图(Confidence map:1x1x40x100)和偏移图(Offsets map:1x2x40x100),两个头都是由卷积层组成,置信度图后的X map和Y map为置信度对应的点的坐标。对于每个车道实例,首先通过在偏移图上选择值小于1的点来获得其起点作为聚类中心。然后,使用置信图和偏移图的组合,将属于同一车道的关键点聚集在采样的起点周围,以构建完整的车道线。
GANet由以下部分组成:
- Backbone+SA+****FPN:采用CNN主干和FPN来提取输入图像的多级视觉表示。为了更好地进行特征学习,在backbone和neck之间进一步插入了自注意力层(Self-Attention, SA ),以获得丰富的上下文信息 ;
- Keypoint head:预测关键点的置信度图;
- Offset head:预测关键点到车道线起始点的偏移量图;
源码说明
Config文件
注: 如果需要复现精度,config中的训练策略最好不要修改,否则可能会有意外的训练情况出现。
Backbone
GANet的backbone采用地平线自研的MixVarGENet,对J6的软硬件较为友好,该结构的基本单元为MixVarGEBlock。如下为MixVarGEBlock的结构图:

MixVarGEBlock由head op, stack ops,downsample layers,fusion layers四个基本模块组成。head_op 和stack_op都是由BasicMixVarGEBlock(如config文件中的mixvarge_f2,mixvarge_f4,mixvarge_f2_gb16)这样的基本单元构成,GANet中的配置见config文件的model定义字段。
GaNetNeck
为了获取丰富的上下文特征,ganet在backbone和neck间插入了Self-Attention(SA)层。
SA模块
SA模块是对backbone提取的图像特征进行“加权融合”,输出新的特征:
$$Attention(Q,K,V)=softmax({QK^T}{})$$
将位置编码加入到特征中,通过卷积计算生成Query(Q)、Key(K)、Value(V)向量,然后再进行如下的attention计算:
相关代码如下所示:
Neck
GANet的neck网络采用fpn,它采用自顶向下的层次结构来提取多尺度的高层语义特征。fpn网络结构如图所示:

相关代码:
GaNetHead
GANet利用一个关键点头(keypoint head)和一个偏移量头(offset head)来分别预测关键点的置信度图(confidence map)和关键点到车道线起始点的偏移量图(offset map),在推理过程中通过对这二者进行采样和组合,可以将关键点分配到所属的车道线,得到最终的车道线预测结果。
另外,GaNetHead中还有一个补偿误差分支,该分支的任务是减小输入下采样取整带来的量化误差。相关代码如下所示:
这里需要提到的是,我们将GANet的keypoint head、offset head和quantization error head中的linear都改写成了conv,对性能会有一些增益。
forward代码如下所示:
Decoder
Decoder的作用是基于置信度图、关键点图和误差图构建车道线。对于每个车道线实例,首先通过关键点置信图选择有效的关键点;然后,在offset head生成的偏移图上选择值小于1的点来获得其起始点,并作为聚类中心;最后,使用置信图和偏移图的组合,将属于同一车道的关键点聚集在采样的起点周围,以构建完整的车道线。下图为构建车道线的三个步骤:

采样关键点
首先在关键点置信度图上应用1×3最大池化层,以选择水平局部区域内的最大响应点作为有效关键点,如上图(a)所示。然后,我们将它们分组,将每条车道描述为关键点的有序列表。
起始点采样
为了获得每条车道的起始点,在偏移图上选择值小于1的关键点作为候选起点。由于在同一局部区域内可能存在多个与上述标准匹配的关键点,因此选择该区域的几何中心点以确保唯一性,如上图(b)所示。通过这种方式,预先确定了所有车道的实例及其起始点。每个关键点估计车道线起始点的坐标如下所示:
(sx',sy')=(x,y)+(\delta x,\delta{y}
其中(x,y)是观测关键点的坐标,(\delta{x},\delta{y}是获得的相应偏移。
具体过程如下图所示:
车道线构建
获取图中所有车道线对应的起始点坐标,如图(b)所示,以起始点为中心,划定一定范围,所有指向起始点落在这一范围内的关键点都属于同一条车道线,将这些关键点顺序连接,即可恢复完整的车道线形状。只有起始点估计(sx',sy')和起始点(sx,s{y})之间的距离小于预定义阈值\theta_{dis时,关键点(x,y)才与第i个车道相关联。如图(c)所示,对指向同一起始点附近的关键点进行分组,以生成整个车道线。
总结与建议
训练建议
浮点训练使用 Adam 优化器,base_lr=0.01、weight_decay=4e-5(作用于 weight)、num_epochs=240。
GANet 仅做 Calibration 即可满足量化精度,无需做 qat 训练;calibration 步数 calibration_step=10。
- 量化配置采用 QconfigSetter + q_templates,calibration 阶段 reference observer 为 MSEObserver,predict 阶段为 MinMaxObserver(fix_scale)。
部署建议
建议使用地平线自研的 MixVarGENet 作为 backbone,该结构对 J6 软硬件较为友好,可提升板端运行性能。
将 keypoint head、offset head、quantization error head 中的 linear 改写为 conv,对性能有一定增益。
attention 中的 ElementWise 操作(add/mul)若造成性能瓶颈或量化风险,可结合敏感度分析合理选择量化精度。
附录
modellabs官网:https://(待发布)
参考文档使用指南:https://.../github/heal/readme.md(待发布)
