【语义分割专题】语义分割相关工作--UNet网络介绍

本文深入解析U-Net网络架构,该架构在生物医学图像分割中表现出色。U-Net结合了收缩路径和扩展路径,确保了对上下文信息的捕捉和精确的局部定位。收缩路径由卷积和池化构成,而扩张路径则使用转置卷积进行上采样。此外,网络使用跳跃连接保持高分辨率特征,并通过加权损失处理相邻细胞的分割。代码示例展示了如何构建一个基于VGG的U-Net模型。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

U-Net: Convolutional Networks for Biomedical Image Segmentation

U-Net架构包括一个捕获上下文信息的收缩路径和一个支持精确本地化的对称扩展路径。U-Net证明了这样一个网络使用非常小的图像可以进行端到端的训练,并在生物分割挑战赛中取得了比以前最好的方法。

在这里插入图片描述

收缩路径由2个3 * 3的卷积组成,每个卷积后面跟的是RELU激活函数和一个进行下采样的2 * 2较大池化运算。

扩张阶段包括一个特征通道的上采样。后面跟得上是2 * 2的转置卷积,它能够将特征通道数目减半,同时加大特征图。

最后一层是1 * 1卷积,用这种卷积来组成的特征向量映射到需要的类别数量上。

  • a.U-Net建立在FCN的网络架构上,作者修改并扩大了这个网络框架,使其能够使用很少的训练图像就能得到很精确的分割结果。
  • b.添加上采样阶段,并且添加了很多的特征通道,允许更多的原图像纹理的信息在高分辨率的layers中进行传播
  • c.U-Net没有FC层,且全程使用valid来进行卷积,这样的话可以保证分割的结果都是基于没有缺失的上下文特征得到的,因此输入输出的图像尺寸不太一样(但在keras上代码做的都是same convolution),对于图像很大的输入,可以使用overlap-strategy来进行无缝的图像输出.
  • d.为了预测输入图像的边缘部分,通过镜像输入图像来外推丢失的上下文,实则输入大图像也是可以的,但是这个侧率基于GPU内存不够的情况下所提出的。
  • e.细胞分割的另外一个难点在于将相同类别且互相接触的细胞分开,因此提出weighted loss,也就是赋予相互接触的两个细胞之间的background标签更高的权重。

创新点关键点

  • 1.U-Net简单地将编码器的特征图拼接至每个阶段解码器对的上采样特征图,从而形成一个梯形结构。
  • 2.通过跳跃拼接连接的架构,在每个阶段都允许解码器学习在编码器中丢失的相关特征。
  • 3.上采样采用转置卷积

论文架构

  • Introduction
  • Network Architecture
  • Training
    • 预先计算权重图来获得每一个像素在损失函数中的权值,补充了训练数据每类像素的不同频率。
    • 可借鉴这里的softmax公式以及交叉熵公式
    • Data Augmentation 数据增强操作 Dropout层,隐氏加强了数据增强
    • 改进loss 提出一种带权重的损失
  • Experiments
  • Conclusion

公式部分

在这里插入图片描述

代码架构

encoder部分:

def vgg_encoder(n_classes,input_height,input_width):

    assert  input_height % 32 == 0
    assert  input_width % 32 == 0

    img_input = Input(shape=(input_height, input_width, 3))

    # Block1
    x = Conv2D(64,(3,3),activation="relu",padding="same",name="block1_conv1")(img_input)
    x = Conv2D(64,(3,3),activation="relu",padding="same",name="block1_conv2")(x)
    x = MaxPooling2D((2,2),strides=(2,2),name="block1_pool")(x)
    f1 = x

    # Block2
    x = Conv2D(128,(3,3),activation="relu",padding="same",name="block2_conv1")(x)
    x = Conv2D(128,(3,3),activation="relu",padding="same",name="block2_conv2")(x)
    x = MaxPooling2D((2,2),strides=(2,2),name="block2_pool")(x)
    f2 = x

    # Block3
    x = Conv2D(256,(3,3),activation="relu",padding="same",name="block3_conv1")(x)
    x = Conv2D(256,(3,3),activation="relu",padding="same",name="block3_conv2")(x)
    x = Conv2D(256,(3,3),activation="relu",padding="same",name="block3_conv3")(x)
    x = MaxPooling2D((2, 2), strides=(2, 2), name="block13_pool")(x)
    f3 = x

    # Block4
    x = Conv2D(512,(3,3),activation="relu",padding="same",name="block4_conv1")(x)
    x = Conv2D(512,(3,3),activation="relu",padding="same",name="block4_conv2")(x)
    x = Conv2D(512,(3,3),activation="relu",padding="same",name="block4_conv3")(x)
    x = MaxPooling2D((2,2),strides=(2,2),name="block4_pool")(x)
    f4 = x

    # Block5
    x = Conv2D(512,(3,3),activation="relu",padding="same",name="block5_conv1")(x)
    x = Conv2D(512,(3,3),activation="relu",padding="same",name="block5_conv2")(x)
    x = Conv2D(512,(3,3),activation="relu",padding="same",name="block5_conv3")(x)
    x = MaxPooling2D((2,2),strides=(2,2),name="block5_pool")(x)
    f5 = x

    return img_input, [f1, f2, f3, f4, f5]



decoder部分

def UNet_decoder(n_classes,levels):

    [f1, f2, f3, f4, f5] = levels

    # 解码层1
    y = UpSampling2D((2,2))(f5)
    y = concatenate([f4,y],axis=-1)
    y = Conv2D(512,(3,3),padding="same")(y)
    y = BatchNormalization()(y)

    # 解码层2
    y = UpSampling2D((2,2))(y)
    y = concatenate([f3,y],axis=-1)
    y = Conv2D(256,(3,3),padding="same")(y)
    y = BatchNormalization()(y)

    # 解码层3
    y = UpSampling2D((2,2))(y)
    y = concatenate([f2,y],axis=-1)
    y = Conv2D(128,(3,3),padding="same")(y)
    y = BatchNormalization()(y)

    # 解码层4
    y = UpSampling2D((2,2))(y)
    y = concatenate([f1,y],axis=-1)
    y = Conv2D(64,(3,3),padding="same")(y)
    y = BatchNormalization()(y)

    # 解码层5
    y = UpSampling2D((2,2))(y)
    y = Conv2D(64,(3,3),padding="same")(y)
    y = BatchNormalization()(y)

    # 最后的softmax层
    y = Conv2D(n_classes,(1,1),padding="same")(y)
    y = BatchNormalization()(y)
    y = Activation("relu")(y)

    y = Reshape((-1,n_classes))(y)
    y = Activation("softmax")(y)

    return y

UNet部分

def UNet(n_classes,input_height,input_width):

    assert input_height % 32 == 0
    assert input_width % 32 == 0

    img_input,levels =vgg_encoder(n_classes,input_height,input_width)

    output = UNet_decoder(n_classes, levels)

    Vgg_UNet = Model(img_input, output)
    return Vgg_UNet

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

mind_programmonkey

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

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

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

打赏作者

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

抵扣说明:

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

余额充值