深度学习500问——Chapter09:图像分割(1)

文章目录


9.1 图像分割算法分类

图像分割是预测图像中每一个像素所属的类别或者物体。基于深度学习的图像分割算法主要分为两类:

1. 语义分割

为图像中的每个像素分配一个类别,如把画面中的所有物体都指出它们各自的类别。

2. 实例分割

与语义分割不同,实例分割只对特定物体进行类别分配,这一点与目标检测有点相似,但目标检测输出的是边界框和类别,而实例分割输出的是掩膜(mask)和类别。

9.2 传统的基于CNN的分割方法缺点

传统的基于CNN的分割方法:为了对一个像素分类,使用该像素周围的一个图像块作为CNN的输入,用于训练与预测,这种方法主要有几个缺点:

1)存储开销大,例如,对每个像素使用 15*15 的图像块,然后不断滑动窗口,将图像块输入到CNN中进行类别判断,因此,需要的存储空间随滑动窗口的次数和大小急剧上升。

2) 效率低下,相邻像素块基本上是重复的,针对每个像素块逐个计算卷积,这种计算有很大程度上的重复;

3)像素块的大小限制了感受区域的大小,通常像素块的大小比整幅图像的大小小很多,只能取一些局部特征,从而导致分类性能受到限制。而全卷积网络(FCN)则是从抽象的特征中恢复出每个像素所属的类别。即从图像级别的分类进一步延伸到像素级别的分类。

9.3 FCN

9.3.1 FCN改变了什么

对于一般的分类CNN网络,如VGG和Resnet,都会在网络的最后加入一些全连接层,经过softmax后就可以获得类别概率信息。但是这个概率信息是1维的,即只能标识整个图片的类别,不能标识每个像素点的类别,所以这种全连接方法不适用于图像分割。而FCN提出可以把后面几个全连接都换成卷积,这样就可以获得一张二维的 feature map,后接 softmax 层获得每个像素点的分类信息,从而解决了分割问题,如图4。

图4

9.3.2 FCN网络结构

FCN对图像进行像素级的分类,从而解决了语义级别的图像分割(semantic segmentation)问题。与经典的CNN在卷积层之后使用全连接层得到固定长度的特征向量进行分类(全连接层+softmax输出)不同,FCN可以接受任意尺寸的输入图像,采用反卷积层对最后一个卷积层的feature map进行上采样,使它恢复到输入图像相同的尺寸,从而可以对每个像素都产生一个预测,同时保留了原始输入图像中的空间信息,最后在上次采样的特征图上进行逐像素分类。下图是语义分割所采用的全卷积网络(FCN)的结构示意图:

9.3.3 全卷积网络举例

通常CNN网络在卷积层之后会接上若干个全连接层,将卷积层产生的特征图(feature map)映射成一个固定长度的特征向量。以AlexNet为代表的经典CNN结构适合于图像级的分类和回归任务,因为它们最后都得到整个输入图像的一个概率向量。

如上图所示:

(1)在CNN中,猫的图片输入到AlexNet,得到一个长为1000的输出向量,表示输入图像属于每一类的概率,其中在“tabby cat”这一类统计概率最高,用来做分类任务。

(2)FCN与CNN的区别在于把CNN最后的全连接层转换成卷积层,输出的是一张已经带有标签的图片,而这个图片就可以做语义分割。

(3)CNN的强大之处在于它的多层结构能够自动学习特征,并且可以学习到多个层次的特征:较浅的卷积层感知域较小,学习到一些局部区域的特征;较深的卷积层具有较大的感知域,能够学习到更加抽象一些的特征。高层的抽象特征对物体的大小、位置和方向等敏感性更低,从而有助于识别性能的提高,所以我们常常可以将卷积层看作是特征提取器。

9.3.4 全连接层和卷积层如何相互转化

两者相互转换的可能性:

全连接层和卷积层之间唯一的不同就是卷积层中的神经元只与输入数据中的一个局部区域连接,并且在卷积列中的神经元共享参数。然而在两类层中,神经元都是计算点积,所以它们的函数形式是一样的。因此,将此两者相互转化是可能的:

(1)对于任一个卷积层,都存在一个能实现和它一样的前向传播函数的全连接层。权重矩阵是一个巨大的矩阵,除了某些特定块,其余部分都是零。而在其中大部分块中,元素都是相等的。

