原始U-Net模型代码

论文:1505.U-Net: Convolutional Networks for Biomedical Image Segmentation
代码: https://github.com/milesial/Pytorch-UNet/blob/master/unet/unet_model.py

一、原始u-net 架构结构 (输入572x572x1,5层,向下采样4次):

每个蓝色框对应一个多通道特征图。通道的数量在框的顶部表示。x-y 大小在框的左下角提供。白盒代表复制的特征图。箭头表示不同的操作

在这里插入图片描述

1.0 框架代码

import torch
import torch.nn as nn

class UNet(nn.Module):
    def __init__(self, n_channels, n_classes, bilinear=False):
        """
        初始化函数,定义UNet模型的结构。

        参数:
        n_channels -- 输入图像的通道数,例如RGB图像的通道数为3。
        n_classes -- 输出的类别数,即分割后的图像通道数。
        bilinear -- 是否使用双线性插值进行上采样。默认值为False。
        """
        super(UNet, self).__init__()
        self.n_channels = n_channels
        self.n_classes = n_classes
        self.bilinear = bilinear

        # 初始卷积层,输入通道数为n_channels,输出通道数为64
        self.inc = DoubleConv(n_channels, 64)
        # 第一个下采样层,输入通道数为64,输出通道数为128
        self.down1 = Down(64, 128)
        # 第二个下采样层,输入通道数为128,输出通道数为256
        self.down2 = Down(128, 256)
        # 第三个下采样层,输入通道数为256,输出通道数为512
        self.down3 = Down(256, 512)
        # 根据是否使用双线性插值设置下采样因子
        factor = 2 if bilinear else 1
        # 第四个下采样层,输入通道数为512,输出通道数为1024(如果使用双线性插值,则输出通道数减半)
        self.down4 = Down(512, 1024 // factor)
        # 第一个上采样层,输入通道数为1024(或512),输出通道数为512(或256)
        self.up1 = Up(1024, 512 // factor, bilinear)
        # 第二个上采样层,输入通道数为512(或256),输出通道数为256(或128)
        self.up2 = Up(512, 256 // factor, bilinear)
        # 第三个上采样层,输入通道数为256(或128),输出通道数为128(或64)
        self.up3 = Up(256, 128 // factor, bilinear)
        # 第四个上采样层,输入通道数为128,输出通道数为64
        self.up4 = Up(128, 64, bilinear)
        # 输出卷积层,输入通道数为64,输出通道数为n_classes
        self.outc = OutConv(64, n_classes)

    def forward(self, x):
        """
        前向传播函数,定义输入x如何通过各层传递并输出结果。

        参数:
        x -- 输入的图像张量

        返回:
        logits -- 输出的类别概率张量
        """
        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         # 返回最终的类别概率张量

1.1 DoubleConv:2个3x3卷积+relu层的实现

在这里插入图片描述

import torch
import torch.nn as nn
import torch.nn.functional as F

class DoubleConv(nn.Module):
    """(卷积 => [批归一化] => ReLU) * 2"""

    def __init__(self, in_channels, out_channels, mid_channels=None):
        """
        初始化函数,定义双卷积层结构

        参数:
        in_channels -- 输入通道数
        out_channels -- 输出通道数
        mid_channels -- 中间层通道数,如果未指定,则等于输出通道数
        """
        super().__init__()
        if not mid_channels:
            mid_channels = out_channels
        # 定义双卷积层,包含两次卷积,每次卷积后跟批归一化和ReLU激活函数
        self.double_conv = nn.Sequential(
            nn.Conv2d(in_channels, mid_channels, kernel_size=3, padding=1, bias=False),
            nn.BatchNorm2d(mid_channels),
            nn.ReLU(inplace=True),
            nn.Conv2d(mid_channels, out_channels, kernel_size=3, padding=1, bias=False),
            nn.BatchNorm2d(out_channels),
            nn.ReLU(inplace=True)
        )

    def forward(self, x):
        """
        前向传播函数,输入x,输出双卷积的结果
        """
        return self.double_conv(x)

1.2 Down:向下采样+同层2次卷积 (特征图维度变为原来的一半)

在这里插入图片描述
每次向下采样后,经过2次卷积层
在这里插入图片描述
对应在架构图为
在这里插入图片描述

class Down(nn.Module):
    """通过最大池化下采样,然后进行双卷积"""

    def __init__(self, in_channels, out_channels):
        """
        初始化函数,定义下采样结构

        参数:
        in_channels -- 输入通道数
        out_channels -- 输出通道数
        """
        super().__init__()
        # 定义下采样层,包含一个2x2最大池化层,然后是一个双卷积层
        self.maxpool_conv = nn.Sequential(
            nn.MaxPool2d(2),
            DoubleConv(in_channels, out_channels)
        )

    def forward(self, x):
        """
        前向传播函数,输入x,输出下采样的结果
        """
        return self.maxpool_conv(x)

1.3 Up: 向上采样+拼接(特征图维度加倍+拼接之前维度)

在这里插入图片描述
每次向上采样后,要接收对应向下采样结果的特征图拼接(padding和crop是类似的方法)
拼接过程中,对称层效果最好
在这里插入图片描述
拼接完成后,经过2次卷积处理)
在这里插入图片描述
代码中up操作
在这里插入图片描述

class Up(nn.Module):
    """通过上采样,然后进行双卷积"""

    def __init__(self, in_channels, out_channels, bilinear=True):
        """
        初始化函数,定义上采样结构

        参数:
        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
### U-Net 模型介绍 U-Net 是一种用于图像分割的深度学习模型,最初由 Ronneberger 等人在2015年提出[^3]。该模型特别适用于医学图像处理中的像素级分类任务,在需要高精度图像分割的应用场景中表现出色[^2]。 #### 基本架构 U-Net 的名称来源于其独特的网络结构形状类似于字母 “U”。此架构主要分为两部分: - **收缩路径(Encoder)**:负责捕捉输入图片的空间特征并逐步减少空间分辨率;通过一系列卷积层和池化操作实现。 - **扩展路径(Decoder)**:旨在恢复原始尺寸的同时保持细节信息;利用反卷积/转置卷积来增加维度,并与来自编码器相应层次的信息相融合。 这种设计使得 U-Net 能够有效地保留上下文信息,同时获取更精细的目标边界定位能力。 #### 关键组件和技术特点 - 卷积神经网络 (CNN): 作为构建基础,能够自动提取复杂模式下的视觉特性[^1]。 - Skip Connections: 连接编码阶段与解码阶段相同尺度处的数据流,有助于缓解梯度消失问题并且增强了位置敏感性的表达力。 - 数据增强策略: 对训练样本进行随机变换以扩充数据集规模,提高泛化性能。 ```python import torch.nn as nn class UNet(nn.Module): def __init__(self, n_channels, n_classes): super(UNet, self).__init__() # 定义具体的网络层... def forward(self, x): # 实现前向传播逻辑... pass ``` 上述代码片段展示了如何定义一个简单的 PyTorch 版本的 U-Net 类框架。实际应用时还需要填充详细的参数设置及内部模块配置等内容。 ### 应用案例 由于其出色的分割效果,U-Net 已经被广泛应用于多个领域,尤其是在生物医学成像方面取得了显著成就。例如细胞检测、肿瘤识别等任务都可以借助这一工具获得更加精准的结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

曾小蛙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值