unet模型及代码解析

什么是unet

一个U型网络结构,2015年在图像分割领域大放异彩,unet被大量应用在分割领域。它是在FCN的基础上构建,它的U型结构解决了FCN无法上下文的信息和位置信息的弊端

Unet网络结构

主干结构解析

左边为特征提取网络(编码器),右边为特征融合网络(解码器)

高分辨率—编码—低分辨率—解码—高分辨率

特征提取网络

高分辨率—编码—低分辨率

前半部分是编码, 它的作用是特征提取(获取局部特征,并做图片级分类),得到抽象语义特征

由两个3x3的卷积层(RELU)再加上一个2x2的maxpooling层组成一个下采样的模块,一共经过4次这样的操作

特征融合网络

低分辨率—解码—高分辨率

利用前面编码的抽象特征来恢复到原图尺寸的过程, 最终得到分割结果(掩码图片)

由一层反卷积+特征拼接concat+两个3x3的卷积层(ReLU)反复构成,一共经过4次这样的操作,与特征提取网络刚好相对应,最后接一层1*1卷积,降维处理,即将通道数降低至特定的数量,得到目标图,具体内容可以参考这篇文章 一文读懂卷积神经网络中的1x1卷积核

FCN与UNet特征融合操作对比解析

FCN是通过特征图对应像素值的相加来融合特征的

torch代码:

concat1 = out1+out2
# 其中out1与out2都是torch中的tensor格式

unet是通过同维度矩阵拼接来融合特征的

torch代码:

concat2 = torch.cat([convt1,conv4],dim=1)
# dim = 1 意味着在第1维度方向(第1维也就是列为4的方向)进行叠加
# 对于更高维的数据,也就是在dim = x 时,即x所对应维度方向进行叠加

UNet主要创新点

  • 采取将低级特征图与后面的高级特征图进行融合操作

  • 完全对称的U型结构使得前后特征融合更为彻底,使得高分辨率信息与低分辨率信息在目标图片中增加

  • 结合了下采样时的低分辨率信息(提供物体类别识别依据)和上采样时的高分辨率信息(提供精准分割定位依据),此外还通过融合操作(跳跃结构)填补底层信息以提高分割精度.(分辨率就是图片的尺寸)

对高层语义特征与底层空间信息的理解

越底层的特征蕴含的空间信息(分割定位特征)更多,语义特征(就是类别判断特征,像素点可以分到哪一个类别中去)更少,越高级的特征蕴含的空间信息更少,语义特征更多

  • 底层特征图片更偏向于组成图像的基本单元,如点,线,边缘轮廓

UNet与FCN的比较

1.编解码结构
  • 它们的结构都用了一个比较经典的思路,也就是编码和解码(encoder-decoder)结构,该结构早在2006年就被Hinton提出来发表在了nature上。当时这个encoder-decoder结构提出的主要作用并不是分割,而是压缩图像和去噪声。输入是一幅图,经过下采样的编码,得到一串比原先图像更小的特征,相当于压缩,然后再经过一个解码,理想状况就是能还原到原来的图像。这样的话我们存一幅图的时候就只需要存一个特征和一个解码器即可。同理,这个思路也可以用在原图像去噪,做法就是在训练的阶段在原图人为地加上噪声,然后放到这个编码解码器中,目标是可以还原得到原图。在UNet与FCN的目标任务中,是得到一张Mask掩码图,实现端到端(由图得到图),这与Hinton提出的编解码操作不谋而合。

  • 和FCN相比,U-Net的第一个特点是完全对称,也就是左边和右边是很类似的,而FCN的解码器部分相对简单,只用了一个反卷积的操作,之后并没有跟上卷积结构。

2.全卷积结构
  • UNet和FCN一样, 是全卷积形式, 没有全连接层(即没有固定图的尺寸)——全连接层输入是提前固定好的,所以容易适应很多输入尺寸大小
3.跳跃结构,即特征融合操作
  • UNet相比FCN,跳跃结构更多,更彻底,每一层下采样都与后面每一次上采样对应,一个经验的解释(大量实验)就是跳级连接能够保证特征更加精细
  • UNet是拼接操作,而FCN是加操作

模型torch代码解析

import torch.nn as nn
import torch.nn.functional as F
import torch.utils.data
import torch



