语义分割网络之PSPnet

本文介绍PSPnet,一种解决基于FCN全卷积网络在语义分割中遇到的问题的方法。该网络利用金字塔模型提取多尺度信息,实现State-of-the-art的分割效果。关键点包括多尺度Pooling和额外深度监督Loss。文章提供了Caffe代码链接,详细指导了数据训练过程,包括数据标注工具和训练模型的准备,以及训练后的测试结果。

一.提出背景

       基于FCN全卷积网络的分割面临诸多问题,这篇文章从多尺度入手,提出了金字塔模型来提取多尺度的信息,达到了 State-of-the-art 的结果

       论文:PSPnet:Pyramid Scene Parsing Network 【点击下载

       Caffe代码:【Github


二.算法框架

       算法细节比较多,这里我主要强调以下几个关键点:

       1)通过多尺度 Pooling 的方式得到不同 Scale 的 Feature,Concat 得到判别的多尺度特征;

     

       2)加入额外的深度监督 Loss

        

三.数据训练

### PSPNet 语义分割网络架构 PSPNetPyramid Scene Parsing Network)是一种先进的图像语义分割模型,其设计旨在解决传统卷积神经网络在处理多尺度物体时遇到的挑战。该网络引入了一个独特的组件——金字塔池化模块(Pyramid Pooling Module),使得模型能够在多个尺度上捕捉全局上下文信息。 #### 架构详解 1. **基础骨干网络** 骨干网络通常采用预训练的深度卷积神经网络,如ResNet系列。这些网络负责提取输入图像的基础特征[^2]。 2. **金字塔池化模块 (PPM)** PPM 是 PSPNet 的核心创新之一。它通过对特征图应用不同大小的感受野来聚合多层次的信息。具体来说,PPM 将特征图划分为若干子区域并执行最大池化操作,随后将得到的结果重新组合成完整的特征表示。这种机制有助于增强对大范围背景的理解以及改善边界细节的表现力[^3]。 3. **融合层** 经过 PPM 处理后的特征会被与原始分辨率下的低级特征相结合,形成最终用于分类预测的高维特征向量。这一过程确保了局部纹理和整体布局都能被充分考虑进去。 4. **输出分支** 最终,经过一系列卷积运算后产生的特征映射会通过一个 softmax 层转换为像素级别的类别概率分布,进而完成整个语义分割任务。 ```python import torch.nn as nn from torchvision.models import resnet50, ResNet50_Weights class PSPModule(nn.Module): def __init__(self, features, out_features=1024, sizes=(1, 2, 3, 6)): super().__init__() self.stages = [] self.stages = nn.ModuleList([self._make_stage(features, size) for size in sizes]) self.bottleneck = nn.Conv2d(features * 2, out_features, kernel_size=1) self.relu = nn.ReLU() def _make_stage(self, features, size): prior = nn.AdaptiveAvgPool2d(output_size=(size, size)) conv = nn.Conv2d(features, features, kernel_size=1, bias=False) return nn.Sequential(prior, conv) def forward(self, feats): h, w = feats.size(2), feats.size(3) priors = [F.interpolate(input=stage(feats), size=(h, w), mode='bilinear', align_corners=True) for stage in self.stages] + [feats] bottle = self.bottleneck(torch.cat(priors, 1)) return self.relu(bottle) class PSPUpsample(nn.Module): def __init__(self, in_channels, out_channels): super().__init__() self.conv = nn.Sequential( nn.Conv2d(in_channels, out_channels, 3, padding=1), nn.BatchNorm2d(out_channels), nn.PReLU() ) def forward(self, x): h, w = 2 * x.size(2), 2 * x.size(3) p = F.interpolate(input=x, size=(h, w), mode='bilinear', align_corners=True) return self.conv(p) class PSPNet(nn.Module): def __init__(self, n_classes=21, sizes=(1, 2, 3, 6), psp_size=2048, deep_features_size=1024, backend='resnet50'): super().__init__() backbone = resnet50(weights=ResNet50_Weights.IMAGENET1K_V1).features[:-1] self.feats = nn.Sequential(*list(backbone.children())[:7]) # Extracts up to layer 7 of the pretrained model. self.psp = PSPModule(psp_size, 1024, sizes) self.drop_1 = nn.Dropout2d(p=0.3) self.up_1 = PSPUpsample(1024, 256) self.up_2 = PSPUpsample(256, 64) self.up_3 = PSPUpsample(64, 64) self.final = nn.Sequential( nn.Conv2d(64, n_classes, kernel_size=1), nn.LogSoftmax(dim=1) ) self.classifier = nn.Linear(deep_features_size, n_classes) def forward(self, x): f = self.feats(x) p = self.psp(f) p = self.drop_1(p) u1 = self.up_1(p) u2 = self.up_2(u1) u3 = self.up_3(u2) return self.final(u3) ```
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值