(2)任何全连接层都可以被转化为卷积层。比如VGG16中第一个全连接层是 25088*4096的数据尺寸,将它转化为 512*7*7*4096的数据尺寸,即一个 K=4096 的全连接层,输入数据体的尺寸是 7*7*512 ,这个全连接层可以被等效地看作一个 F=7,P=0,S=1,K=4096 的卷积层。换句话说,就是将滤波器的尺寸设置为和输入数据体的尺寸一致 7*7,这样输出就变为 1*1*4096,本质上和全连接层的输出是一样的。

输出激活数据体深度是由卷积核的数目决定的(K=4096)。

在两种变换中,将全连接层转化为卷积层在实际运用中更加有用。假设一个卷积神经网络的输入是227x227x3的图像,一系列的卷积层和下采样层将图像数据变为尺寸为7x7x512的激活数据体,AlexNet的处理方式为使用了两个尺寸为4096的全连接层。最后一个有1000个神经元的全连接层用于计算分类评分。我们可以将这3个全连接层中任意一个转化为卷积层:

   (1)第一个连接区域是[7x7x512]的全连接层,令其滤波器尺寸为F=7,K=4096,这样输出数据体就为[1x1x4096]。
   (2)第二个全连接层,令其滤波器尺寸为F=1,K=4096,这样输出数据体为[1x1x4096]。
   (3)最后一个全连接层也做类似的,令其F=1,K=1000,最终输出为[1x1x1000]。

9.3.5 为什么传统CNN的输入图片是固定大小

对于CNN,一幅输入图片在经过卷积和pooling层时,这些层是不关心图片大小的。比如对于一个卷积层,outputsize = (inputsize - kernelsize)/ stride + 1,它并不关心inputsize多大,对于一个inputsize大小的输入feature map,滑窗卷积,输出outputsize大小的feature map即可。pooling层同理。但是在进入全连接层时,feature map(假设大小为nxn)要拉成一条向量,而向量中每个元素(共nxn个)作为一个结点都要与下一个层的所有结点(假设4096个)全连接,这里的权值个数是4096 x n x n ,而我们知道神经网络结构一旦确定,它的权值个数都是固定的,所有这个n不能变化,n是conv5的outputsize,所以层层向回看,每个outputsize都要固定,那每个inputsize都要固定,因此输入图片大小要固定。

9.3.6 把全连接层的权重W重塑成卷积层的滤波器有什么好处

这样的转化可以在单个向前传播的过程中,使得卷积网络在一张更大的输入图片上滑动,从而得到多个输出(可以理解为一个label map)。

比如:我们想让 224x224 尺寸的浮窗,以步长为 32 在 384x384 的图片上滑动,把每个经停的位置都带入卷积网络,最后得到 6x6 个位置的类别得分,那么通过全连接层转化为卷积层之后的运算为:

如果 224x224 的输入图片经过卷积层和下采样层之后得到了 [7x7x512] 的数组,那么,384x384的大图片经过同样的卷积层和下采样层之后会得到 [12x12x512] 的数组,然后再经过上面由3个全连接层转化得到的3个卷积层,最终得到 [6x6x1000]的输出((12-7)/1+1=6),这个结果正是浮窗在原图经停的 6x6 个位置的得分。

一个确定的CNN网络结构之所以要固定输入图片大小,是因为全连接层权值数固定,而该权值数和feature map大小有关,但是FCN在CNN的基础上把1000个结点的全连接层改为含有1000个 1x1 卷积核的卷积层,经过这一层,还是得到二维的feature map,同样我们也不关心这个 feature map的大小,所以对于输入图片的size并没有限制。

如下图所示,FCN将传统CNN中的全连接层转化为卷积层,对应CNN网络FCN把最后三层全连接层转换为三层卷积层:

一个分类网络

变为全卷积网络

End-to-end,pixels-to pixels网络

(1)全连接层转化为全卷积层:在传统的CNN结构中,前5层是卷积层,第6层和第7层分别是一个长度为4096的一维向量,第8层是长度为1000的一维向量,分别对应1000个不同类别的概率。FCN将这3层表示为卷积层,卷积核的大小(通道数,宽,高)分别为(4096,1,1)、(4096,1,1)、(1000,1,1)。看上去数字上并没有什么差别,但是卷积跟全连接层是不一样的概念和计算过程,使用的是之前CNN已经训练好的权值和偏置,但是不一样的在于权值和偏置都是有自己的范围,属于自己的一个卷积核。

