zoukankan      html  css  js  c++  java
  • 计算机视觉

    引言

    已经有很多U-Net-Like的神经网络被提出。

    U-Net适用于医学图像分割、自然图像生成。

    在医学图像分割表现好:

    1. 因为利用了底层的特征(同分辨率级联)改善上采样的信息不足。

    2. 医学图像数据一般较少,底层的特征其实很重要。

    不只是医学图像,对于二分类的语义分割问题,类 UNet 结构均取得不错的效果。linknet、large kernel 和 Tiramisu 等模型的效果也不错,但不如类 UNet 结构

    本文的内容主要是根据我在 Kaggle TGS Salt Identification Challenge 比赛中所做的尝试,以及别人分享的实验结果。

    一、损失函数

    1. 最常见的损失函数就是 binary cross entropy loss 结合 dice coeff loss
      前者是像素级别的损失函数
      后者是图像级别或者是 batch 级别的损失函数,适合基于以 IOU 作为评价指标的问题。

    2. online bootstrapped cross entropy loss
      比如FRNN,难样本挖掘的一种

    3. lovasz loss
      来自论文 The Lovasz-Softmax loss: A tractable surrogate for the optimization of the intersection-over-union measure in neural networks
      也是适合以 IOU 作为评价指标的问题。

    二、网络的 Backbone

    比较流行的 Backbone 如 SE-ResNeXt101,SE-ResNeXt50,SE-ResNet101,我觉得在数据集不是特别充足的情况下,差别不大。
    由于显存的限制,我用的是 ResNet34
    之前做的一些实例检测,实例分割问题,用 ResNet50 的效果也和 ResNet101 差不多。

    三、基于 Attention 的 UNet

    Concurrent Spatial and Channel Squeeze & Excitation in Fully Convolutional Networks
    SE-Net 中的 SE 结构就是对 feature maps 中的不同 channel 进行加权处理。
    这篇论文中把这种 attention 通用化,SE-Net 中采用的是 cSELayer,还有对不同的 position 进行加权的 sSELayer,以及两种加权方式结合起来的 scSELayer
    论文中的实验表明这些 Attention-Gated 结构,放在 不同阶段的 encoder 和 decoder 之后,比起不加 attention,效果更好

    class cSELayer(nn.Module):
        def __init__(self, channel, reduction=2):
            super(cSELayer, self).__init__()
            self.avg_pool = nn.AdaptiveAvgPool2d(1)
            self.fc = nn.Sequential(
                nn.Linear(channel, channel // reduction),
                nn.ELU(inplace=True),
                nn.Linear(channel // reduction, channel),
                nn.Sigmoid()
            )
            
        def forward(self, x):
            b, c, _, _ = x.size()
            y = self.avg_pool(x).view(b, c)
            y = self.fc(y).view(b, c, 1, 1)
            return x * y
    
    
    class sSELayer(nn.Module):
        def __init__(self, channel):
            super(sSELayer, self).__init__()
            self.fc = nn.Conv2d(channel, 1, kernel_size=1)
            self.sigmoid = nn.Sigmoid()
    
        def forward(self, x):
            y = self.fc(x)
            y = self.sigmoid(y)
            return x * y
    
    
    class scSELayer(nn.Module):
        def __init__(self, channels, reduction=2):
            super(scSELayer, self).__init__()
            self.sSE = sSELayer(channels)
            self.cSE = cSELayer(channels, reduction=reduction)
    
        def forward(self, x):
            sx = self.sSE(x)
            cx = self.cSE(x)
            x = sx + cx
            return x
    

    四、关于 Context

    class Dblock(nn.Module):
        def __init__(self, channel):
            super(Dblock, self).__init__()
            self.dilate1 = nn.Conv2d(channel, channel, kernel_size=3, dilation=1, padding=1)
            self.dilate2 = nn.Conv2d(channel, channel, kernel_size=3, dilation=2, padding=2)
            self.dilate3 = nn.Conv2d(channel, channel, kernel_size=3, dilation=4, padding=4)
            for m in self.modules():
                if isinstance(m, nn.Conv2d):
                    if m.bias is not None:
                        m.bias.data.zero_()
    
        def forward(self, x):
            dilate1_out = F.relu(self.dilate1(x), inplace=True)
            dilate2_out = F.relu(self.dilate2(dilate1_out), inplace=True)
            dilate3_out = F.relu(self.dilate3(dilate2_out), inplace=True)
    
            out = x + dilate1_out + dilate2_out + dilate3_out
            return out
    

    OCNet: Object Context Network for Scene Parsing
    对于语义分割,模型既需要高纬度的上下文信息(全局信息),又需要分辨率能力(即图片的局部信息)。UNet 通过 concatenate 来提高图片的局部信息。那么如何获得更好的全局信息呢。OCNet论文中对 UNet 结构中间的 center block 进行了讨论。

    五、Hyper columns

    Hypercolumns for Object Segmentation and Fine-grained Localization

    
            d5 = self.decoder5(center)
            d4 = self.decoder4(d5, e4) 
            d3 = self.decoder3(d4, e3) 
            d2 = self.decoder2(d3, e2) 
            d1 = self.decoder1(d2, e1)
    
            f = torch.cat((
                d1,
                F.interpolate(d2, scale_factor=2, mode='bilinear', align_corners=False),
                F.interpolate(d3, scale_factor=4, mode='bilinear', align_corners=False),
                F.interpolate(d4, scale_factor=8, mode='bilinear', align_corners=False),
                F.interpolate(d5, scale_factor=16, mode='bilinear', align_corners=False),
            ), 1)
    
    

    六、关于 Deep Supervision

  • 相关阅读:
    Android 中的selector
    Android 中SimpleDateFormat的使用注意
    Android 和iOS中 View的滚动
    Android 和iOS中 Gesture 和 Touch
    iOS 的UIWindow 类研究
    iOS keyChain 的使用
    关于Intent ,Task, Activity的理解
    Android Broadcast 和 iOS Notification
    Android 程序中得到root activity的引用
    ios中的addChildViewController 和 android中的fragment
  • 原文地址:https://www.cnblogs.com/viredery/p/semantic_segmentation_2.html
Copyright © 2011-2022 走看看