UNet网络解读

article/2025/8/24 4:53:05

UNet解读

  • UNet论文
  • UNet的简介
  • 代码解读
    • DoubleConv模块
    • Down模块
    • Up模块
    • OutConv模块
  • 整个UNet
  • 参考资料

UNet论文

UNet论文地址

UNet的简介

UNET

  • UNet是一个对称的网络结构,左侧为下采样,右侧为上采样
  • 下采样为encoder,上采样为decoder;
  • 四条灰色的平行线,就是在上采样的过程中,融合下采样过程的特征图的通道,Concat
    • 原理就是:一本大小为10cm10cm的书,厚度为3cm的书本(10103)的A书,和一本大小为10cm10cm,厚度为4cm的B书(10103)
    • 将A书和B书,边缘对齐的摞在一起,这样就可以得到一个大小10107的一摞书了
    • 所以对feature map,一个大小为256*256*64的feature map(w为256,h为256,c为64),和一个大小为256*256*32的feature map进行Concat融合,你就会得到一个大小为256*256*96的feature map
    • 在实际使用中,Concat融合的两个feature map的大小不一定相同,例如25625664的feature map和24024032的feature map进行Concat
      • 两种方法
        • 1.将大的256*256*64的feature map进行裁剪,裁剪为240*240*64的feature map,比如上下左右,各舍弃8 pixel,裁剪后再进行Concat,得到24024096的feature map。
        • 2.将小的240*240*32的feature map进行padding操作,padding为256*256*32的feature map,比如上下左右,各补8 pixel,padding后再进行Concat,得到25625696的feature map。
      • UNet采用的Concat方案就是第二种,将小的feature map进行padding,padding的方式是补0,一种常规的常量填充。(详细看代码Up)

代码解读

  • 组成U-Net的模型块主要有如下几个部分:

    • 1)每个子块内部的两次卷积(Double Convolution)

    • 2)左侧模型块之间的下采样连接,即最大池化(Max pooling)

    • 3)右侧模型块之间的上采样连接(Up sampling)

    • 4)输出层的处理(OutConv)

DoubleConv模块

  • 两次卷积操作:
class DoubleConv(nn.Module):# mid_channel是第一次conv的out和第二次conv的输入def __init__(self, in_channels, out_channels, mid_channels=None):super().__init__()if not mid_channels:mid_channels = out_channelsself.double_conv = nn.Sequential(# 大小 (高宽 + 2*padding - kernel_size)/stride + 1# (572 + 2*0 - 3 )/1 +1 = 570# 通道1->64nn.Conv2d(in_channels, mid_channels, kernel_size=3, padding=0, bias=False),# 帮助网络训练, 对输入数据做规范化,称为Covariate shift# BatchNorm后是不改变输入的shape# num_features: 输入维度,也就是数据的特征维度;# eps: 是在分母上加的一个值,是为了防止分母为0的情况,让其能正常计算;# affine: 是仿射变化,将,分别初始化为1和0;# nn.BatchNorm2d是对channel做归一化处理,也就是对批次内的特征进行归一化# 加快收敛,防止梯度爆炸和消失nn.BatchNorm2d(mid_channels),# inplace = True 时,会修改输入对象的值,所以打印出对象存储地址相同,类似于C语言的址传递# inplace = False 时,不会修改输入对象的值,而是返回一个新创建的对象,所以打印出对象存储地址不同,类似于C语言的值传递nn.ReLU(inplace=True),# (570 + 2*0 - 3 )/1 +1 = 568# 设置padding=1(原始的是设置为0,会改变)经过卷积后不会改变特征层的大小,这也是现在主流的实现方式nn.Conv2d(mid_channels, out_channels, kernel_size=3, padding=0, bias=False),nn.BatchNorm2d(out_channels),nn.ReLU(inplace=True))def forward(self, x):x = self.double_conv(x)return x
  • 注意代码里面的卷积是如何计算的( (高宽 + 2*padding - kernel_size)/stride + 1),如U图中的初始:(572 + 2*0 - 3 )/1 +1 = 570

Down模块

