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

news2024/11/20 20:42:29

文章目录

  • 前言
  • 1.网络结构
    • 1.1 网络结构示意图
    • 1.2 创建LinkNet模型
  • 2.代码
    • 2.1 各模块搭建
      • 2.1.1 卷积模块
      • 2.1.2 反卷积模块
      • 2.1.3 编码器模块
    • 2.2 编码网络结构
    • 2.3 损失函数&训练
    • 2.4 训练


前言

已经有了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 网络结构示意图

在这里插入图片描述
在这里插入图片描述
是在论文上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 编码器模块

复用卷积模块卷
在这里插入图片描述
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 编码网络结构

还是需要看一下这个网络结构图
在这里插入图片描述
开始搭建积木


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

在这里插入图片描述
数据集一览

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/502104.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Docker基础篇(很详细)

一、简单介绍 (一)为什么用docker 开发人员发开完成就发布一个jar或者war包,其他的都交给运维人员来做;而现在,开发即运维,打包部署上线一套流程走完:开发人员会将项目及其附带的环境一起打包j…

UML类图使用介绍

文章目录 一、UML图1、什么是UML图2、类图概述3、类图的作用 二、类的表示方式举个栗子 三、类与类之间关系的表示方式1、关联关系(1)单向关联(2)双向关联(3)自关联 2、聚合关系3、组合关系4、依赖关系5、继…

安全加密基础—基本概念、keytool、openssl

前言 (1)本文不涉及源码、底层。只是讲解大概的密码演变过程和基本概念。能让接触到相关名词的人知道这些名词是干嘛的,为什么要有它。专业人士可以当作概念梳理,非专业人士可以当作科普。 (2)本文你将了解…

亿发工业互联网智能制造ERP系统,生产工厂信息化建设解决方案

亿发工业互联网智能制造ERP系统,生产工厂信息化建设解决方案 随着制造水平的发展,传统工厂原有的生产组织模式和质量管理模式已不能满足先进制造水平的要求。确保公司战略目标的实现,有必要借助信息技术加强对各种业务流程的管理。而企业走向…

Leetcode506. 相对名次

Every day a leetcode 题目来源&#xff1a;506. 相对名次 解法1&#xff1a;STL vector 自定义排序 使用 vector<pair<int, int>> 数组v记录原来 score 数组的下标和成绩。 对v按成绩进行降序排序。 新建一个 vector<string> 数组 ans&#xff0c;遍历…

WiFi(Wireless Fidelity)基础(三)

目录 一、基本介绍&#xff08;Introduction&#xff09; 二、进化发展&#xff08;Evolution&#xff09; 三、PHY帧&#xff08;&#xff08;PHY Frame &#xff09; 四、MAC帧&#xff08;MAC Frame &#xff09; 五、协议&#xff08;Protocol&#xff09; 六、安全&#x…

FP斗篷,2023独立站必看指南

Cloak斗篷技术是一种网络隐身术&#xff0c;通过技术手段实现在网络上匿名和隐身&#xff0c;保护个人隐私和安全。斗篷技术的实现原理是通过使用虚拟专用网络&#xff08;VPN&#xff09;或代理服务器等技术&#xff0c;将用户的真实IP地址隐藏起来&#xff0c;使其在网络上的…

CentOS7离线升级SSH至9.1P1

1、离线安装telnet&#xff08;用telnet登录升级ssh&#xff0c;因为ssh升级时&#xff0c;ssh会话会断开&#xff09; &#xff08;1&#xff09;下载telnet、telnet-server、xinetd&#xff0c;并传到服务器上 http://rpmfind.net/linux/centos/7.9.2009/updates/x86_64/Pack…

目前电视盒子哪个最好?测评20款后整理网络电视盒子推荐

电视盒子是日常必备的数码单品&#xff0c;功能越来越丰富&#xff0c;但很多人不懂要如何选择电视盒子&#xff0c;芯片、内存外还应该考虑系统、技术优化和界面设计等因素。昨天刚刚结束了二十款电视盒子的测评&#xff0c;马上来介绍下我的测评结果&#xff0c;整理了网络电…

flutter mqtt的使用看这里,持续更新

mqtt网络协议&#xff0c;相信跟物联网相关的公司都会遇到&#xff0c;在Android,iOS原生开发是可以很好的实现&#xff0c;相关的资料也是很多&#xff01;但是在flutter里面还算比较尝鲜的一个领域吧&#xff01; 幸亏flutter里面 已经有一个还不错的第三库mqtt_client&…

