【语义分割】LinkNet从0到1和代码实现

这篇具有很好参考价值的文章主要介绍了【语义分割】LinkNet从0到1和代码实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言

已经有了U-net了,为什么需要linkNet?
unet见这个文章【语义分割】unet结构和代码实现:https://blog.csdn.net/weixin_40293999/article/details/129648032
它引入了resNet,主打一个RealTime,实时系统,用于自动驾驶等需要快速返回结果的领域。unet适合医疗诊断等不那么实时的地方。它也借鉴了自编码器的结构。
论文:https://arxiv.org/pdf/1707.03718.pdf 是2017年的一篇文章,才5页,值得一读。介绍了一种新的深度神经网络架构,可以高效地进行像素级语义分割,用于视觉场景理解。该网络仅使用了1150万个参数和21.2 GFLOPs,既准确又快速。


1.网络结构

1.1 网络结构示意图

【语义分割】LinkNet从0到1和代码实现
【语义分割】LinkNet从0到1和代码实现
是在论文上copy的,建议直接看论文.

1.2 创建LinkNet模型

LinkNet由4个基础模块就能搭建出整个模型
1.卷积模块(卷积+BN+Activate)
2.反卷积(反卷积+BN+Activate)
3.编码器(4个卷积模块)
4.解码器(卷积模块+反卷积模块+卷积模块)
5.实现整体网络结构(1,2,3,4搭积木即可):卷积模块+反卷积模块+编码器+解码器

2.代码

2.1 各模块搭建

2.1.1 卷积模块

卷积模块,初始化默认kernel_size=3, stride = 1, padding =1 ,也就是特征图大小原样输出。
然后呢用sequential把它们处理成一个pipline

# 卷积模块
class ConvBlock(nn.Module):
    def __init__(self, in_channels, out_channels,k_size=3,stride=1,pad=1) -> None:
        super().__init__()
        self.conv_bn_relu = nn.Sequential(
            nn.Conv2d(in_channels, out_channels,kernel_size=k_size,stride,padding=pad),
            nn.BatchNorm2d(out_channels),
            nn.ReLU(inplace=True)
            )
    
    def farward(self,x):
        x = self.conv_bn_relu(x)
        return x

2.1.2 反卷积模块

反卷积需要有两个padding, padding 是反卷积开始的位置, output_padding 将反卷积之后的图像的边缘部分进行填充

class DeconvBlock(nn.Module):
    def __init__(self, in_channels, out_channels,k_size=3,stride=2,padding=1,output_padding = 1) -> None:
        """
        反卷积需要有两个padding
        """
        super().__init__()
        #padding 是反卷积开始的位置, output_padding 将反卷积之后的图像的边缘部分进行填充
        self.deconv = nn.ConvTranspose2d(in_channels,out_channels,kernel_size=k_size,stride=stride,padding=padding,output_padding=output_padding)
        self.bn = nn.BatchNorm2d(out_channels)
    
    def farward(self,x, is_act=True):
        x = self.deconv(x)
        if is_act:
            x = torch.relu(self.bn(x))
        return x

2.1.3 编码器模块

复用卷积模块卷
【语义分割】LinkNet从0到1和代码实现
4个基础卷积块+一个shortcut块, 这里需要说明下,因为整个4个卷积中,缩放了1倍,所以shortcut也需要做相应处理,否则加不起来。

class EncodeBlock(nn.Module):
   def __init__(self, in_channels, out_channels) -> None:
       super().__init__()
       # 第一层需要对图像进行缩放
       self.conv1 = ConvBlock(in_channels,out_channels,stride=2)
       # 第2层不需要对图像进行缩放
       self.conv2 = ConvBlock(out_channels,out_channels)
       # 第三层,第四层原样输出
       self.conv3 = ConvBlock(out_channels,out_channels)
       self.conv4 = ConvBlock(out_channels,out_channels)
           
       self.short_cut =  ConvBlock(in_channels,out_channels,stride=2)
   def farward(self,x):
       out1 = self.conv1(x)
       out1 = self.conv2(out1)
       short_cut = self.short_cut(x)
       # 第一部分的输出和shortcut相加
       out2 = self.conv3(out1+short_cut)
       out2 = self.conv4(out2)
       return out2 + out1

2.2 编码网络结构

还是需要看一下这个网络结构图
【语义分割】LinkNet从0到1和代码实现
开始搭建积木