class Down(nn.Module):def __init__(self, in_channels, out_channels):super().__init__()self.maxpool_conv = nn.Sequential(nn.MaxPool2d(2),# 扩大通道64->128DoubleConv(in_channels, out_channels))def forward(self, x):return self.maxpool_conv(x)

Up模块

class Up(nn.Module):def __init__(self, in_channels, out_channels, bilinear=True):super().__init__()# 上采样需要插值,双if bilinear:# 两倍self.up = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True)self.conv = DoubleConv(in_channels, out_channels, in_channels // 2)else:# 反卷积self.up = nn.ConvTranspose2d(in_channels, 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 = x2.size()[2] - x1.size()[2]diffX = x2.size()[3] - x1.size()[3]# F.pad是pytorch内置的tensor扩充函数,便于对数据集图像或中间层特征进行维度扩充# 最后一维padding,第一个元素代表左边padding的个数,第二个元素代表右边padding的个数# input:需要扩充的tensor,可以是图像数据,抑或是特征矩阵数据# pad:扩充维度,用于预先定义出某维度上的扩充参数# mode:扩充方法,’constant‘, ‘reflect’ or ‘replicate’三种模式,分别表示常量,反射,复制# value:扩充时指定补充值,但是value只在mode='constant’有效,# 即使用value填充在扩充出的新维度位置,而在’reflect’和’replicate’模式下,value不可赋值# https://www.modb.pro/db/227153x1 = F.pad(x1, [diffX // 2, diffX - diffX // 2, diffY // 2, diffY - diffY // 2])x = torch.cat([x2, x1], dim=1)return self.conv(x)
  • __init__初始化函数里定义的上采样方法以及卷积采用DoubleConv
    • 上采样,定义了两种方法:UpsampleConvTranspose2d,也就是双线性插值反卷积

      • 双线性插值:
        双线性插值

      • 简单地讲:已知Q11、Q12、Q21、Q22四个点坐标,通过Q11和Q21求R1,再通过Q12和Q22求R2,最后通过R1和R2求P,这个过程就是双线性插值。

      • 对于一个feature map而言,其实就是在像素点中间补点,补的点的值是多少,是由相邻像素点的值决定的。

    • 反卷积:

      • 就是反着卷积

      • 反卷积

      • 下面的蓝色为原始图片,周围白色的虚线方块为padding结果,通常为0,上面绿色为卷积后的图片。

      • 这个示意图,就是一个从2*2的feature map->4*4的feature map过程

      • forward前向传播函数中x1接收的是上采样的数据x2接收的是特征融合的数据。特征融合方法就是,上文提到的,先对小的feature map进行padding,再进行concat

OutConv模块

class OutConv(nn.Module):def __init__(self, in_channels, out_channels):super(OutConv, self).__init__()  # 和super().__init__()一样self.conv = nn.Conv2d(in_channels, out_channels, kernel_size=1)def forward(self, x):return self.conv(x)

整个UNet

class UNet(nn.Module):def __init__(self, n_channels, n_classes, bilinear=True):super(UNet, self).__init__()self.n_channels = n_channelsself.n_classes = n_classesself.bilinear = bilinear# 最左边self.inc = DoubleConv(n_channels, 64)# 下采样(里面包括下采样完的两次卷积)self.down1 = Down(64, 128)self.down2 = Down(128, 256)self.down3 = Down(256, 512)# 插值方式factor = 2 if bilinear else 1self.down4 = Down(512, 1024 // factor)self.up1 = Up(1024, 512 // factor, bilinear)self.up2 = Up(512, 512 // factor, bilinear)self.up3 = Up(256, 256 // factor, 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

参考资料

  • UNet语义分割
  • F.pad的使用

http://chatgpt.dhexx.cn/article/ElvSa1SZ.shtml

相关文章

UNet网络

UNet 本博客主要对UNet网络进行讲解,以下为文章目录: UNet 原论文讲解网络结构数据集介绍评价指标损失计算代码 本文参考资料如下: UNet原论文 https://arxiv.org/pdf/1505.04597.pdfU-Net网络结构讲解(语义分割) https://www.bilibili.c…

U-Net网络详解

U-Net: Convolutional Networks for Biomedical Image Segmentation 原文地址:https://zhuanlan.zhihu.com/p/43927696 前言 U-Net是比较早的使用全卷积网络进行语义分割的算法之一,论文中使用包含压缩路径和扩展路径的对称U形结构在当时非常具有创新…

U-Net网络

U-Net普遍应用在生物医学影像领域,其在架构设计和其他利用卷积神经网络基于像素的图像分割方面更成功,它甚至对有限数据集的图像更有效。U-Net的命名源自它的结构,它的网络结构可视化的结果很像一个字母U。 U-NET网络性能机制 U-Net 融合了 …

【Unet系列】Unet Unet++

文章目录 U-net概述细节部分1、结构的解析2、一些小点 result Unet概述细节部分resultsummary U-net U-Net是一篇基本结构非常好的论文,主要是针对生物医学图片的分割,而且,在今后的许多对医学图像的分割网络中,很大一部分会采取…

图像分割UNet系列------UNet详解

图像分割unet系列------UNet详解 1、UNet网络结构2、UNet网络结构高性能的原因分析3、医学图像使用UNet网络结构 UNet最早发表在2015的MICCAI上,到2020年中旬的引用量已经超过了9700多次,估计现在都过万了,从这方面看足以见得其影响力。当然&…

UNet、UNet++、UNet3+系列

一、unet 简介 继承FCN的思想,继续进行改进。但是相对于FCN,有几个改变的地方,U-Net是完全对称的,且对解码器(应该自Hinton提出编码器、解码器的概念来,即将图像->高语义feature map的过程看成编码器&…

unet网络详解

Unet 参考文献:U-Net: Convolutional Networks for Biomedical Image Segmentation作者:Olaf Ronneberger, Philipp Fischer, and Thomas Brox 什么是Unet模型 Unet是一个优秀的语义分割模型,其主要执行过程与其它语义分割模型类似。与CNN…

Unet相关介绍

老师的bloghttps://zhuanlan.zhihu.com/p/370931792。写的比我这个好,233 Unet是在Fcn基础上提出的一种应用于医学影响的分割网络。医学影像的特点是1、数据集小。2、单张图片大。 由于以上医疗影像的特点,我们无法直接用Fcn进行分割学习。一个德国团队…

UNET详解和UNET++介绍(零基础)

一背景介绍 背景介绍: 自2015年以来,在生物医学图像分割领域,U-Net得到了广泛的应用,目前已达到四千多次引用。至今,U-Net已经有了很多变体。目前已有许多新的卷积神经网络设计方式,但很多仍延续了U-Net的核…

UNet - unet网络

目录 1. u-net介绍 2. u-net网络结构 3. u-net 网络搭建 3.1 DoubleConv 3.2 Down 下采样 3.3 Up 上采样 3.4 网络输出 3.5 UNet 网络 UNet 网络 forward 前向传播 3.6 网络的参数 4. 完整代码 1. u-net介绍 Unet网络是医学图像分割领域常用的分割网络&#xff0…

UNet 浅析

文章目录 1. UNet 简介2. UNet 详解3. 代码实例 - 医学图像分割 (ISBI数据集)【参考】 1. UNet 简介 UNet 属于 FCN 的一种变体,它可以说是最常用、最简单的一种分割模型,它简单、高效、易懂、容易构建,且可以从小数据集中训练。2015 年&…

unet 网络结构

unet 是15年提出的用于解决医学图像分割问题。unet有两部分组成。左边部分可以看出是特征提取网络,用于提取图像的抽象特征。右边可以看作是特征融合操作。与传统的FCN相比,unet使用是使用特征拼接实现特征的融合。unet 通过特征融合操作,实现了浅层的低分辨率(越底层的信息…

unet模型及代码解析

什么是unet 一个U型网络结构,2015年在图像分割领域大放异彩,unet被大量应用在分割领域。它是在FCN的基础上构建,它的U型结构解决了FCN无法上下文的信息和位置信息的弊端 Unet网络结构 主干结构解析 左边为特征提取网络(编码器&…

深度学习论文精读[6]:UNet++

UNet的编解码结构一经提出以来,大有统一深度学习图像分割之势,后续基于UNet的改进方案也经久不衰,一些研究者也在从网络结构本身来思考UNet的有效性。比如说编解码网络应该取几层,跳跃连接是否能够有更多的变化以及什么样的结构训…

【Unet系列】(三)Unet++网络

一、UNet整体网络结构 Unet主要是探索encoder和decoder需要多大的问题,以此为基础,提出了融合不同尺寸Unet结构的网络。创新点就是把不同尺寸的Uent结构融入到了一个网络里。 二、结构的好处 (1)不管哪个深度的特征有效&#…

深度学习零基础学习之路——第四章 UNet-Family中Unet、Unet++和Unet3+的简介

Python深度学习入门 第一章 Python深度学习入门之环境软件配置 第二章 Python深度学习入门之数据处理Dataset的使用 第三章 数据可视化TensorBoard和TochVision的使用 第四章 UNet-Family中Unet、Unet和Unet3的简介 第五章 个人数据集的制作 Unet-Family的学习 Python深度学习…

憨批的语义分割重制版6——Pytorch 搭建自己的Unet语义分割平台

憨批的语义分割重制版6——Pytorch 搭建自己的Unet语义分割平台 注意事项学习前言什么是Unet模型代码下载Unet实现思路一、预测部分1、主干网络介绍2、加强特征提取结构3、利用特征获得预测结果 二、训练部分1、训练文件详解2、LOSS解析 训练自己的Unet模型一、数据集的准备二、…

UNet详解(附图文和代码实现)

卷积神经网络被大规模的应用在分类任务中,输出的结果是整个图像的类标签。但是UNet是像素级分类,输出的则是每个像素点的类别,且不同类别的像素会显示不同颜色,UNet常常用在生物医学图像上,而该任务中图片数据往往较少…

条纹进度条

最开始学习qml的时候,想实现一个条纹进度条,当时还不熟悉动画,做不出来,只做了个静止的。qml学习和使用了快1年之际,把这个遗憾弥补下。 先上效果图,颜色取自Bootflat。 以下是源码,先上Stripe…

数据批量插入与逐条插入分析

简述 今天抽空做了一下使用Jdbc对数据操作的实际性能。在平时开发过程中我们经常会使用Hibernate来操作数据库,所以我们很少会去使用批量插入数据。一般都是通过hibernate的insert、addSave等方法来一条条地插入数据。所以很少去考虑这个问题。下面是针对Jdbc进行的…