Springcloud 之Gateway组件详解

目录 1.网关 1.1 网关简介 1.2 网关组件 1.2.1 Gateway介绍 1.2.2 Gateway实践 1.2.3 Gateway执行流程 1.2.4 断言工厂 1.2.5 过滤器 1.网关 1.1 网关简介 大家都都知道在微服务架构中&#xff0c;一个系统会被拆分为很多个微服务。那么作为客户端要如何去调用这么多…

Vmware ESXi 5.0 安装与部署

在虚拟化领域VMware、Citrix、Microsoft都有不错的解决方案而在服务器虚拟化领域VMware又占据着领导者地位游侠www.2cto.com今天也装了个平台与大家一起分享。   VMware的虚拟化产品就个人、小企业而言有Workstation、ESXivSphere免费版、VMwareServer免费版可以选择由于Work…

彩蛋丨利用R语言脚本实现批量合并Excel表格,再也不用手动点来点去了!

利用R语言脚本实现批量合并Excel表格 在整理数据的时候遇到一个问题&#xff1a;假如有很多个excel表&#xff0c;分别存放了一部分数据&#xff0c;现在想要快速把这些表格的数据汇总到一起&#xff0c;如何用R语言快速完成呢&#xff1f;本文分享一个脚本&#xff0c;能够自动…

分享2个教学视频录制的方法!

案例&#xff1a;如何录制教学视频&#xff1f; 【我是一名老师&#xff0c;我想录制一些教学视频发布在网络平台上&#xff0c;但是我不知道如何操作。有没有人知道录制教学视频需要什么工具&#xff1f;如何录制&#xff1f;】 随着在线教育的普及&#xff0c;越来越多的教…

【K8s】K8s介绍与集群环境搭建

文章目录 一、Kubernetes介绍1、背景2、kubernetes简介3、组件说明4、示例&#xff1a;部署nginx说明各组件的协作5、kubernetes核心概念 二、kubernetes集群环境搭建1、部署方式2、安装要求和最终目标3、环境准备4、环境初始化5、集群测试 一、Kubernetes介绍 1、背景 在部署…

转向路线优化之算法二

0.概述 广义上的主曲线定义为穿过数据中心的自洽曲线,本文基于数据点的概率密度估计结果,得到相应的梯度Gradient和Hessian矩阵,以此求得原始数据点的主曲线拟合结果. 1.基于Gradient与Hessian的主曲线定义 一般认为可构造主曲面(含主曲线)的数据点具有某种固有的潜在概…

Java多线程入门到精通学习大全?了解线程的几种创建方式和基本原理、代码示例!(第四篇:线程的创建学习)

Java多线程的创建方式有三种&#xff1a;继承Thread类&#xff0c;实现Runnable接口和使用Callable和Future接口。 一、继承Thread类 1 原理&#xff1a; 继承Thread类&#xff0c;重写run()方法&#xff0c;将需要并发执行的代码写在run()方法中&#xff0c;创建Thread类的…

【python学习】基础篇-文件与系统-打开与读取文件、文件操作的常用方法

打开与读取文件 在 Python 中&#xff0c;内置了文件(file) 对象。 在使用文件对象时&#xff0c;首先需要通过内置的 open0 方法创建一个文件对象&#xff0c;然后通过该对象提供的方法进行基本的文件操作。 open() 函数的语法格式如下: file open(filename[,mode[,bufferin…

推荐系统学习之路

基本概念&#xff1a; 一、基本流程 b站王树森老师课程笔记 召回(retrieval&#xff09;&#xff1a;快速从海量数据中取回几千个用户可能感兴趣的物品。 方法&#xff1a; 协同过滤 相似度计算&#xff1a; 余弦&#xff0c; 杰卡德 矩阵分解&#xff1a; 将一个稀疏的用户评…

2022年宜昌市网络搭建与应用竞赛样题(三)

网络搭建与应用竞赛样题&#xff08;三&#xff09; 技能要求 &#xff08;总分1000分&#xff09; 竞赛说明 一、竞赛内容分布 “网络搭建与应用”竞赛共分三个部分&#xff0c;其中&#xff1a; 第一部分&#xff1a;网络搭建及安全部署项目&#xff08;500分&#xff0…