class Net(nn.Module):
    def __init__(self) -> None:
        super().__init__()
        # 第一层
        self.input_conv = ConvBlock(3,64,stride=2,k_size=7,pad=3)
        # maxpool 原来的图像缩放2倍
        self.input_maxpool = nn.MaxPool2d(kernel_size=2)
        # 四个编码器模块,通道扩大一倍,size减小一倍
        self.encode1 = EncodeBlock(64,64)
        self.encode2 = EncodeBlock(64,128)
        self.encode3 = EncodeBlock(128,256)
        self.encode4 = EncodeBlock(256,512)
        # 四个解码模块,和encode是对应的,通道数减小,size扩大为原来的一倍
        self.decode4 = DeconvBlock(512,256)
        self.decode3 = DeconvBlock(256,128)
        self.decode2 = DeconvBlock(128,64)
        self.decode1 = DeconvBlock(64,64)
        # 输出部分,第一层走默认即可
        self.deconv_out1 = DeconvBlock(64,32)
        self.conv_out = ConvBlock(32,32)
        # stride 为2 可以不写, 一共就是2分类。kesize=2,因为论文给的是2x2的,2x2的适合 padding是不需要变化的,都是0 保证正好变为原来的2倍,因为stride正好是2
        self.deconv_out2 = DeconvBlock(32,2,k_size=2,padding=0,output_padding=0)
        
    def farward(self,x):
        # input 的两层
        x = self.input_conv(x)
        x = self.input_maxpool(x)
        # 后面的中间值要保留
        e1 = self.encode1(x)
        e2 = self.encode2(e1)
        e3 = self.encode3(e2)
        e4 = self.encode3(e3)
        # 到此为止,左边半拉,完成
        
        d4 = self.decode4(e4)
        d3 = self.decode3(d4+e3)
        d2 = self.decode2(d3+e2)
        d1 = self.decode2(d2+e1)
        f1 = self.deconv_out1(d1)
        f2 = self.conv_out(f1)
        f3 = self.deconv_out2(f2)
        return f3

初始化一下看看结构

 Output exceeds the size limit. Open the full output data in a text editor