(2)CNN中输入的图像大小是统一固定成 227x227 大小的图像,第一层pooling后为 55x55,第二层pooling后图像大小为 27x27,第五层pooling后的图像大小为 13x13,而FCN输入的图像是 H*W大小,第一层pooling后变为原图大小的1/2,第二层变为原图大小的1/4,第五层变为原图大小的1/8,第八层变为原图大小的1/16。

(3)经过多次卷积和pooling以后,得到的图像越来越小,分辨率越来越低。其中图像到 H/32* W/32的图片是最小是一层时,所产生图叫做heatmap热图,热图就是我们最重要的高维特征图,得到高维特征的heatmap之后就是最重要的一步也是最后的一步对原图像进行upsampling,把图像进行放大几次到原图像的大小。

相较于使用被转化前的原始卷积神经网络对所有36个位置进行迭代计算优化模型,然后再对36个位置做预测,使用转化后的卷积神经网络进行一次前向传播计算要高效得多,因为36次计算都在共享计算资源。这一技巧在实践中经常使用,通常将一张图像尺寸变得更大,然后使用变换后的卷积神经网络来对空间上很多不同位置进行评价得到分类评分,然后求这些分值的平均值。

9.3.7 反卷积层理解

Upsampling 的操作可以看成是反卷积(deconvolutional),卷积运算的参数和CNN的参数一样是在训练FCN模型的过程中通过bp算法学习得到。反卷积层也是卷积层,不关心input的大小,滑窗卷积后输出output。deconv并不是真正的deconvolution(卷积的逆变换),最近比较公认的叫法应该是transposed convolution,deconv的前向传播就是conv的反向传播。

反卷积参数:利用卷积过程filter的转置(实际上就是水平和竖直方向上翻转filter)作为计算卷积前的特征图。

反卷积的运算如下所示:

蓝色是反卷积层的input,绿色是反卷积层的outputFull padding,transposed Full padding,transposed。

上图中的反卷积,input就是 2x2,output是 4x4。Zero padding,non-unit strides,transposed。

上图中的反卷积,input feature map是3x3,转化后是5x5,output是5x5

9.3.8 跳级(skip)结构

对CNN的结果做处理,得到了dense prediction,而作者在试验中发现,得到的分割结果比较粗糙,所以考虑加入更多前层的细节信息,也就是把倒数第几层的输出和最后的输出做一个fusion,实际上就是加和:

实验表明,这样的分割结果更细致更准确。在逐层fusion的过程中,做到第三行再往下,结果又会变差,所以作者做到这里就停了。

9.3.9 模型训练

(1)用AlexNet,VGG16或者GoogLeNet训练好的模型做初始化,在这个基础上做fine-tuning,全部都fine-tuning,只需在末尾加上upsampling,参数的学习还是利用CNN本身的反向传播原理。

(2)采用whole image做训练,不进行patchwise sampling。实验证明直接用全图已经很 effective and efficient。

(3)对class score的卷积层做全零初始化。随机初始化在性能和收敛上没有优势。

举例:

FCN例子:输入可为任意尺寸图像彩色图像;输入与输出尺寸相同,深度为:20类目标+背景=21,模型基于AlexNet。

蓝色:卷积层。

绿色:Max Pooling层。

黄色:求和运算,使用逐数据相加,把三个不同深度的预测结果进行融合:较浅的结果更为精细,较深的结果更为鲁棒。

灰色:裁剪,在融合之前,使用裁剪层统一两者大小,最后裁剪成和输入相同尺寸输出。

对于不同尺寸的输入图像,各层数据的尺寸(height,width)相应变化,深度(channel)不变。

(1)全卷积层部分进行特征提取,提取卷积层(3个蓝色层)的输出来作为预测21个类别的特征。

(2)图中虚线内是反卷积层的运算,反卷积层(3个橙色层)可以把输入数据尺寸放大。和卷积层一样,上采样的具体参数经过训练确定。

1)以经典的AlexNet分类网络为初始化。最后两级是全连接(红色),参数弃去不用。

