【Semantic Segmentation】语义分割综述 -- Pyramid & Multi-Path
Pyramid & Multi-Path
使用图像金字塔或者特征金字塔的方式增强利用空间上下文的能力。
[RefineNet] Multi-Path Refinement Networks for High-Resolution Semantic Segmentation 2016-11
https://arxiv.org/abs/1611.06612?context=cs.CV
注意ResNet去除了BN.
[PSPNet] Pyramid Scene Parsing Network 2016-12
https://arxiv.org/abs/1612.01105
PSPNet 结构如上图所示,通过backbone提取的feature,送入PPM结构,提取不同size的语意特征,大的pool对小物体敏感,小的pool对大物体敏感,因为感受野随着feature map 的 size 缩小而提升。
b)feature map zise 较原图缩小8倍。
[PPM] Pyramid Pooling Module
c) 图pytorch 代码如下
class PPM(nn.Module):
def __init__(self, in_ch):
super(PPM, self).__init__()
out_ch = int(in_ch / 4)
self.ppm1 = nn.Sequential(
nn.AdaptiveAvgPool2d((1, 1)),
nn.Conv2d(in_ch, out_ch, 1, bias=False),
nn.BatchNorm2d(out_ch),
nn.ReLU(inplace=True),
)
self.ppm2 = nn.Sequential(
nn.AdaptiveAvgPool2d((2, 2)),
nn.Conv2d(in_ch, out_ch, 1, bias=False),
nn.BatchNorm2d(out_ch),
nn.ReLU(inplace=True),
)
self.ppm3 = nn.Sequential(
nn.AdaptiveAvgPool2d((3, 3)),
nn.Conv2d(in_ch, out_ch, 1, bias=False),
nn.BatchNorm2d(out_ch),
nn.ReLU(inplace=True),
)
self.ppm4 = nn.Sequential(
nn.AdaptiveAvgPool2d((6, 6)),
nn.Conv2d(in_ch, out_ch, 1, bias=False),
nn.BatchNorm2d(out_ch),
nn.ReLU(inplace=True),
)
def forward(self, x):
size = (x.size(2), x.size(3))
ppm1 = F.interpolate(self.ppm1(x),
size=size,
mode='bilinear',
align_corners=True)
ppm2 = F.interpolate(self.ppm2(x),
size=size,
mode='bilinear',
align_corners=True)
ppm3 = F.interpolate(self.ppm3(x),
size=size,
mode='bilinear',
align_corners=True)
ppm4 = F.interpolate(self.ppm4(x),
size=size,
mode='bilinear',
align_corners=True)
ppm = torch.cat([x, ppm1, ppm2, ppm3, ppm4], dim=1)
return ppm
AdaptiveAvgPool2d 是一种自适应平均卷积,只需要输入想要输出的feature map的size,就可以得到池化后的feature map,保持其他维度size 不变。不需要设置的stride,pad,dilated。
import torch.nn as nn # target output size of 5x7 m = nn.AdaptiveAvgPool2d((5,7)) input = torch.randn(1, 64, 8, 9) output = m(input) print(output.shape) # Out[20]: torch.Size([1, 64, 5, 7]) # target output size of 14,15 m = nn.AdaptiveAvgPool2d((14,15)) output = m(input) print(output.shape) # Out[24]: torch.Size([1, 64, 14, 15])
[GCN] Large Kernel Matters —— Improve Semantic Segmentation by Global Convolutional Network 2017-03
https://arxiv.org/abs/1703.02719
GCN 是face ++ 提出的对于FCN 的改进,结构如下,类似于U-Net,但是在特征融合时,采用了不同的结构。
第一个点,GCN 结构是将中间过程的feature map 用
k
×
1
+
1
×
k
k\times 1+1\times k
k×1+1×k 和
1
×
k
+
k
×
1
1\times k+k\times 1
1×k+k×1去提取空间信息,随着
k
k
k取值的增大,最终的mIOU越高,证明了大kernel size对于效果的提升。
论文进一步讨论了
k
k
k选取的影响,把GCN替换为
k
×
k
k \times k
k×k的conv,结果就是参数量的剧增会导致not converge 以及 overfit 。另外在这种spatial上的neckbottle,确实和空间上的neckbottle会有同样的效果。
第二个点 BR (Boundary Refinement) 就是把中间卷积改为残差结构,效果提升0.02。