目录
1.模型架构
2.核心模块SCNN_*分析
SCNN(Spatial As Deep: Spatial CNN for Traffic Lane Detection)是一种专为交通车道线检测任务设计的深度神经网络架构,由中国科学院计算技术研究所提出,旨在在语义分割框架中增强空间信息的传播能力,特别适用于车道线这样细长、连续目标的检测。
论文连接:[1712.06080] Spatial As Deep: Spatial CNN for Traffic Scene Understanding
代码连接:
-
- GitHub - XingangPan/SCNN: Spatial CNN for traffic lane detection (AAAI2018) (作者官方实现)
- GitHub - cardwing/Codes-for-Lane-Detection: Learning Lightweight Lane Detection CNNs by Self Attention Distillation (ICCV 2019) (包含多种 lane detection 方法)
核心思想
传统的卷积神经网络(CNN)主要处理局部感受野,难以捕捉长距离的空间依赖,而车道线具有连续性强、形状细长的特点。SCNN 提出在 feature map 的空间维度上进行类似“层间传播”的处理,增强特征图在水平方向、垂直方向上的信息流动。
1.模型架构
SCNN模型架构整体结构:
Input Image↓
Backbone CNN(如 VGG16)↓
Feature Map [C × H × W]↓
SCNN Module(四方向空间传播)↓
Feature Enhancement↓
Output Layer(如分割、分类)
Backbone CNN:
-
一般使用标准的 CNN,如 VGG16、ResNet-18/34 等;
-
主要负责提取基础的图像特征;
-
输出 shape:
[B, C, H, W]
。
SCNN 模块:
在特征图上沿某个方向逐行/逐列地信息传播,类似 RNN。
共有四个方向的传播模块:Downward(D)、Upward(U)、Rightward(R)、Leftward(L)
输出层:
-
通过
1x1 卷积
将增强后的特征图降维; -
若为二分类(如车道线 vs 非车道线),输出通道为 1;
-
通常带有:
-
BatchNorm
-
激活函数(如 ReLU)
-
上采样(恢复到原图大小)
-
2.核心模块SCNN_*分析
SCNN的核心是在特征图的垂直方向上(从上到下)进行跨行的信息传播,使得像素点在竖直方向上可以感受到更大的上下文区域。处理方式并不是完全替代卷积层,而是在已有的 CNN 结构中嵌入一个“空间卷积”模块,其操作流程如下:
- 沿某个空间维度(例如从上到下)逐行传播;
- 当前行的特征受到上一行的影响;
- 以残差连接的形式完成传播;
- 对上下左右四个方向分别做一次 SCNN;
- 最终实现信息在空间域上的深层传递。
这类似于将一维的 RNN 沿空间维度展开,但效率更高、计算复杂度更低。
(Top→Bottom、Bottom→Top、Left→Right、Right→Left)
模块儿输入 & 输出形状
- 输入特征图:形状为 C × H × W
- 输出特征图:形状仍为 C × H × W
SCNN 不改变特征图尺寸,只增加其空间上下文建模能力。
以SCNN_D层为例了解处理步骤:(向下传播的空间卷积)
- 沿 Height 方向拆分:
- 将特征图拆成 H 个 slice(每一行,shape 为 C × W)。
- 逐行传播(从第2行到最后一行):
- 从第2行开始,每一行与上一行进行融合。
- 融合方式:
- 将前一行的输出通过一层带偏置的一维卷积(跨通道)处理;
- 加到当前行的特征上(残差连接);
- 通常再经过非线性激活(如 ReLU)。
- 用共享卷积核进行空间信息传播:
- 卷积核大小:C × w,其中 w 是横向(一维)卷积宽度;
- 用 C 个核对每一行做一维卷积,融合上一行的信息。
第一层slice做的事情:
- 原始 feature map 是 C × H × W(通道数 × 高 × 宽);
- 拆成 H 个 slice,意味着每个 slice 是 C × W(固定某一行);
- 现在拿一个 C × W 的 slice,去做一个卷积;
- 卷积核是 C × w,总共有 C 个卷积核(输出C个通道);
这里需要注意每个卷积核是 C × w,长度是C,宽度w。对slice做卷积得到是一维特征图。一共有C个卷积核(等于有C个输出通道)。
伪代码:
for i in range(1, H):msg = Conv1D(slice[i - 1]) # C个卷积核,核大小 C × wslice[i] = slice[i] + msg # 残差加法融合slice[i] = ReLU(slice[i]) # 非线性激活(可选)
其余方向的处理:
模块名称 | 英文方向 | 中文含义 | 数据遍历方向 | 每步计算来源 |
SCNN_D | Downward | 向下传播 | 从第 1 行 → 第 H 行 | 来自上一行(i−1) |
SCNN_U | Upward | 向上传播 | 从第 H 行 → 第 1 行 | 来自下一行(i+1) |
SCNN_R | Rightward | 向右传播 | 从第 1 列 → 第 W 列 | 来自左侧列(j−1) |
SCNN_L | Leftward | 向左传播 | 从第 W 列 → 第 1 列 | 来自右侧列(j+1) |
各方向的具体流程(类比 SCNN_D)
✅ 1. SCNN_D(Downward)
- 拆分为 H 个 C × W 的 slices(按行划分);
- 从上往下(1 → H)遍历;
- 每一行接收上一行的信息;
- 用 1D 卷积 + 残差加法融合。
✅ 2. SCNN_U(Upward)
- 同样拆分为 H 个 C × W 的 slices;
- 但从下往上(H → 1)遍历;
- 每一行接收下一行的信息;
- 卷积方向相同(都是横向做一维卷积),只是遍历方向相反(即处理的行顺序反了过来(D 从上往下,U 从下往上)。
它与 SCNN_D 是对称操作。
✅ 3. SCNN_R(Rightward)
- 拆分为 W 个 C × H 的 slices(按列划分);
- 从左往右(1 → W)遍历;
- 每一列接收左边一列的信息;
- 使用 C × h 的卷积核(h 是竖直方向核高);
- 融合后仍保留输出为 C × H × W。
✅ 4. SCNN_L(Leftward)
- 同样拆成 W 个 C × H 的 slices;
- 从右往左(W → 1)遍历;
- 每一列接收右边列的信息;
- 卷积和融合方式类似于 SCNN_R。
模块效果直观解释
场景 | 传统 CNN | SCNN |
车道线很长(上下方向延展) | 感受野不够 | SCNN_D/U 可以让上下文关联 |
车道线并行(左右方向延展) | 空间关系弱 | SCNN_L/R 可以增强列之间的联系 |
弯道或遮挡 | 难以识别连续结构 | SCNN 传播机制可以传递线索,从未遮挡区域“推理”出被遮挡部分 |