【深度学习|学习笔记】Dual Path Fully Convolutional Network(Dual Path FCN)的起源、原理、发展和应用(附代码)
【深度学习|学习笔记】Dual Path Fully Convolutional Network(Dual Path FCN)的起源、原理、发展和应用(附代码)
文章目录
欢迎铁子们点赞、关注、收藏!
祝大家逢考必过!逢投必中!上岸上岸上岸!upupup
大多数高校硕博生毕业要求需要参加学术会议,发表EI或者SCI检索的学术论文会议论文。详细信息可关注VX “
学术会议小灵通
”或参考学术信息专栏:https://blog.csdn.net/2401_89898861/article/details/146957339
一、起源:融合多尺度信息的需求推动
1.1 背景
随着 FCN(Fully Convolutional Network,全卷积网络) 的提出,语义分割进入深度学习主导时代。但 FCN 存在两个问题:
- 上采样精度不足,导致边缘模糊;
- 高层特征虽语义强,但空间细节差,低层特征细节丰富但语义弱。
1.2 Dual Path FCN 的提出
为了解决上述矛盾,研究者提出了 Dual Path FCN,核心思想是通过 两条独立路径 分别处理:
- 主路径(主干):提取高层语义特征;
- 辅助路径(边缘细节):保留空间分辨率和边缘信息。
二、原理:双分支融合结构
2.1 核心结构组成
Dual Path FCN = 主路径 + 辅助路径 + 融合模块
🧠 主路径:
- 通常为一个 CNN 主干(如 ResNet、VGG、MobileNet 等)
- 逐层下采样、获取高语义特征
👁️ 辅助路径:
- 保持较高空间分辨率(不下采样或轻量下采样)
- 保留细节边缘、纹理、局部结构
🔗 融合策略:
- 特征对齐后拼接 / 加权融合 / attention 加权
- 多尺度融合、skip connection 或 feature alignment
2.2 结构图示意
Input
├──→ 主路径(深层 CNN 提取语义)─────┐
└──→ 辅助路径(浅层保留边缘细节)──┤→ 融合 → 分割预测
三、发展与演进
3.1 BiSeNet(2018)
- 结构上类似 Dual Path FCN,被视为其进化版;
- 提出 Spatial Path + Context Path 的分支结构;
- 更强融合策略如 attention refinement、feature fusion module。
3.2 高效模型演进
Dual Path 架构被广泛融合进:
- HRNet:不同分辨率分支同时进行
- ICNet:Image Cascade for Real-Time Segmentation
- DDRNet:Deep Dual-Resolution Network(分辨率不对齐也可训练)
四、改进方向
五、应用场景
六、PyTorch 简化实现示例
我们以一种简化版 Dual Path FCN 的结构进行演示(主干 + 辅助 + 融合):
import torch
import torch.nn as nn
import torch.nn.functional as F
from torchvision.models import resnet18
class DualPathFCN(nn.Module):
def __init__(self, num_classes):
super(DualPathFCN, self).__init__()
# 主路径:使用 ResNet18 backbone
resnet = resnet18(pretrained=True)
self.backbone = nn.Sequential(*list(resnet.children())[:-2]) # [B, 512, H/32, W/32]
# 辅助路径:轻量卷积提取边缘细节
self.aux_path = nn.Sequential(
nn.Conv2d(3, 32, kernel_size=3, padding=1),
nn.BatchNorm2d(32),
nn.ReLU(),
nn.Conv2d(32, 64, kernel_size=3, padding=1),
nn.BatchNorm2d(64),
nn.ReLU()
)
# 上采样主路径特征
self.up_main = nn.ConvTranspose2d(512, 64, kernel_size=4, stride=4)
# 融合后预测
self.classifier = nn.Sequential(
nn.Conv2d(128, 64, 3, padding=1),
nn.ReLU(),
nn.Conv2d(64, num_classes, 1)
)
def forward(self, x):
x_main = self.backbone(x) # [B, 512, H/32, W/32]
x_main_up = self.up_main(x_main) # [B, 64, H/8, W/8]
x_aux = self.aux_path(x) # [B, 64, H, W]
x_aux_ds = F.interpolate(x_aux, scale_factor=1/8, mode='bilinear', align_corners=True)
fused = torch.cat([x_main_up, x_aux_ds], dim=1) # concat features
out = self.classifier(fused)
out = F.interpolate(out, size=x.shape[2:], mode='bilinear', align_corners=True)
return out