论文题目:U-Net: Convolutional Networks for Biomedical
Image Segmentation
论文地址:https://arxiv.org/pdf/1505.04597
U-Net是一种广泛应用于图像分割任务的卷积神经网络架构,最初由Olaf Ronneberger等人在2015年提出。尽管它最初是为生物医学图像分割设计的,但由于其强大的特征提取和精细分割能力,U-Net已经被应用于各种其他领域。
什么是U-Net?
U-Net是一种基于全卷积网络(Fully Convolutional Network, FCN)的图像分割架构。它的独特之处在于其“U”形结构,由对称的编码器(Encoder)和解码器(Decoder)组成。编码器负责从图像中提取多尺度特征,而解码器则将这些特征逐步恢复到原始分辨率,从而生成高精度的分割结果。
2. U-Net的网络架构
U-Net的架构由两个主要部分组成:收缩路径(encoder)和扩展路径(decoder)。
U-Net架构详细示例
1. 收缩路径(编码器)
收缩路径的作用是提取图像的多尺度特征,并逐步降低图像的分辨率。具体步骤如下:
-
步骤1:输入大小为 256 × 256 \textcolor{red}{256 \times 256} 256×256的图像,通过第一次卷积操作,使用 3 × 3 \textcolor{red}{3 \times 3} 3×3的卷积核,得到 256 × 256 × 64 \textcolor{red}{256 \times 256 \times 64} 256×256×64的特征图。
-
步骤2:再进行一次 3 × 3 \textcolor{red}{3 \times 3} 3×3卷积操作,保持特征图的大小不变,输出仍然是 256 × 256 × 64 \textcolor{red}{256 \times 256 \times 64} 256×256×64。
-
步骤3:通过 2 × 2 \textcolor{red}{2 \times 2} 2×2的最大池化操作(Max Pooling),将特征图的分辨率减半,输出为 128 × 128 × 128 \textcolor{red}{128 \times 128 \times 128} 128×128×128。
-
步骤4:重复上述卷积和池化操作,最终得到 16 × 16 × 512 \textcolor{red}{16 \times 16 \times 512} 16×16×512的特征图。
- Conv1: ( 128 × 128 × 128 ) → ( 128 × 128 × 128 ) \text{Conv1: } \left(\textcolor{red}{128 \times 128 \times 128}\right) \to \left(\textcolor{red}{128 \times 128 \times 128}\right) Conv1: (128×128×128)→(128×128×128)
- Conv2: ( 128 × 128 × 128 ) → ( 128 × 128 × 128 ) \text{Conv2: } \left(\textcolor{red}{128 \times 128 \times 128}\right) \to \left(\textcolor{red}{128 \times 128 \times 128}\right) Conv2: (128×128×128)→(128×128×128)
- Pooling: ( 128 × 128 × 128 ) → ( 64 × 64 × 256 ) \text{Pooling: } \left(\textcolor{red}{128 \times 128 \times 128}\right) \to \left(\textcolor{red}{64 \times 64 \times 256}\right) Pooling: (128×128×128)→(64×64×256)
- 最终输出为: ( 16 × 16 × 512 ) \left(\textcolor{red}{16 \times 16 \times 512}\right) (16×16×512)
2. 扩展路径(解码器)
扩展路径用于将编码器提取的特征恢复到原始分辨率,同时生成最终的分割图。具体步骤如下:
-
步骤1:将 16 × 16 × 512 \textcolor{red}{16 \times 16 \times 512} 16×16×512的特征图通过反卷积操作(也称为上采样)扩展为 32 × 32 × 256 \textcolor{red}{32 \times 32 \times 256} 32×32×256。
-
步骤2:将扩展后的特征图与编码器中对应层的 32 × 32 × 256 \textcolor{red}{32 \times 32 \times 256} 32×32×256特征图拼接(Concatenate),得到 32 × 32 × 512 \textcolor{red}{32 \times 32 \times 512} 32×32×512的特征图。
-
步骤3:再进行两次 3 × 3 \textcolor{red}{3 \times 3} 3×3卷积操作,将特征图精细化,输出为 32 × 32 × 256 \textcolor{red}{32 \times 32 \times 256} 32×32×256。
- Conv1: ( 32 × 32 × 512 ) → ( 32 × 32 × 256 ) \text{Conv1: } \left(\textcolor{red}{32 \times 32 \times 512}\right) \to \left(\textcolor{red}{32 \times 32 \times 256}\right) Conv1: (32×32×512)→(32×32×256)
- Conv2: ( 32 × 32 × 256 ) → ( 32 × 32 × 256 ) \text{Conv2: } \left(\textcolor{red}{32 \times 32 \times 256}\right) \to \left(\textcolor{red}{32 \times 32 \times 256}\right) Conv2: (32×32×256)→(32×32×256)
-
步骤4:重复上采样和拼接操作,逐步恢复图像的分辨率,最终将特征图恢复为 256 × 256 × 64 \textcolor{red}{256 \times 256 \times 64} 256×256×64。
- Upsampling: ( 32 × 32 × 256 ) → ( 64 × 64 × 128 ) \text{Upsampling: } \left(\textcolor{red}{32 \times 32 \times 256}\right) \to \left(\textcolor{red}{64 \times 64 \times 128}\right) Upsampling: (32×32×256)→(64×64×128)
- Concatenate: ( 64 × 64 × 128 ) + ( 64 × 64 × 128 ) → ( 64 × 64 × 256 ) \text{Concatenate: } \left(\textcolor{red}{64 \times 64 \times 128}\right) + \left(\textcolor{red}{64 \times 64 \times 128}\right) \to \left(\textcolor{red}{64 \times 64 \times 256}\right) Concatenate: (64×64×128)+(64×64×128)→(64×64×256)
- Final Output: ( 256 × 256 × 64 ) \text{Final Output: } \left(\textcolor{red}{256 \times 256 \times 64}\right) Final Output: (256×256×64)
-
最后一层:使用 1 × 1 1 \times 1 1×1卷积,将 256 × 256 × 64 \textcolor{red}{256 \times 256 \times 64} 256×256×64的特征图映射到最终的类别数(例如:分割3个类别,输出为 256 × 256 × 3 \textcolor{red}{256 \times 256 \times 3} 256×256×3)。
- 公式: Final Conv: ( 256 × 256 × 64 ) → ( 256 × 256 × 3 ) \text{Final Conv: } \left(\textcolor{red}{256 \times 256 \times 64}\right) \to \left(\textcolor{red}{256 \times 256 \times 3}\right) Final Conv: (256×256×64)→(256×256×3)
反卷积举例
假设我们有一个大小为 2 × 2 \textcolor{red}{2 \times 2} 2×2的输入特征图和一个 2 × 2 \textcolor{red}{2 \times 2} 2×2的卷积核,我们希望通过反卷积操作将其扩展为一个 4 × 4 \textcolor{red}{4 \times 4} 4×4的输出特征图。
1. 输入特征图和卷积核
- 输入特征图:
[ 1 2 3 4 ] \begin{bmatrix} 1 & 2 \\ 3 & 4 \end{bmatrix} [1324]- 卷积核(假设所有元素均为 1 1 1):
[ 1 1 1 1 ] \begin{bmatrix} 1 & 1 \\ 1 & 1 \end{bmatrix} [1111]2. 初始化输出特征图
我们初始化一个全零的 4 × 4 \textcolor{red}{4 \times 4} 4×4的输出特征图:
[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ] \begin{bmatrix} 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 \end{bmatrix} 0000000000000000
3. 逐步计算反卷积
步骤1:处理输入特征图的第一个元素 1 1 1
- 卷积核与第一个元素相乘:
[ 1 1 1 1 ] × 1 = [ 1 1 1 1 ] \begin{bmatrix} 1 & 1 \\ 1 & 1 \end{bmatrix} \times 1 = \begin{bmatrix} 1 & 1 \\ 1 & 1 \end{bmatrix} [1111]×1=[1111]- 将结果累加到输出特征图的左上角:
输出特征图 = [ 1 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 ] \text{输出特征图} = \begin{bmatrix} 1 & 1 & 0 & 0 \\ 1 & 1 & 0 & 0 \\ 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 \end{bmatrix} 输出特征图= 1100110000000000 步骤2:处理输入特征图的第二个元素 2 2 2
卷积核与第二个元素相乘:
[ 1 1 1 1 ] × 2 = [ 2 2 2 2 ] \begin{bmatrix} 1 & 1 \\ 1 & 1 \end{bmatrix} \times 2 = \begin{bmatrix} 2 & 2 \\ 2 & 2 \end{bmatrix} [1111]×2=[2222]将结果累加到输出特征图的右上角:
输出特征图 = [ 1 3 2 0 1 3 2 0 0 0 0 0 0 0 0 0 ] \text{输出特征图} = \begin{bmatrix} 1 & 3 & 2 & 0 \\ 1 & 3 & 2 & 0 \\ 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 \end{bmatrix} 输出特征图= 1100330022000000 步骤3:处理输入特征图的第三个元素 3 3 3
卷积核移动到下一行与第三个元素相乘:
[ 1 1 1 1 ] × 3 = [ 3 3 3 3 ] \begin{bmatrix} 1 & 1 \\ 1 & 1 \end{bmatrix} \times 3 = \begin{bmatrix} 3 & 3 \\ 3 & 3 \end{bmatrix} [1111]×3=[3333]将结果累加到输出特征图的左下角:
输出特征图 = [ 1 3 2 0 4 6 2 0 3 3 0 0 0 0 0 0 ] \text{输出特征图} = \begin{bmatrix} 1 & 3 & 2 & 0 \\ 4 & 6 & 2 & 0 \\ 3 & 3 & 0 & 0 \\ 0 & 0 & 0 & 0 \end{bmatrix} 输出特征图= 1430363022000000 步骤4:处理输入特征图的第四个元素 4 4 4
卷积核与第四个元素相乘:
[ 1 1 1 1 ] × 4 = [ 4 4 4 4 ] \begin{bmatrix} 1 & 1 \\ 1 & 1 \end{bmatrix} \times 4 = \begin{bmatrix} 4 & 4 \\ 4 & 4 \end{bmatrix} [1111]×4=[4444]将结果累加到输出特征图的右下角:
最终输出特征图 = [ 1 3 2 0 4 10 6 0 3 7 4 0 0 0 0 0 ] \text{最终输出特征图} = \begin{bmatrix} 1 & 3 & 2 & 0 \\ 4 & 10 & 6 & 0 \\ 3 & 7 & 4 & 0 \\ 0 & 0 & 0 & 0 \end{bmatrix} 最终输出特征图= 14303107026400000 通过以上步骤,我们将输入的 2 × 2 \textcolor{red}{2 \times 2} 2×2特征图通过反卷积操作扩展为 4 × 4 \textcolor{red}{4 \times 4} 4×4的输出特征图。在每一步中,输入特征图的元素与卷积核进行点积,并将结果累加到输出特征图的相应位置。反卷积的主要作用是“放大”特征图的空间维度,从而恢复图像的分辨率。
U-Net的训练方法
U-Net的训练依赖于大量的标注数据。首先,需要准备训练数据集,其中包括原始图像和对应的分割标签。为了提升模型的泛化能力和鲁棒性,通常会使用数据增强技术对训练数据进行扩充,包括旋转、缩放、平移、翻转和颜色调整等。
小批量训练
由于图像分割任务需要处理高分辨率图像,为了最大化GPU内存的利用率,通常会采用较小的批量大小(batch size),例如1到4。每次迭代通过一个小批量的图像计算梯度,并更新网络权重。
模型评估与保存
在训练过程中,模型会定期在验证集上进行评估。常见的评估指标包括交叉熵损失、Dice系数、IoU(Intersection over Union)等。为了避免过拟合,通常会应用早停策略,并保存验证集上表现最佳的模型。
损失函数选择
U-Net的损失函数选择直接影响训练的效果和分割结果的精度。以下是常用的损失函数:
交叉熵损失(Cross-Entropy Loss)
交叉熵损失是图像分割任务中最常用的损失函数之一。它通过计算预测概率与真实标签之间的差异来衡量模型的预测准确性。对于类别不平衡的场景,可以使用加权交叉熵,将更多的权重分配给较少出现的类别。
Dice损失(Dice Loss)
Dice损失通过直接优化分割结果的重叠度(即Dice系数)来提高小物体和边界区域的分割精度。它对于处理类别不平衡问题尤其有效,能够更好地保持细节。
联合损失
为了获得更好的分割效果,U-Net可以结合交叉熵损失和Dice损失进行训练。联合损失函数的形式为:
Loss
𝛼
×
Cross-Entropy Loss
+
𝛽
×
Dice Loss
Loss=α×Cross-Entropy Loss+β×Dice Loss
其中
α
\alpha
α和
β
\beta
β是可调参数,用于平衡两者的贡献。
实验结果
U-Net在各种图像分割任务中均表现优异,以下是一些典型的实验结果:
医学图像分割:U-Net在医学图像分割中表现尤为突出,尤其在肿瘤分割、器官分割任务中。实验结果显示,U-Net在ISBI挑战赛中取得了最佳的分割结果,Dice系数通常高达0.9以上。
总结
U-Net凭借其独特的架构设计和灵活的损失函数选择,在图像分割任务中取得了广泛的成功。通过合理的数据准备、优化器选择和损失函数调整,U-Net能够在多种分割任务中提供出色的结果。