UNet 简介
UNet 论文:Convolutional Networks for Biomedical Image Segmentation
这篇论文主要是针对生物医学影像这个领域提出的,所以一提到UNet一般都会联想到医学影像。
UNet 网络结构
UNet它是一个encoder - decoder的结构,那么encoder对应就是这个u型网络左边这半部分,也就是我们特征提取及下采样这部分。decoder解码就是右边部分通过一系列上采样,我们得到最终的一个分割图。 对于网络结构左边这一侧,作者叫做contracting path ,对于右边这一侧作者称为expansive path 。
在上图的网络结构中,每一个长条的矩形对应的都是一个特征层,其中箭头表示是一种操作。图中右下角列出了每一种箭头它所对应的操作类型。下面详细的介绍网络的搭建过程:
U型网络的左半部分
- 这里输入是以
572x572 的单通道的图像为例的,首先通过一个卷积层,它的卷积核大小为3x3 的,并且后面跟一个Relu 激活函数。注意对于这个卷积层它的步距是等于1的,其次是没有padding 操作的,所以你会发现通过这个卷积层,它的高和宽都会减少。比如这里通过第一个3x3 的卷积,它的高和宽从572 变为570 ,再通过一个3x3 卷积层又变为568.由于这篇论文是2015 年发表的,当时BN(batch normalization) 还没火起来,所以按时还没有使用BN这个模块。 - 接下来,通过一个
max pooling 下采样,池化核大小为2x2 ,步距为2 ,那么经过下采样特征层的高和宽就会减半。由568 变成这里的284,channel是没有发生变化的还是64.再通过两个3x3的卷积核,这里注意每个下采样后,通过卷积层都会对channel进行翻倍。比如这里下采样后的channel为64,通过3x3卷积后channel变为128 - 接下来,通过下采样max-pooling,将特征层的高和宽由280变为140,然后再通过两个3x3的卷积层,将通道由128调整为256.
- 接下来,再通过下采样max-pooling,将特征层的高和宽由136变为68,然后再通过两个3x3的卷积层,将channel由256调整为512.
- 然后,再通过下采样max-pooling,将特征层的高和宽由64变为32,然后再通过两个3x3的卷积层,将channel由512调整为1024.
U型网络的右半部分
- 接下来这一部分需要注意了,首先对于绿色箭头部分,这里有写是一个上采样(
up conv ),这里上采样采用的是转置卷积,通过转置卷积后它将特征层的宽和高变为原来的两倍,比如这里由28变成56,然后channel会减半,由这里的1024变为512.对应图中的蓝色部分。 注意这里旁边有个灰色的箭头(copy and crop ),比如灰色箭头左侧对应64x64大小的特征层,但箭头右侧蓝色部分的特征图为56x56,没法直接将他们进行拼接。那么就需要对左侧64x64大小的特征层进行一个中心裁剪,就是将中间56x56部分裁剪过来和右侧蓝色部分进行channel 方向的concat拼接,拼接后channel就变为1024了。然后再通过2个3x3的卷积核将channel调整成512 - 然后再通过上采样将特征图的高和宽由52调整到这里的104,然后channel减半为256.然后将灰色箭头右侧的特征层通过中心裁剪的方式,将中间104x104的区域裁剪过来与箭头右侧蓝色部分进行concat拼接,通道由256变为512。然后再通过两个3x3的卷积进一步融合,并且通道由512变为256
- 然后再通过上采样将特征图的高和宽由100调整到这里的200,然后channel减半为128.然后将灰色箭头右侧的特征层通过中心裁剪的方式,将中间200x200的区域裁剪过来与箭头右侧蓝色部分进行concat拼接,通道由128变为256。然后再通过两个3x3的卷积进一步融合,并且通道由256变为128
- 然后再通过上采样将特征图的高和宽由196调整到这里的392,然后channel减半为64.然后将灰色箭头右侧的特征层通过中心裁剪的方式,将中间392x392的区域裁剪过来与箭头右侧蓝色部分进行concat拼接,通道由64变为128。然后再通过两个3x3的卷积进一步融合,得到388x388,通道为64的特征层。
- 再通过一个1x1的卷积核,将channel调整为我们的分类个数。论文中是为2表示只有两个类别,前景和背景。最终输出的特征图大小为388x388x2,注意最后一个1x1卷积是没有relu激活函数的。
注意我们输入的图片大小为572x572,但是我们得到的分割图是388x388的,所以我们这里得到分割图并不是针对我们原图的一个分割图,而是只有中间388x388那个区域的分割图。
但是现在比较主流的实验方式 ,github 所实现的一系列源码当中,大家并不是严格按照原论文给的方式去实现的,现在主流的实现方式是将3x3 的卷积加上一个padding ,就是说我们每次通过3x3 的卷积层不会改变特征层的高和宽。并且我们在卷积核Relu 之间会加上一个Bn 层。这样做会给我们带来一个怎样的变化呢,由于卷积后不改变特征层大小,两个特征图可以直接拼接,就不需要中心裁剪了,并且最终得到的卷积层高和宽与输入的卷积层高和宽是保持一致的。所以后面要实现可以按照当前主流的方式。
假设我们要用原论文提出的UNet的话,其实是有一定的问题的,比如我们要得到上图中黄色区域的分割图片,其实我们需要更大的输入图片如蓝色部分才可以得到中间黄色区域的分割图片。
但对于边缘区域,边缘之外的像素我们是没有的,为了应对这个问题作者说对于那些缺失的数据,它就直接采用镜像的策略,通过沿边框进行镜像得到。但如果按照目前主流的实现方式,输出的分割图与原图保持一致的话,其实我们根本不用考虑边缘缺失数据这个情况。
|