Net(
(input_conv): ConvBlock(
  (conv_bn_relu): Sequential(
    (0): Conv2d(3, 64, kernel_size=(7, 7), stride=(1, 1), padding=(3, 3))
    (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
    (2): ReLU(inplace=True)
  )
)
(input_maxpool): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(encode1): EncodeBlock(
  (conv1): ConvBlock(
    (conv_bn_relu): Sequential(
      (0): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
      (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (2): ReLU(inplace=True)
    )
  )
  (conv2): ConvBlock(
    (conv_bn_relu): Sequential(
      (0): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
      (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (2): ReLU(inplace=True)
    )
  )
  (conv3): ConvBlock(
...
(deconv_out2): DeconvBlock(
  (deconv): ConvTranspose2d(32, 2, kernel_size=(2, 2), stride=(2, 2))
  (bn): BatchNorm2d(2, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)

2.3 损失函数&训练

model = Net()
loss_fn = nn.CrossEntropyLoss()

它的训练和unet训练几乎是一模一样的,添加了IOU指标。
IOU 指标
张量与张量的除法用 torch.true_divide(tensor1,tesor2)

2.4 训练

训练起来了

Output exceeds the size limit. Open the full output data in a text editor
epoch:  0 loss:  0.072 accuracy: 0.806 IOU: 0

      test_loss:  0.071 test_accuracy: 0.81 test_iou: 0
epoch:  1 loss:  0.072 accuracy: 0.806 IOU: 0

      test_loss:  0.07 test_accuracy: 0.81 test_iou: 0
epoch:  2 loss:  0.071 accuracy: 0.807 IOU: 0

      test_loss:  0.07 test_accuracy: 0.809 test_iou: 0
epoch:  3 loss:  0.071 accuracy: 0.807 IOU: 0

      test_loss:  0.07 test_accuracy: 0.811 test_iou: 0
epoch:  4 loss:  0.071 accuracy: 0.807 IOU: 0

      test_loss:  0.071 test_accuracy: 0.81 test_iou: 0
epoch:  5 loss:  0.071 accuracy: 0.807 IOU: 0

      test_loss:  0.07 test_accuracy: 0.81 test_iou: 0
epoch:  6 loss:  0.071 accuracy: 0.808 IOU: 0

      test_loss:  0.07 test_accuracy: 0.81 test_iou: 0
epoch:  7 loss:  0.071 accuracy: 0.808 IOU: 0

      test_loss:  0.071 test_accuracy: 0.81 test_iou: 0
epoch:  8 loss:  0.071 accuracy: 0.809 IOU: 0
...
      test_loss:  0.07 test_accuracy: 0.81 test_iou: 0
epoch:  9 loss:  0.071 accuracy: 0.809 IOU: 0

      test_loss:  0.071 test_accuracy: 0.809 test_iou: 0

【语义分割】LinkNet从0到1和代码实现
数据集一览文章来源地址https://www.toymoban.com/news/detail-436924.html

到了这里,关于【语义分割】LinkNet从0到1和代码实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Python&语义分割】Segment Anything(SAM)模型全局语义分割代码+掩膜保存(二)

    我上篇博文分享了Segment Anything(SAM)模型的基本操作,这篇给大家分享下官方的整张图片的语义分割代码(全局),同时我还修改了一部分支持掩膜和叠加影像的保存。 1.1 概况         Meta AI 公司的 Segment Anything 模型是一项革命性的技术,该模型能够根据文本指令或图像

    2024年02月03日
    浏览(34)
  • 复现PointNet++(语义分割网络):Windows + PyTorch + S3DIS语义分割 + 代码

    Windows 10 GPU RTX 3090 + CUDA 11.1 + cudnn 8.9.6 Python 3.9 Torch 1.9.1 + cu111 所用的原始代码:https://github.com/yanx27/Pointnet_Pointnet2_pytorch Stanford3dDataset_v1.2_Aligned_Version 分享给有需要的人,代码质量勿喷。 对源代码进行了简化和注释。 分割结果保存成txt,或者利用 laspy 生成点云。 别问为啥在

    2024年01月21日
    浏览(33)
  • 【语义分割】ST_Unet论文 逐步代码解读

    主要工程文件为这5个 分别作用为: 构造相应的deform 卷积 DCNN的残差网络 编写相应的配置文件,可以改变相应参数 模型的主函数和主框架 模型的连接部分 代码框架由3部分组成,encode,decode和decode中将图像还原成语义分割预测图 Transformer(config, img_size) 组成编码部分,包含主

    2024年02月07日
    浏览(32)
  • 使用爬虫代码获得深度学习目标检测或者语义分割中的图片。

    问题描述:目标检测或者图像分割需要大量的数据,如果手动从网上找的话会比较慢,这时候,我们可以从网上爬虫下来,然后自己筛选即可。 代码如下(不要忘记安装代码依赖的库): 这里以搜索明星的图片为例,运行代码,然后根据提示输入搜索图片的名字→搜索图片

    2024年02月10日
    浏览(38)
  • 【Python&语义分割】Segment Anything(SAM)模型详细使用教程+代码解释(一)

    1.1 概况         Meta AI 公司的 Segment Anything 模型是一项革命性的技术,该模型能够根据文本指令或图像识别,实现对任意物体的识别和分割。这一模型的推出,将极大地推动计算机视觉领域的发展,并使得图像分割技术进一步普及化。         论文地址:https://arxiv.org/

    2024年02月05日
    浏览(41)
  • 语义分割系列11-DAnet(pytorch实现)

    DAnet:Dual Attention Network for Scene Segmentation 发布于CVPR2019,本文将进行DAnet的论文讲解和复现工作。 DAnet的思想并没有之前提到的DFAnet那么花里胡哨,需要各种多层次的连接,DAnet的主要思想就是——同时引入了空间注意力和通道注意力,也就是Dual Attention = Channel Attention + Posit

    2023年04月13日
    浏览(41)
  • vscode搭建OpenCV环境(默认已经有了vscode)

    @[TOC](这里写目录标题) # 一.文件下载: ## 1.MinGW下载 ## 2.Cmake下载 ## 3.Opencv下载 # 二.配置环境变量: # 三.vscode 配置 ## 1、launch.json ## 2、c_ cpp_ properties json ## 3、tasks json # 四.测试 1.MinGW下载(MinGW-w64 - for 32 and 64 bit Windows - Browse Files at SourceForge.net) 单独在一个盘里面新建一个文

    2024年02月06日
    浏览(33)
  • 利用torchvision库实现目标检测与语义分割

    利用torchvision库实现目标检测与语义分割。         Pytorch预训练模型、内置模型实现图像分类、检测和分割

    2024年02月10日
    浏览(24)
  • 语义分割系列7-Attention Unet(pytorch实现)

    继前文Unet和Unet++之后,本文将介绍Attention Unet。 Attention Unet地址,《Attention U-Net: Learning Where to Look for the Pancreas》。 Attention Unet发布于2018年,主要应用于医学领域的图像分割,全文中主要以肝脏的分割论证。 Attention Unet主要的中心思想就是提出来Attention gate模块,使用soft-at

    2024年02月06日
    浏览(26)
  • 已经有了阿里云OSS还需要开通CDN吗?

        单一的OSS模式,计费包括存储和外网流出费用,目前通常比较流行的方式是 OSS + CDN 的组合模式,OSS负责存储,CDN负责加速,那么只从流量费用的层面来说,采用 OSS + CDN 组合模式比单一OSS模式更加经济和省钱,当然,从安全角度来说采用 OSS + CDN 组合模式也更有优势。

    2024年01月16日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包