U-Net神经网络简明教程

news2024/12/29 8:57:40

在这里插入图片描述

推荐:用 NSDT编辑器 快速搭建可编程3D场景

在我们进入技术细节之前,考虑一下,为什么要使用 U-Net? 你可能在搜索语义分割时遇到过这一点,我很快就会写一篇博客,然后再看看这个。 制作此架构的初衷是用于生物医学图像分割。 如今,它是任何形式的语义分割中最流行的网络,并且该技术也被广泛应用于各种 Kaggle 竞赛中,作为解决大量计算机视觉问题的极其可靠的方法。

1、什么是跳跃连接?

为了理解 U-Net,我们需要理解跳跃连接(skip connection)背后的直觉。 这只是为了更好地了解正在发生的情况,实际论文/模型中并未明确使用它。

跳跃连接,顾名思义,是从网络的较早部分到较晚部分建立的连接,并传输信息。 这背后的直觉非常简单:我们希望找回某些层上丢失的信息,以便为网络提供更好的上下文。 在多个卷积过程的过程中,当网络深入到较低级别的特征时,它会丢失较高级别特征的上下文。 通过跳跃连接发送丢失的信息,即在两层之间建立的连接不按照发送信息的实际顺序。

在这里插入图片描述

在这里我们可以看到如何将输入添加到网络的输出以获得新的输出

2、跳跃连接和U-Nets有什么关系?

简单:卷积过程背后的想法或直觉是双重的:提取特征,并减少较小图像上的计算时间。 然而,它会在此过程中丢失信息。 U-Net 充分利用了两个方面的优点,这样当我们对图像进行上采样或放大时,我们会将特征映射连接到相应的放大后的映射集。
在这里插入图片描述

现在这张图应该更有意义了!

观察跳跃连接如何工作。 对于第一个逆卷积过程,发送了最后一个卷积过程的特征图。 对于第二个逆卷积,倒数第二个,以此类推。 引用论文作者(Olaf Ronneberger、Philipp Fischer 和 Thomas Brox)的话:

为了预测图像边界区域中的像素,通过镜像输入图像来推断丢失的上下文。

正如作者所说的那样,该网络的一个重要特点是该网络能够在极少的数据上进行过度增强的训练,并且训练的准确性很高。

3、U-Net实现代码

我将使用 pytorch 来完成此操作,如果您想了解 TensorFlow/keras 的方法,请尝试这篇文章(一直在底部)。 让我们从定义一些辅助类开始。

class DoubleConv(nn.Module):
    """(convolution => [BN] => ReLU) * 2"""

    def __init__(self, in_channels, out_channels):
        super().__init__()
        self.double_conv = nn.Sequential(
            nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1),
            nn.BatchNorm2d(out_channels),
            nn.ReLU(inplace=True),
            nn.Conv2d(out_channels, out_channels, kernel_size=3, padding=1),
            nn.BatchNorm2d(out_channels),
            nn.ReLU(inplace=True)
        )

    def forward(self, x):
        return self.double_conv(x)

首先,双卷积层,因为每个单独的块都使用其中之一,而不管上采样或下采样。

class Down(nn.Module):
    """Downscaling with maxpool then double conv"""

    def __init__(self, in_channels, out_channels):
        super().__init__()
        self.maxpool_conv = nn.Sequential(
            nn.MaxPool2d(2),
            DoubleConv(in_channels, out_channels)
        )

    def forward(self, x):
        return self.maxpool_conv(x)

然后是使用我们之前制作的 Double Conv 的下采样模块。

