Unet详解

1️⃣ Unet介绍

  语义分割的目的是判断每个像素点的类别,进行精确的分割,在自动驾驶,医疗影像等领域具有广泛应用。
在这里插入图片描述
  上图为自动驾驶中的分割任务的分割结果,可以从一张图片中有效的识别出汽车(深蓝色),行人(红色),红绿灯(黄色),道路(浅紫色)等
  Unet是最常用、最简单的一种分割模型,在2015年被提出。


2️⃣ 原理分析

Unet之所以叫Unet是因为其网络结构类似一个U的形状,该结构由编码器和解码器两部分组成。

  • 编码器中的卷积逐步提取特征(深度增加),maxpool降低空间分辨率(高宽减少)
  • 解码器通过上采样(反卷积)高宽加倍,深度减半;通过卷积降低拼接特征的深度
    在这里插入图片描述

UNet的关键创新是在解码器中引入了跳跃连接(Skip Connection),即将编码器中的特征图与解码器中对应的特征图进行连接。这种跳跃连接可以帮助解码器更好地利用不同层次的特征信息,从而提高图像分割的准确性和细节保留能力


3️⃣网络结构

在这里插入图片描述

首先介绍一下图片中的几个箭头:

  • conv3×3,ReLU:图片中所有的操作都是,3×3卷积,stride=1,padding=0,但卷积核个数动态变化

  • copy and crop:对编码器的特征进行裁剪,方便和解码器中上采样后的特征进行拼接

  • max pool 2×2:下采样,2×2,stride=2,padding=0。通道数不变,高宽减半

  • up-conv 2×2:上采样,即反卷积,2×2反卷积,stride=2,padding=0。通道数减半,高宽加倍

    反卷积公式: 反卷积后的尺寸 = ( 输入图像尺寸 − 1 ) × 步长 + 反卷积核大小 − 2 × P a d d i n g 反卷积后的尺寸=(输入图像尺寸-1)×步长+反卷积核大小-2×Padding 反卷积后的尺寸=(输入图像尺寸1)×步长+反卷积核大小2×Padding 反卷积后的通道数 = 反卷积核数量 反卷积后的通道数=反卷积核数量 反卷积后的通道数=反卷积核数量代码:nn.ConvTranspose2d(in_channels=xx, out_channels=xx, kernel_size=2, stride=2, padding=0)

  • conv1×1:最终输出的时候采用1×1的卷积,stride=1,padding=0,用于改变通道数

接下来详细介绍网络的结构:编码器由图中红色的1→5组成,解码器由图中绿色的1→4组成

  • 编码器1:
    # 输入572×572×1
    # 经过conv1_1,由572×572×1变成了570×570×64
    self.conv1_1=nn.Conv2d(in_channels=1, out_channels=64, kernel_size=3, stride=1, padding=0)
    self.relu1_1 = nn.ReLU()
    # 经过conv1_2,由570×570×64变成568×568×64
    self.conv1_2 = nn.Conv2d(64, 64, kernel_size=3, stride=1, padding=0)  
    self.relu1_2 = nn.ReLU()
    # 维度变化:572×572×1→570×570×64→568×568×64
    
  • 最大池化层1:
    # 经过 maxpool_1,由568×568×64变成284×284×64
    self.maxpool_1 = nn.MaxPool2d(kernel_size=2, stride=2,padding=0)  
    # 维度变化:568×568×64→284×284×64
    
  • 编码器2:
    # 经过conv2_1,由284×284×64变成282×282×128
    self.conv2_1 = nn.Conv2d(in_channels=64, out_channels=128, kernel_size=3, stride=1, padding=0)  
    self.relu2_1 = nn.ReLU()
    # 经过conv2_2,由282×282×128变成280×280×128
    self.conv2_2 = nn.Conv2d(128, 128, kernel_size=3, stride=1
UNet是一种经典的深度学习架构,主要用于图像分割任务,比如医学影像分析、遥感图像解析等。它是由克里斯托弗·拉比等人于2015年提出的一种卷积神经网络结构,设计初衷是为了解决像素级别的标注问题。 基本原理上,UNet结合了编码器(下采样)和解码器(上采样)的概念,形成U型结构。编码器部分逐渐减小空间分辨率并增加特征信息的复杂度,而解码器则相反,逐步恢复原始尺寸的同时将低层特征与高层特征融合,生成详细的预测结果。 以下是简要的UNet结构概述: 1. **输入**:接受一张图像作为输入。 2. **编码器**:通过一系列的卷积层(含池化层),如3x3卷积、ReLU激活函数和最大池化,减少图像大小,提取高层次的特征。 3. **瓶颈层**:通常在编码器的最低层,包含一个大的卷积层,用于压缩特征维度。 4. **解码器**:从瓶颈开始,通过反卷积(上采样)操作逐渐恢复原尺寸,并使用跳跃连接(skip connection)合并来自编码器对应层的特征图,保留细节信息。 5. **输出**:最后是一个1x1卷积层,生成与输入相同大小的预测图,每个像素都有相应的类别概率。 下面是一些关键的代码实现要点(以Keras为例): ```python from keras.models import Model from keras.layers import Input, Conv2D, MaxPooling2D, UpSampling2D, concatenate def build_unet(input_shape, n_classes): inputs = Input(shape=input_shape) # 编码部分 conv1 = Conv2D(64, (3, 3), activation='relu', padding='same')(inputs) pool1 = MaxPooling2D(pool_size=(2, 2))(conv1) # 继续堆叠更多的卷积层... #... # 瓶颈层 bottle_neck = Conv2D(256, (3, 3), activation='relu', padding='same')(pool1) # 解码部分 up1 = UpSampling2D(size=(2, 2))(bottle_neck) merge1 = concatenate([up1, conv1]) conv2 = Conv2D(64, (3, 3), activation='relu', padding='same')(merge1) conv2 = Conv2D(n_classes, (1, 1), activation='sigmoid')(conv2) model = Model(inputs=inputs, outputs=conv2) return model # 创建并编译模型 unet_model = build_unet(input_shape=(height, width, channels), n_classes=n_classes) unet_model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy']) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值