前言:语义分割的基本模型大都是在FCN的基础之上进行改进的,本文所要讨论的U-Net网络便是如此,U-net 是基于FCN的一个语义分割网络,适合与少量样本的图像分割,比如用来做医学图像的分割,能够取得非常好的成绩。
一、U-Net网络的结构
1.1 基本信息
1.2 U-Net的主要结构
1.3 网络的输出是什么?
1.4 U-Net的损失函数
二、U-Net的数据增强data augmentation
2.1 弹性变形
2.2 输入输出大小不一致怎么办
一、U-Net网络的结构
1.1 基本信息
论文题目:U-Net: Convolutional Networks for Biomedical Image Segmentation
论文地址:https://arxiv.org/pdf/1505.04597v1.pdf
U-Net诞生的一个主要前提是,很多时候深度学习的结构需要大量的sample和计算资源,但是U-Net基于FCN(Fully Convultional Neural Network:全卷积神经网络)进行改进,并且利用数据增强(data augmentation)可以对一些比较少样本的数据进行训练,特别是医学方面相关的数据(医学数据比一般我们所看到的图片及其他文本数据的获取成本更大,不论是时间还是资源的消耗),所以U-Net的出现对于深度学习用于较少样本的医学影像是很有帮助的。
本论文主要亮点:
(1)改进了FCN,把扩展路径完善了很多,多通道卷积与类似FPN(特征金字塔网络)的结构相结合。
(2)利用少量数据集进行训练测试,为医学图像分割做出很大贡献。
这篇论文的篇幅不长,如果熟悉前面FCN的小伙伴可以很快的看明白其中的原理以及实现思想。
1.2 U-Net的主要结构
为什么称之为U-Net呢?主要是因为在论文中作者将它的结构图绘制成了一个“U形”形状,由此得名,实际上它跟FCN网络基本上是一模一样的架构,U-Net的结构图如下:
上面的结构图不就是一个U形嘛,故而称之为U-Net。
收缩路径(contracting path)和扩展路径(expanding path),
注意:上图中右下角的颜色注释箭头很重要哦!
(1)收缩路径(contracting path)其实就是一个常规的卷积网络,它包含重复的2个3x3卷积,紧接着是一个RELU,一个max pooling(步长为2),用来降采样,每次降采样我们都将feature channel扩大一倍,从64、128、256、512、1024。两个3x3的卷积核之后跟一个2x2的最大化池化层,缩小图片的分辨率。(其实也可以将收缩路径看成是一个“编码器Ecoder”,只是作者不这么叫)
(2)扩展路径(expanding path)包含一个上采样(2x2上卷积),将图像大小扩大一倍,然后再使用普通的3x3卷积核,再将通道数feature channel缩小一倍,从1024、512、256、128、64(其实也可以将拓展路径看成是一个“解码器Decoder”,只是作者不这么叫)。
(3)裁剪crop并且跨层连接
上面的结构其实如果是水平方向展开,就是一个“编码-解码”的这样一个结构,但是有两个地方是需要注意的:
第一:编码解码的feature map大小是不对称的;
第二:我需要使用跨层连接来提高特征的利用率,在上采样的时候利用前面低层的特征信息;
鉴于这两个点,U-Net依然沿袭了FCN网络的处理方式——进行特征融合,但是与FCN不同的是,融合的方式有所差别,
第一:由于特征图feature map不对称,所以要能够融合需要将收缩路径中的feature map进行裁剪crop,大小一样了才能融合;
第二:特征融合方式是“拼接“”,U-net采用将特征在channel维度拼接在一起,形成更厚的channel。而FCN融合时使用的对应点相加,并不形成更厚的特征。一个是concat,一个是add。
1.3 网络的输出是什么?
从上面的结构图可以看出,在网络的最后,有一个1X1的卷积核,将channel从64一下子下降到了2,熟悉FCN的都知道,全卷积网络最终的channel的数量不就是类别的数量吗,怎么会只有2个channel呢?
事实上U-Net论文的诞生是针对医学影像的分割的,医学影像的这个分割只分为“前景”和“背景”,这不就是两个分类嘛。
针对最后得到的两张heat map(也就是feature map,换了个称呼而已),例如第一张feature map表示的是第一类的得分(即每个像素点对应第一类都有一个得分),第二张feature map表示的是第二类的得分(即每个像素点对应第二类也都有一个得分),然后作为softmax函数的输入,算出概率比较大的softmax类,选择它作为输入给交叉熵进行反向传播训练。
1.4 U-Net的损失函数
看了网上很多的博客文章,在损失函数这一块儿很多都是一样的说法,个人感觉说得不是特别清晰,所以在这里我会用自己的表达方式来说明,不对的地方还望有大佬指正。
(1)首先是交叉熵函数
这个其实跟普通的分类中的交叉熵函数是一样的,公式如下:
熟悉交叉熵的小伙伴看到这个公式有没有很熟悉,下面解释一下每一个字母的含义:
k表示的是类别数量,由于是采用全卷积方式,所以,k也就是最终输出的特征图数量(也就是通道数量channels)。x表示的是某一个像素,所以:
ak(x)表示的是在第k个channel上面的像素位置x的通过激活函数(activation)之后的函数输出值,相对应的
pk(x)表示的是在第k个channel上面的像素位置x的通过激活函数(activation)之后的函数输出值经过softmax交叉熵运算之后产生的概率值
总结:ak(x) 是输出值
pk(x) 是概率值
当某一个像素x在通道k上的值较大,即ak(x)较大,此时在运算得到的pk(x)是接近于1的,说明该像素x属于这个类别k,反之,当某一个像素x在通道k上的值较小,即ak(x)较小,此时在运算得到的pk(x)是接近于0的,说明该像素x不属于这个类别k。
(2)然后是损失函数
对于多分类的交叉熵损失函数,形式如下:
其实U-Net中的损失函数和这个也是非常接近的,但是有一点稍微的区别,公式如下:
这是原论文中的公式截图,那每一个代表什么意思呢?
中的下标 l(x) 表示的是 哪一个类别即 ,
这一个表示的是,早某一个类别中,即在某一个channel的特征图中,比如 l(x)=k 这个类别中,像素X位置的经过交叉熵计算只后得到的概率P,再取对数,这跟普通的分类中的交叉熵损失函数其实是一个意思。
但是有一个明显的不同点是,普通的交叉熵损失前面是乘以一个真实的概率 yi,但是这里不是,这里是乘的一个 w(x) ,那它是什么意思呢?
(3)权重图 weights map
w(x) 其实就是weights map ,即所谓的权重图,其实就是在某一个通道处的特征图上,每一个像素点x对应一个 权重,然后整张特征图上面所有的像素的权重,不就组成了一张 权重图嘛。实际上就是下面这个样子的一张图:
比如这是一张特征图feature map ,上面就是每一个像素所对应的权重,即得到一张权重图。需要注意的是,本来在样本数据中,这张图里面的每一个 W 都是一个概率P的,即每一个像素的概率,但是为什么不用P而要用W呢?作者给出了解释,实际上这里的每一个W也都是通过P去计算得到的。计算公式如下:
ωc:Ω→R是用来平衡类频率的权重图
d1:Ω→R表示到背景的某个像素点到最近细胞边界的距离
d2:Ω→R表示到背景的某个像素点到第二近的细胞边界的距离
经过实验,我们将的设置为ω0=10,σ≈5个像素
论文中为什么要这么做,这么做的目的是什么呢?首先要结合论文的研究对象说起,论文是为了分割细胞的边界,所以细胞内部其实是背景色,为了更好的分割这个边界,当然这个边界自然是与突出越好,所以采用这样的计算方法的目的就在于:使网络更注重学习相互接触的细胞之间的小的分割边界。上面这个公式的理论支撑来源于形态学(morphological operations),至于什么是形态学,这里就不说明了,这其实也反映出作者的综合素养很高,知识面很广阔,能够结合实际案例进行定制。
而这个Wc(x)实际上就是 概率P 矩阵。
我们可以定性分析一下这个 W(x)矩阵的作用:
当距离d1,d2越远,后面那一块越小,几乎为0,所以你看到的远离细胞的地方,基本上权值都是一样的,接近于Wc,即在细胞边界附近的像素点给的权重会大一些,离细胞比较远的像素点的权重会小一些,为什么这么做呢?因为,如果同类细胞贴的比较近,可能就会增大训练的难度,减少准确率,毕竟卷积会考虑该像素点周围的一些特征,而两个相同的类的细胞贴在一起,就容易误判,所以对这种两个相同类贴在一起的细胞边界,给予较大的权重,使的训练之后分类分割更准确 。
(4)总结
总结:现在我们可以总结一下这个 损失函数的运算过程了,
第一步:首先根据训练数据,算出每一个样本图片的w(x),即权值图;
第二步:在某一类别k,即第 k 个channel上面对每一个像素计算交叉损失,并累加起来;
第三步:在所有的特征通道上分别进行第二部的计算,然后进行累加;
最终得到整张样本图片的损失。
二、U-Net的数据增强data augmentation
前面说过,U-Net最大的特点之一是数据增强的方式很独特,为什么?因为医学影像本身很难获得海量的样本图片,数据样本往往较少,所以需要通过预处理来适量扩充训练数据量,U-Net采用的方式是“弹性变形”。
2.1 弹性变形
这个概念其实来源于物理学,所谓弹性形变指的是材料在外力作用下产生变形,当外力取消后,材料变形即可消失并能完全恢复原来形状的性质称为弹性。这种可恢复的变形称为弹性变形。 弹性变形的重要特征是其可逆性,即受力作用后产生变形,卸除载荷后,变形消失。这反映了弹性变形决定于原子间结合力这一本质现象。很明显,生物影像,细胞图片自然是弹性形变的。
与弹性形变相对应的还有一个概念,叫做塑性形变,指的是物质-包括流体及固体在一定的条件下,在外力的作用下产生形变,当施加的外力撤除或消失后该物体不能恢复原状的一种物理现象。
这里是为了更方便的理解什么是“弹性形变”。
- 作者采用“滑动最小二乘法”进行deformation变化,从而使得网络学习到deformation不变性
- 作者采用高斯权重的距离偏移设置,从而使得网络学习到translation不变性
当然,原始论文中并没有给出关于数据增强的具体数学公式推导,只是大致性的进行了一个说明,我们只能参考源码或者是相关的学术论文来了解,这里有一篇论文可以参考:http://faculty.cs.tamu.edu/schaefer/research/mls.pdf
2.2 输入输出大小不一致怎么办
上面的结构图显示出一个问题,那就是图像输入与输出不一样大,即在最上面的结构图中,
输入是 572x572
输出是 388x388
出现这样的原因,那是因为在网络做卷积的过程中没有进行pad,导致每次卷积都会有些损失,到最后导致输出小于输入,既然输入图像与输出图像大小不一样,那自然进行损失函数的时候像素之间没有一一对应的关系,没办法计算,那怎么办呢?先看一下作者提供的思路,
在上图中,先看左侧图像,如果我的原始图像大小是红色方框这么大,要分割的位置是图像中的黄色方框,将其输入到U-Net网络中之后,经过运算,由于输入和输出大小不相等,所以得到的输出图像必然小于原始图像,那得到的右边的那个黄色框框自然也是小于原始图像的黄色框框的,
为了保证输出图像跟我的输入图像一样大,我还需要先将输入图像进行预处理,即我将输入图像(红色方框)先变大一些,记得到上图中的左边的那个大图。具体的操作是:就是对图像做镜像操作,四个边做镜像往外翻一下就扩大了图像。然后把扩大后的图像输入网络,然后输出后图像的大小刚好和输入图像的大小(即红色框框)大小一样,输出中要分割的黄色框框也和输入的图像中的黄色框框大小是一样的,这样就可以进行Loss计算了,在计算loss的时候,其实只考虑了原始的输入图像,即红色方框,镜像翻转的那部分是不参与loss计算的,通过扩大输入图片,这样,输入和输出像素之间相对的一一对应关系,就能够计算loss了。