class Up(nn.Module):
    """Upscaling then double conv"""

    def __init__(self, in_channels, out_channels, bilinear=True):
        super().__init__()

        # if bilinear, use the normal convolutions to reduce the number of channels
        if bilinear:
            self.up = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True)
        else:
            self.up = nn.ConvTranspose2d(in_channels // 2, in_channels // 2, kernel_size=2, stride=2)

        self.conv = DoubleConv(in_channels, out_channels)

    def forward(self, x1, x2):
        x1 = self.up(x1)
        # input is CHW
        diffY = torch.tensor([x2.size()[2] - x1.size()[2]])
        diffX = torch.tensor([x2.size()[3] - x1.size()[3]])

        x1 = F.pad(x1, [diffX // 2, diffX - diffX // 2,
                        diffY // 2, diffY - diffY // 2])
        return self.conv(x1)

现在是上采样模块,再次使用 DoubleConv。 请注意我们如何在双线性上采样和转置卷积过程之间进行选择。 我们选择双线性只是因为研究表明它能提供更好的结果,而且论文还提到可以尝试转置。

class OutConv(nn.Module):
    def __init__(self, in_channels, out_channels):
        super(OutConv, self).__init__()
        self.conv = nn.Conv2d(in_channels, out_channels, kernel_size=1)

    def forward(self, x):
        return self.conv(x)

最后,最后一层的类,具有完成分割颜色图所需的输出通道数。

现在,让我们将其全部应用到模型本身中。 我在这里使用了一些来自之前项目的超参数,请随意根据你的需求进行调整。

class UNet(nn.Module):
    def __init__(self, n_channels, n_classes, bilinear=True):
        super(UNet, self).__init__()
        self.n_channels = n_channels
        self.n_classes = n_classes
        self.bilinear = bilinear

        self.inc = DoubleConv(n_channels, 64)
        self.down1 = Down(64, 128)
        self.down2 = Down(128, 256)
        self.down3 = Down(256, 512)
        self.down4 = Down(512, 512)
        self.up1 = Up(1024, 256, bilinear)
        self.up2 = Up(512, 128, bilinear)
        self.up3 = Up(256, 64, bilinear)
        self.up4 = Up(128, 64, bilinear)
        self.outc = OutConv(64, n_classes)

    def forward(self, x):
        x1 = self.inc(x)
        x2 = self.down1(x1)
        x3 = self.down2(x2)
        x4 = self.down3(x3)
        x5 = self.down4(x4)
        x = self.up1(x5, x4)
        x = self.up2(x, x3)
        x = self.up3(x, x2)
        x = self.up4(x, x1)
        logits = self.outc(x)
        return logits

应该很容易理解这里发生的事情(所有 pytorch 和它的 pythonic 代码风格)。 请密切注意我们如何将 x4、x3 等与其相应的上采样块一起传递,以模拟 U-Net 设计,并且它是跳过连接。 我们将该 x3 发送到两个位置:发送到下一个块以进行下采样,以及用于保存第二个上采样块上采样的数据。

4、U-Net应用领域

正如我们上面所讨论的,U-Net的最大用途是语义分割,并且迄今为止在该领域表现出色。

在这里插入图片描述

一项非常受欢迎的 Kaggle 竞赛,旨在创建这些汽车的掩码以便于提取

5、结束语

希望你对 unets 是什么以及它们如何工作有一个很好的了解,或者至少了解它们如何工作背后的直觉。 Good Day!


原文链接:U-Net简明教程 — BimAnt

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

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

相关文章

Spring MVC程序开发(JavaEE进阶系列3)

目录 前言: 1.什么是Spring MVC 1.1MVC的定义 1.2MVC和Spring MVC的关系 1.3为什么要学习Spring MVC 2.Spring MVC项目的创建 3.Spring MVC框架的使用 3.1连接的功能 3.1.1RequestMapping 3.1.2GetMapping 3.1.3PostMapping 3.2获取参数的功能 3.2.1获…

罗彻斯特大学探讨ChatGPT等人工智能将如何影响高等教育

人工智能聊天机器人ChatGPT持续引起互联网用户的热议,它能够回答关于各个领域的问题,创作歌曲、食谱,起草电子邮件等等。罗切斯特的教职员工和管理人员就他们如何处理 ChatGPT 以及它如何影响未来的教学和学习提出了他们的想法。 “让这项技…

基于Java的新能源汽车在线租赁平台设计与实现(源码+lw+ppt+部署文档+视频讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序(小蔡coding)有保障的售后福利 代码参考源码获取 前言 💗博主介绍:✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…

基于ChatGPT快速入门体验NLP词云

基于ChatGPT快速入门体验NLP词云 一、什么是自然语言处理二、自然语言处理和词云的关系三、Python环境准备四、基于ChatGpt制作词云4.1 ChatGPT生成初级词云代码4.2 ChatGPT生成进阶词云代码4.3 基于ChatGPT解决代码问题4.4 基于ChatGPT建议修改问题代码 一、什么是自然语言处理…

c语言进阶部分详解(详细解析字符串常用函数,并进行模拟实现)

前段时间也是把指针较为详细系统的讲解完毕,接下来介绍一个全新的知识点,就是字符函数和字符串函数 前几期文章可进我主页观看:总之就是非常唔姆_Matlab,经验分享,c语言题目分享-CSDN博客 想要源代码可以去我的github看看:Neros…

教你拥有一个自己的QQ机器人!0基础超详细保姆级教学!基于NoneBot2 Windows端搭建QQ机器人

0.序言 原文链接:教你本地化部署一个QQ机器人本教程主要面向Windows系统用户教程从0开始全程详细指导,0基础萌新请放心食用🍕如果你遇到了问题,请仔细检查是否哪一步有遗漏。如果你确定自己的操作没问题,可以到原文链…

苹果macbook电脑磁盘满了怎么清理内存

如果你是苹果macbook用户,可能会面临一个常见但又令人头疼的问题——磁盘空间不足。这不仅影响了你的电脑性能,还可能导致新的软件无法安装,甚至影响到文件的保存。好消息是,有多种方法可以有效地解决这个问题。下面就一起来看看吧…

【100个 Unity实用技能】☀️ | UGUI Text中加入超链接文本,可直接点击跳转

Unity 小科普 老规矩,先介绍一下 Unity 的科普小知识: Unity是 实时3D互动内容创作和运营平台 。包括游戏开发、美术、建筑、汽车设计、影视在内的所有创作者,借助 Unity 将创意变成现实。Unity 平台提供一整套完善的软件解决方案&#xff…

unity脚本_Input鼠标键盘 c#

获取鼠标坐标 检测鼠标输入 如果在运行游戏场景中点击一下鼠标左键 检测鼠标抬起 选中即可 检测键盘按下 当前屏幕分辨率 注意:获取的是显示器的分辨率 获取设备屏幕宽高 屏幕休眠模式 窗口/全屏模式 移动设备屏幕转向

【C语言】字符函数和字符串函数(1)

#国庆发生的那些事儿# 大家好,我是苏貝,本篇博客带大家了解字符函数和字符串函数,如果你觉得我写的还不错的话,可以给我一个赞👍吗,感谢❤️ 目录 1.本章重点2. strlen2.1函数介绍2.2 模拟实现 3. strcpy3…

第八章 排序 六、简单选择排序

目录 一、算法思想 二、例子 1、我们有以下序列要排序 2、首先从左往右扫描,在其中找到最小的一个数,让它与第一个数互换位置 3、此次扫描完成后,我们取新的子序列,并再次从左往右扫描,在其中找到最小的一个数&…

makeMakefile

一、 什么是make&Makefile ? ①make 是一条命令,makefile是一个文件,配合使用,通过依赖关系和依赖方法达到我们形成可执行程序的目的 ②makefile好处就是可以进行 自动化编译 ” ,极大的提高软件开发的效率,一旦写好,只需要一个 make 命令…

推荐一款在线的JDK17中文文档

spring6.0及springboot3.0最低版本要求都是java17,换上java17是迟早的事,所以虽然我现在做的是java8,但是后面我想从java8直接飞升到java17,先做个准备,找到一个JDK17的中文文档,是在线的,地址&…

数据结构刷题训练——二叉树篇(一)

📙作者简介: 清水加冰,目前大二在读,正在学习C/C、Python、操作系统、数据库等。 📘相关专栏:C语言初阶、C语言进阶、C语言刷题训练营、数据结构刷题训练营、有感兴趣的可以看一看。 欢迎点赞 &#x1f44d…

学习记忆——方法篇——整除特点

理解记忆法 对于数的整除特征大家都比较熟悉:比如4看后两位(因为100是4的倍数),8看后三位(因为1000是8的倍数),5末尾是0或5,3与9看各位数字和等等,今天重点研究一下3,9,…

创新家庭办公室:打造完美工作空间的秘诀

一个精心策划的家庭办公室有很多好处,何不把临时工作区升级改造为你的专属工作区呢,还能为这些至关重要的区域注入新的活力。 创造多用途的起居室:我们大多数人都不曾拥有一个可以完全根据工作需求设计的独立家庭办公室——所以有时候要找到…

目标检测算法改进系列之Backbone替换为RIFormer

RIFormer简介 Token Mixer是ViT骨干非常重要的组成成分,它用于对不同空域位置信息进行自适应聚合,但常规的自注意力往往存在高计算复杂度与高延迟问题。而直接移除Token Mixer又会导致不完备的结构先验,进而导致严重的性能下降。 原文地址&…

Pytorch之shuffleNet图像分类

💂 个人主页:风间琉璃🤟 版权: 本文由【风间琉璃】原创、在CSDN首发、需要转载请联系博主💬 如果文章对你有帮助、欢迎关注、点赞、收藏(一键三连)和订阅专栏哦 前言 ShuffleNet是Face(旷视)在2017年发布的一个高效率…

【傅里叶梅林图像配准】用于图像配准的傅里叶梅林相位相关性的实现(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

Python之元组

Python之元组 元组tuple 一个有序的元素组成的集合使用小括号 ( ) 表示元组是不可变对象 tuple(), (), type(()) # 空元组 ((), (), tuple)(1,), (1) # 元组中只有1必须加逗号,否则就是1了 # ((1,), 1)x 1, 2 # 以逗号分隔的内容会形成元组,封装元组x…