论文解析:一文弄懂U-Net(图像分割)!
目录
一、相关资源
二、Motivation
三、技术细节
1.数据增强
2.下采样、上采样操作
(1)下采样
(2)上采样
3.重合拼接策略(Overlap-tile策略)
(1)图像预处理
(2)裁剪与拼接
4.训练策略
四、网络结构及参数选择
1.收缩路径(Contracting Path)
2.扩展路径(Expansive Path)
3.最终层
4.改进网络结构
五、创新点
1.网络结构
2.跳跃连接
3.高效的数据利用
4.模块化设计,易于改进优化
六、比较对象
七、启发/Idea
1.编码器-解码器架构
2.跳跃连接
3.数据增强
4.无缝分割
5.改进网络结构
一、相关资源
论文题目:U-Net: Convolutional Networks for Biomedical Image Segmentation
链接:https://arxiv.org/pdf/1505.04597
参考代码:Pytorch-UNet/unet at master · milesial/Pytorch-UNet · GitHub
二、Motivation
在医学图像分割中,往往需要精确定位到细胞或组织的边界,这对网络的分割精度(像素级别)提出了很高的要求。
医学影像的数据量相对较少,获取难度大,数据量可能只有几百甚至不到100。这样的数据集规模对于大型网络模型(如DeepLabv3+等)来说,很容易导致过拟合问题。由于数据量有限,需要通过网络结构和训练策略来增强模型的泛化能力,以应对医学图像中的多样性和复杂性。
在“FCN全连接网络”(处理全局信息和局部细节方面存在不足)基础上建立新的卷积网络。使其在使用很少的训练图像的情况下,仍能较快地产生更精确的分割结果。
三、技术细节
1.数据增强
论文中主要使用弹性形变的增强方式
原理:弹性形变是一种模拟生物组织在成像过程中可能发生的非刚性变形的技术。通过对原始图像进行弹性变换,可以生成具有不同形变模式的图像,从而增加训练数据的多样性。
应用:在医学图像分割中,由于生物组织的复杂性和多样性,弹性形变技术尤为有效。它可以帮助模型学习到对形变的鲁棒性,提高在真实应用场景中的分割精度。
2.下采样、上采样操作
(1)下采样【重要】
通过下采样(收缩路径)过程可以通过减少特征图的尺寸,使网络能够捕捉到更广泛的上下文信息。这有助于网络在分割过程中更好地理解图像的整体结构和内容,实现特征融合的效果,这些特征表示在后续的解码过程中将被用来重建图像并实现分割。
(2)上采样【重要】
如右图通过增加特征图的尺寸,使网络能够逐步恢复到原始图像的分辨率。这是实现图像分割的关键步骤之一。
上采样操作主要在解码器部分进行,通过转置卷积(也称为反卷积)或上采样层(如双线性插值、最近邻插值等)逐步增加特征图的尺寸,同时提取出边界信息。然后U-Net通过跳跃连接(Skip-Connection)将编码器中的特征图与解码器中的特征图进行融合,以保留更多的细节信息并提高分割精度。这种融合方式使得解码器在重建图像时能够充分利用编码器中提取的多尺度特征表示。
3.重合拼接策略(Overlap-tile策略)
Overlap-tile策略主要在扩展过程(即解码器或上采样过程)中使用,但这一策略的实施实际上也涉及到了输入图像的处理,以确保整个网络在处理图像时能够保持有效的上下文信息。
(1)图像预处理
在将图像输入到U-net之前,会对图像进行水平翻转将像素镜像填充(mirror padding),填充后,图像的边缘部分会被其镜像内容所包围,这样在进行卷积操作时,边缘像素也能够获得与图像内部像素相似的上下文信息。
然后将大图像划分为多个小图块,并在图块之间创建重叠区域。例如,假设要预测黄色区域的分割结果,需要蓝色区域内的图像数据作为输入。
(2)裁剪与拼接
在U-net的扩展路径(即上采样过程)中,每次上采样后的特征图尺寸会增大,但由于使用的是不带padding的卷积(valid convolution),特征图的尺寸并不能完全恢复到与下采样前相同。此时,会通过Overlap-tile策略,将下采样过程中对应层的特征图裁剪后,与上采样后的特征图进行拼接(concatenation)。
这种拼接方式使得上采样过程能够获取到更多的高分辨率信息,上采样后的特征图就融合了来自下采样过程的高分辨率信息,从而更完善地恢复原始图像中的细节信息,提高分割精度。
这种重叠平铺策略可以对任意大的图像进行无缝分割,避免了边界效应,确保分割结果的连续性和一致性。这种平铺策略对处理大图像很重要,否则分辨率会受到GPU内存的限制。
4.训练策略
使用随机梯度下降策略
四、网络结构及参数选择
1.收缩路径(Contracting Path)
卷积层:每个步骤包括两个3x3的卷积操作(不填充),每个卷积操作后跟一个ReLU激活函数。
池化层:接着是一个2x2的最大池化操作,步幅为2,用于下采样。
特征通道:每次下采样时,特征通道的数量会加倍。
2.扩展路径(Expansive Path)
上采样:每个步骤包括对特征图进行上采样,接着是一个2x2的卷积操作(“上卷积”),将特征通道数量减半。
裁剪:由于卷积操作会导致边界像素的丢失,因此需要对收缩路径中的特征图进行裁剪,使其与上采样后的特征图尺寸匹配,参看图中的虚线框出部分(裁剪到与上采样后的特征图相同的尺寸)。
拼接:然后将上采样、裁剪后的特征图与收缩路径中对应裁剪的特征图进行拼接。
卷积层:再进行两个3x3的卷积操作,每个卷积操作后跟一个ReLU激活函数。
3.最终层
在最终层使用1x1的卷积操作,将每个64维的特征向量映射到所需的类别数量。
4.改进网络结构
在卷积操作前先加上padding操作,让每次卷积不改变当层的特征图尺寸,这样可以直接将同一层的收缩路径和扩展路径的特征图拼接,而不用执行裁剪操作,最终得到的输出尺寸和输入是一样的。
在卷积操作后和ReLU中间加上一个BN层,进行归一化处理。
5.伪代码实现
U-Net 的核心思想是通过跳跃连接将编码器的低级空间特征与解码器的高级语义特征相结合,从而实现精确的分割结果。
下面这段伪代码实现了标准的 U-Net 网络结构,主要包括以下部分:
(1)卷积块:由两个连续的卷积层和 ReLU 激活函数组成
(2)编码器路径:通过多次下采样逐渐减少空间维度,增加通道数
(3)瓶颈部分:网络的最深处,进行特征提取
(4)解码器路径:通过多次上采样逐渐恢复空间维度,减少通道数,同时使用跳跃连接融合编码器特征
(5)输出层:使用 1x1 卷积和适当的激活函数生成最终分割结果
# Unet网络结构伪代码
# Unet是一种用于图像分割的卷积神经网络,由编码器(收缩路径)和解码器(扩展路径)组成# 定义卷积块 - 由两个连续的卷积层和ReLU激活函数组成
def double_conv(input_tensor, num_filters):# 第一个卷积层:3x3卷积核,不填充,保持通道数x = Conv2D(num_filters, kernel_size=3, padding='same')(input_tensor)x = BatchNormalization()(x) # 批量归一化x = ReLU()(x) # ReLU激活# 第二个卷积层:3x3卷积核,不填充,保持通道数x = Conv2D(num_filters, kernel_size=3, padding='same')(x)x = BatchNormalization()(x) # 批量归一化x = ReLU()(x) # ReLU激活return x# 定义编码器部分的下采样模块
def encoder_block(input_tensor, num_filters):x = double_conv(input_tensor, num_filters)p = MaxPooling2D(pool_size=2)(x) # 2x2最大池化进行下采样return x, p # 返回特征图和下采样后的结果# 定义解码器部分的上采样模块
def decoder_block(input_tensor, skip_features, num_filters):# 上采样操作,将特征图尺寸扩大2倍x = ConvTranspose2D(num_filters, kernel_size=2, strides=2, padding='same')(input_tensor)# 将上采样结果与编码器部分的对应特征图进行拼接(跳跃连接)x = Concatenate()([x, skip_features])x = double_conv(x, num_filters) # 应用两次卷积return x# 构建完整的Unet网络
def build_unet(input_shape, num_classes=1):# 输入层inputs = Input(shape=input_shape)# 编码器路径(下采样)# 每次下采样,特征图通道数翻倍,尺寸减半s1, p1 = encoder_block(inputs, 64) # s1: 保留用于跳跃连接s2, p2 = encoder_block(p1, 128) # s2: 保留用于跳跃连接s3, p3 = encoder_block(p2, 256) # s3: 保留用于跳跃连接s4, p4 = encoder_block(p3, 512) # s4: 保留用于跳跃连接# 瓶颈部分(网络最深处)# 不进行下采样,只进行两次卷积b1 = double_conv(p4, 1024)# 解码器路径(上采样)# 每次上采样,特征图通道数减半,尺寸翻倍# 同时将编码器部分的对应特征图通过跳跃连接与当前特征图拼接d1 = decoder_block(b1, s4, 512)d2 = decoder_block(d1, s3, 256)d3 = decoder_block(d2, s2, 128)d4 = decoder_block(d3, s1, 64)# 输出层# 使用1x1卷积将特征图通道数转换为类别数# 对于二分类或单通道分割,使用sigmoid激活函数# 对于多分类,使用softmax激活函数outputs = Conv2D(num_classes, kernel_size=1, activation='sigmoid')(d4)# 创建模型model = Model(inputs=inputs, outputs=outputs)return model# 创建Unet模型实例
# 输入形状为(256, 256, 3)表示256x256的RGB图像
# 输出类别数为1表示二分类分割任务
model = build_unet(input_shape=(256, 256, 3), num_classes=1)# 打印模型摘要
model.summary()
五、创新点
1.网络结构
U-Net网络的整体结构类似于大写的英文字母“U”,由收缩路径(contracting path)和扩张路径(expanding path)组成,这种结构使得网络能够同时捕获图像的上下文信息和细节信息。
2.跳跃连接
U-Net创新性地引入了跳跃连接,将编码器中的特征图与解码器中的特征图进行拼接(Concat),以实现特征的融合。这种融合方式不仅保留了更多的细节信息,还有助于提高分割的精度。
3.高效的数据利用
U-Net能够从极少的训练图像中,依靠数据增强技术将有效的标注数据更为有效地使用,这对于处理生物医学图像等标注数据稀缺的领域尤为重要。U-Net没有全连接层,且仅使用每个卷积的有效部分,这使得网络可以通过重叠拼接(overlap-tile)策略对任意大的图像进行无缝分割,提高了分割的灵活性和效率。
4.模块化设计,易于改进优化
U-Net的编码器、解码器和跳跃连接等部分都采用了模块化的设计,这使得网络易于进行改进和优化,以适应不同的分割任务和数据集。
六、比较对象
滑动窗口卷积网络方法(存在的问题:非常低效,在重叠的补丁之间不重用共享的特性。)
结论:U-net网络优于传统方法
七、启发/Idea
1.编码器-解码器架构
U-Net启发我们在设计图像分割网络时,可以优先考虑这种架构,以充分利用图像的多尺度信息。
2.跳跃连接
U-Net中的跳跃连接是另一个重要的创新点。通过将编码器中的特征图与解码器中的特征图进行拼接,跳跃连接实现了多尺度特征的融合,提高了分割的精度。这启发我们在设计网络时,可以引入类似的连接机制,以保留更多的细节信息并提升分割效果。
3.数据增强
在处理稀缺数据时,可以采用数据增强等策略来提高数据的利用率和模型的泛化能力。
4.无缝分割
通过重叠-切片策略对任意大的图像进行无缝分割。这启发我们在处理大尺度图像时,可以采用类似的策略来避免分割过程中的边界效应和信息丢失。
5.改进网络结构
(1) 在卷积操作前先加上padding操作,让每次卷积不改变当层的特征图尺寸,这样可以直接将同一层的收缩路径和扩展路径的特征图拼接,而不用执行裁剪操作,最终得到的输出尺寸和输入是一样的。
(2) 在卷积操作后和ReLU中间加上一个BN层,进行归一化处理。