"""
    构造下采样模块--右边特征融合基础模块    
"""


class conv_block(nn.Module):
    """
    Convolution Block
    """

    def __init__(self, in_ch, out_ch):
        super(conv_block, self).__init__()

        self.conv = nn.Sequential(
            nn.Conv
UNet模型是一种广泛应用于图像分割任务的深度学习架构,其核心结构包括编码器(下采样)和解码器(上采样),并且通过跳跃连接(skip connections)将低层特征与高层特征融合,从而提升分割精度。以下是一个基于PyTorch实现的UNet模型代码示例。 ### UNet模型结构定义 ```python import torch import torch.nn as nn import torch.nn.functional as F class UNet(nn.Module): def __init__(self, in_channels=3, out_channels=1): super(UNet, self).__init__() def CBR(in_channels, out_channels): return 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) ) self.down1 = CBR(in_channels, 64) self.down2 = CBR(64, 128) self.down3 = CBR(128, 256) self.down4 = CBR(256, 512) self.down5 = CBR(512, 1024) self.maxpool = nn.MaxPool2d(kernel_size=2, stride=2) self.up4 = nn.ConvTranspose2d(1024, 512, kernel_size=2, stride=2) self.up_conv4 = CBR(1024, 512) self.up3 = nn.ConvTranspose2d(512, 256, kernel_size=2, stride=2) self.up_conv3 = CBR(512, 256) self.up2 = nn.ConvTranspose2d(256, 128, kernel_size=2, stride=2) self.up_conv2 = CBR(256, 128) self.up1 = nn.ConvTranspose2d(128, 64, kernel_size=2, stride=2) self.up_conv1 = CBR(128, 64) self.final_conv = nn.Conv2d(64, out_channels, kernel_size=1) def forward(self, x): conv1 = self.down1(x) x = self.maxpool(conv1) conv2 = self.down2(x) x = self.maxpool(conv2) conv3 = self.down3(x) x = self.maxpool(conv3) conv4 = self.down4(x) x = self.maxpool(conv4) x = self.down5(x) x = self.up4(x) x = torch.cat([x, conv4], dim=1) x = self.up_conv4(x) x = self.up3(x) x = torch.cat([x, conv3], dim=1) x = self.up_conv3(x) x = self.up2(x) x = torch.cat([x, conv2], dim=1) x = self.up_conv2(x) x = self.up1(x) x = torch.cat([x, conv1], dim=1) x = self.up_conv1(x) return self.final_conv(x) ``` ### 模型训练流程简要说明 1. **数据加载**:使用`torchvision`或自定义`Dataset`类加载图像和对应的分割掩码。 2. **损失函数**:常用的损失函数包括`BCEWithLogitsLoss`(适用于二分类)、`CrossEntropyLoss`(多分类)或`DiceLoss`等。 3. **优化器**:通常使用`Adam`或`SGD`优化器。 4. **训练循环**:包括前向传播、损失计算、反向传播和参数更新。 ### 示例训练代码 ```python import torch.optim as optim # 初始化模型、损失函数和优化器 model = UNet(in_channels=3, out_channels=1) device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') model.to(device) criterion = nn.BCEWithLogitsLoss() optimizer = optim.Adam(model.parameters(), lr=1e-4) # 假设dataloader已经定义好 for epoch in range(10): # 训练10个epoch for images, masks in dataloader: images = images.to(device) masks = masks.to(device) outputs = model(images) loss = criterion(outputs, masks) optimizer.zero_grad() loss.backward() optimizer.step() print(f'Epoch [{epoch+1}/10], Loss: {loss.item():.4f}') ``` 上述代码展示了UNet模型的基本结构及其训练流程。在实际应用中,可以根据具体任务需求对模型结构、损失函数及训练策略进行调整。例如,引入注意力机制、使用不同的编码器(如ResNet)作为特征提取器等。 [^1]: [UNet网络对图像的分割](https://github.com/xxx/unet-segmentation) [^2]: [小白】基于Resnet+Unet的图像分割模型(by Pytorch)](https://example.com/resnet-unet) [^3]: [深度学习图像分割之UNET](https://example.com/unet-seg) [^4]: [图像分割之Unet解析及实现代码](https://github.com/FENGShuanglang/unet)
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值