2)从特征小图预测分割小图,之后直接上采样为大图。

反卷积(橙色)的步长为32,这个网络称为FCN-32s。

3)上采样分为两次完成(橙色x2),在第二次上采样前,把第4个pooling层(绿色)的预测结果(蓝色)融合进来。使用跳级结构提升精确性。

第二次反卷积步长为16,这个网络称为FCN-16s。

4)上采样分为三次完成(橙色x3),进一步融合了第3个pooling层的预结果。

第三次反卷积步长为8,记为FCN-8s,

 其他参数: minibatch:20张图片。

 learning rate:0.001。

初始化:分类网络之外的卷积层参数初始化为0。

反卷积参数初始化为bilinear插值。

最后一层反卷积固定位bilinear插值不做学习。

9.3.10 FCN缺点

(1)得到的结果还是不够精细。进行8倍上采样虽然比32倍的效果好了很多,但是上采样的结果还是比较模糊和平滑,对图像中的细节不敏感。

(2)对各个像素进行分类,没有充分考虑像素与像素之间的关系。忽略了在通常的基于像素分类的分割方法中使用的空间规整(spatial regularization)步骤,缺乏空间一致性。

  • 21
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
1. 什么是 Java 异常? Java 异常是指程序执行期间可能发生的错误或异常情况,例如除以零、数组越界、空指针引用等。当这些异常发生时,Java 虚拟机会抛出一个异常对象,并且程序的执行流程将被中断。 2. Java 异常处理机制有哪些关键字和语句? Java 异常处理机制包括以下关键字和语句: - try:用于包含可能会抛出异常的代码块。 - catch:用于捕获指定类型的异常,并在捕获到异常时执行相应的处理代码。 - finally:用于包含无论是否发生异常都需要执行的代码块。 - throw:用于抛出指定的异常对象。 - throws:用于声明可能会抛出指定类型异常的方法。 3. Java 中的异常分为哪几类? Java 中的异常分为两大类:Checked Exception 和 Unchecked Exception。 Checked Exception 是指在编译时就能够检查出来的异常,例如 IOException、ClassNotFoundException 等。程序必须显式地处理这些异常,否则编译不通过。 Unchecked Exception 是指在运行时才能检查出来的异常,例如 NullPointerException、ArrayIndexOutOfBoundsException 等。程序可以选择处理这些异常,但不处理也不会导致编译错误。 4. 请简要说明 try-catch-finally 的执行流程。 当程序执行到 try 块时,Java 会尝试执行其中的代码。如果在 try 块中抛出了异常,则会将异常对象传递给 catch 块进行处理。catch 块会匹配异常类型,如果匹配成功,则执行相应的处理代码。如果 catch 块处理完异常后,程序需要继续执行,则会执行 finally 块中的代码。如果 finally 块中也抛出了异常,则该异常会覆盖 try 或 catch 块中的异常。 如果 try 块中没有抛出异常,则 catch 块不会被执行。如果 finally 块中抛出异常,则该异常会覆盖 try 块中的异常。 5. 什么是异常链? 异常链是指在处理异常时,将一个异常对象作为另一个异常的原因,并将它们组合成一个异常链。这样做的好处是,在抛出异常时可以同时传递多个异常信息,从而更加清晰地表示异常发生的原因。 6. 请简要说明 try-with-resources 的作用和使用方法。 try-with-resources 是 Java 7 中引入的语法,用于自动关闭实现了 AutoCloseable 接口的资源。在 try 块中声明需要使用的资源,Java 会在 try 块执行完毕后自动关闭这些资源,无需手动调用 close 方法。 try-with-resources 的语法如下: ``` try (Resource1 r1 = new Resource1(); Resource2 r2 = new Resource2()) { // 使用资源 } catch (Exception e) { // 处理异常 } ``` 7. 请简要说明 Java 中的文本 IO。 Java 中的文本 IO 主要包括两种类:Reader 和 Writer。Reader 用于读取字符流,而 Writer 用于写入字符流。 Java 中常用的 Reader 类包括 InputStreamReader、FileReader 和 BufferedReader,常用的 Writer 类包括 OutputStreamWriter、FileWriter 和 BufferedWriter。这些类提供了各种方法来读取和写入字符流,并且可以处理多种编码格式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JOYCE_Leo16

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值