Fully Convolutional Networks
FCN与CNN的区别:
简单的来说,FCN把于CNN最后的全连接层换成卷积层,使用反卷积上采样恢复原图大小,最后逐个像素计算softmax分类的损失,输出的是一张已经Label好的图片。
CNN:通常CNN网络在卷积层之后会接上若干个全连接层, 将卷积层产生的特征图(feature map)映射成一个固定长度的特征向量。以AlexNet为代表的经典CNN结构适合于图像级的分类和回归任务,因为它们最后都期望得到整个输入图像的一个数值描述(概率),比如AlexNet的ImageNet模型输出一个1000维的向量表示输入图像属于每一类的概率(softmax归一化)
FCN:对图像进行像素级的分类,从而解决了语义级别的图像分割(semantic segmentation)问题。FCN可以接受任意尺寸的输入图像,采用反卷积层对最后一个卷积层的feature map进行上采样, 使它恢复到输入图像相同的尺寸,从而可以对每个像素都产生了一个预测, 同时保留了原始输入图像中的空间信息, 最后在上采样的特征图上进行逐像素分类。最后逐个像素计算softmax分类的损失, 相当于每一个像素对应一个训练样本。
变化:
在传统的CNN结构中,前5层是卷积层,第6层和第7层分别是一个长度为4096的一维向量,第8层是长度为1000的一维向量,分别对应1000个类别的概率。
FCN将这3层表示为卷积层,卷积核的大小(通道数,宽,高)分别为[4096,1,1]、[4096,1,1]、[1000,1,1]。所有的层都是卷积层,故称为全卷积网络。
卷积conv:
-
valid
滑动步长为S,图片大小为N1xN1,卷积核大小为N2xN2,卷积后图像大小:(N1-N2)/S+1 x (N1-N2)/S+1
-
same
滑动步长为1,图片大小为N1xN1,卷积核大小为N2xN2,卷积后图像大小:N1xN1
-
full
滑动步长为1,图片大小为N1xN1,卷积核大小为N2xN2,卷积后图像大小:(N1+N2-1) x (N1+N2-1)
反卷积deconv:
其实卷积层的前向传播过程就是反卷积层的反向传播过程,卷积层的反向传播过程就是反卷积层的前向传播过程。
反卷积的工作过程,和卷积的工作过程差不多,主要的区别在于:反卷积输出的图片的尺寸会大于输入图片的尺寸,通过增加padding来实现。
stride=1的反卷积过程:在进行反卷积的时候设置的stride并不是指反卷积在进行卷积时候卷积核的移动步长,而是被卷积矩阵填充的padding
stride=2的反全卷积过程:
总结:
- 通过反卷积并不能还原卷积之前的矩阵,只能从大小上进行还原,反卷积的本质还是卷积,只是在进行卷积之前,会进行一个自动的padding补0,从而使得输出的矩阵与指定输出矩阵的shape相同。
- 可以发现因为卷积核是(3x3),所以外圈总是补两圈0,也就卷积核和红圈矩阵左上角只相交一个元素。
- stride为1中间不补零,为2中间补一排零,依次类推。
- 反卷积过程就是:填充0->padding->卷积->裁剪(如果有的话)
FCN思想:
- 不含全连接层(fc)的全卷积(fully conv)网络。可适应任意尺寸输入。
- 增大数据尺寸的反卷积(deconv)层。能够输出精细的结果。
- 结合不同深度层结果的跳级(skip)结构,可以同时确保鲁棒性和精确性。
FCN网络结构:
其中:
- 输入可为任意尺寸图像彩色图像
- 输出与输入尺寸相同
- 深度为:20类目标+背景=21
虚线上,全卷积提取特征:
- 蓝色:conv+bn+relu
- 绿色:max-pooling
对于不同尺寸的输入图像,各层数据的尺寸(height,width)相应变化,feature map数量(channel)不变。
这部分由深度学习分类问题中经典网络AlexNet1/VGG16修改而来。只不过,把最后两个全连接层(fc)改成了卷积层。
虚线下,反卷积逐像素预测:
- 蓝色:con(1x1,21)用来降维
- 橙色:deconv,可以把输入数据尺寸放大
- 黄色:add,逐数据相加,把三个不同深度的预测结果进行融合:较浅的结果更为精细,较深的结果更为鲁棒
- 灰色:crop,使用裁剪层统一两者大小,最后裁剪成和输入相同尺寸输出
分别从卷积网络的不同阶段,以卷积层(蓝色×3)预测深度为21的分类结果。
在论文中FCN使用了上采样。例如经过5次卷积(和pooling)以后,图像的分辨率依次缩小了2,4,8,16,32倍。
为了得到原图一样的大小,需要对图片进行上采样,这个上采样是通过反卷积(deconvolution)实现的。
最后一层的输出图像,需要进行32倍的上采样,对第5层的输出(32倍放大)反卷积到原图大小,得到的结果还是不够精确,一些细节无法恢复。于是将第4层的输出和第3层的输出也依次反卷积,分别需要16倍和8倍上采样,结果就精细一些了。
训练:
- 第一阶段:
以经典的分类网络为初始化。最后两级是全连接(红色),参数弃去不用。
- 第二阶段:
特征图先用(1x1,21)的卷积核进行卷积,大小从(16x16x4096)变为(16*16*21)就是21分类。
再上采样变为大图。反卷积(橙色)的步长为32,这个网络称为FCN-32s。
- 第三阶段:
升采样分为两次完成(橙色×2)。
在第二次升采样前,把第4个pooling层(绿色)的预测结果(蓝色)融合进来。使用跳级结构提升精确性。
第二次反卷积步长为16,这个网络称为FCN-16s。
- 第四阶段:
升采样分为三次完成(橙色×3)。
进一步融合了第3个pooling层的预测结果。
第三次反卷积步长为8,记为FCN-8s。
较浅层的预测结果包含了更多细节信息。比较2,3,4阶段可以看出,跳级结构利用浅层信息辅助逐步升采样,有更精细的结果。
总结:想要精确预测每个像素的分割结果
- 必须经历从大到小,再从小到大的两个过程
- 在升采样过程中,分阶段增大比一步到位效果更好
- 在升采样的每个阶段,使用降采样对应层的特征进行辅助
参考:http://www.cnblogs.com/gujianhan/p/6030639.html & https://blog.csdn.net/qq_36269513/article/details/80420363
loss
交叉熵损失
Unet
主要针对生物医学图像分割。
Unet是完全对称的,而且对解码器进行了卷积加深处理,FCN只是单纯上采样。
编码器:将图像image->高语义feature map的过程看成编码器
解码器:将高语义->像素级别的分类score map的过程看作解码器
采用了核FCN一样的Skip connection结构
Concat联合:在FCN中,Skip connection的联合是通过对应像素的求和,而U-Net则是对其的channel的concat过程
算法结构:
1.算法和FCN一样,都是把图片先进行下采样得到feature map,再进行上采样得到score map 的像素级分类。
2.因为这里是医学图像,所以通道数是1。
3.先连续2个(3x3)conv+Relu,stride=1,因为是Valid卷积,可以保证分割的结果都是基于没有缺失的上下文特征得到的,,但是会使得feature map大小减小2(这也是下面要进行裁剪的原因)。不过但是在keras上代码做的都是same convolution,ORZ。
4.再通过(2x2)max pool来进行1/2的下采样,padding=Valid(same 策略会在边缘填充0,保证featuremap的每个值都会被取到,vaild会忽略掉不能进行下去的pooling操作,而不是进行填充)。
5.再skip connection结构的concat操作的时候大小不一致,需要对下采样的feature map进行copy&crop操作,crop就是裁剪。
6.上采样,这里是一个up-conv(2x2),操作会将featuremap的大小乘2。
7.输出的最后一层,使用了(1x1)卷积来进行2分类(是否为轮廓)。
Overlap-tile strategy
Unet的结构中没有全连接,这就表示Unet的输入图片的大小其实是可以不固定的。无论训练还是测试的时候,都可以放一整张图片进去。Unet最开始是为了处理医疗图像的,一般医疗图像都非常大,所以用一个滑动窗口把原图扫一边,使用原图的切片进行训练或测试。
但是现在出现一个问题:图像输入(每个黄色滑窗)与输出不一样大。因为在网络做卷积的过程中没有进行padding,导致每次卷积都会有些损失,到最后导致输出小于输入,其实在进行Loss回归的过程中,是用黄色滑窗上的每个点与输出的图像的每个点进行对比,然后得到Loss,但是这个不一样大怎么进行每个像素点的对比,这个时候作者是这样做的,他把输入图像先扩大,怎么扩大呢,就是对图像做镜像操作,四个边做镜像往外翻一下就扩大了图像,你看看下图就知道了,然后把扩大后的图像输入网络,然后输出后刚好和黄色滑窗的图像大小是一样的,这样就可以进行Loss回归了。
Overlap-title策略用于无缝分割任意大小图像的重叠平铺策略。(这里是EM堆栈中神经元结构的分割)。预测黄色区域中的分割,需要蓝色区域内的图像数据作为输入。通过镜像复制得到缺少输入数据。
LOSS
最后的heatmap,再用一个(1X1)的卷积做分类,这里最终输出的是两个通道的特征图,即分成两类:背景和前景,因为这个是对医学图像做的处理,只分背景和前景。
特征图上的像素级 softmax 值计算:
pixel-wise softmax,就是每个像素对应的输出单独做softmax,也就是做了w*h个softmax
- αk(x) 代表在位置 x 处的像素在特征图中的第 k 层的激活值,也就是表示每一像素点(x)对应特征通道(k)的得分。
- K 是像素点的类别总数
- pk(x)是类k的对像素点x的分类结果,就是概率
损失函数:
是每个像素的真实标签
是之前介绍的权重图,用来让某些像素更加重要
权重图:
我们通过预先计算权重图的来获得每一个像素在损失函数中的权值,这种方法补偿了训练数据每类像素的不同频率,并且使网络更注重学习相互接触的细胞间的边缘。分割边界使用形态学运算,特征图的计算方法如下:
- ωc:Ω→R是用来平衡类频率的权重图
- d1:Ω→R表示到背景的某个像素点到最近细胞边界的距离
- d2:Ω→R表示到背景的某个像素点到第二近的细胞边界的距离
权重初始化相当重要,我们使用高斯分布初始化权重,标准差为,其中N表示一个神经元的输入节点是的数量,如,对于一个3x3的卷积,前一层有64个feature channel,那么N=3∗3∗64=576。
源码分析: