精华内容
下载资源
问答
  • 2022-03-18 14:43:05

    1.论文相关知识
    参考链接https://zhuanlan.zhihu.com/p/379325978
    2.训练技巧
    1.可以用双线性插值初始化转置卷积核
    2.至少在175个epoch之后算法才会有不错的表现
    3.学习率在一百次之后进行调整
    4.pool3之前的特征图不需要融合
    3.实验分析
    1.扩大数据规模可以提高准确率
    2.数据预处理randomly mirroring and “jittering” 对实验结果并没有明显改善
    3.数据平衡并不是必须的
    4.Fine-tuning整个网络训练效果更好

    更多相关内容
  • 全卷积神经网络FCN

    2021-07-24 20:25:40
    全连接层的缺点在于其会破坏图像的空间结构,因此人们开始使用卷积层来代替全连接层,通常采用1x1的卷积核,这种不包含全连接层的神经网络就是全卷积神经网络(FCN)。FCN最初是用于图像分割任务,之后开始在计算机...

    全连接层的缺点在于其会破坏图像的空间结构,因此人们开始使用卷积层来代替全连接层,通常采用1x1的卷积核,这种不包含全连接层的神经网络就是全卷积神经网络(FCN)。FCN最初是用于图像分割任务,之后开始在计算机视觉领域的各种任务上都得到应用。FCN的特点就在于输入和输出都是二维的,并且输入和输出具有相对应的空间结构,在这种情况下,我们可以将FCN的输出看作是一种热度图,用热度来指示检测的目标的区域。在目标所处的区域显示较高的热度,而在背景区域显示较低的热度,这也可以看成是对图像上的每一个像素点都进行了分类,这个点是否位于待检测的目标上。(摘自)

    全连接层和卷积层之间不同在于:
    1)卷积核中的权值每次滑动计算时只是局部连接,且可以共享参数,而全连接层神经元的权值与所有输入相连,产生的参数量远大于卷积层的。
    2)全连接层使得神经网络只能输入固定尺寸的图像,而全卷积神经网络可输入任意尺寸的图像。
    3)全连接层会破坏图像的空间结构,而卷积层不会破坏图像的空间结构。

    代码(pytorch)

    全连接层:fc = nn.Linear(512,1000)
    转卷积层:
    fc2conv = nn.Sequential(
    	nn.Dropout(0.5),
    	nn.Conv2d(512, 1000, kernel_size=1),	# 512x1000xWxH
    	nn.ReLU(inplace=True),
    	nn.AdaptiveAvgPool2d((1, 1))		# 512x1000x1x1
    )
    def forward(self, input):
    	out = cnn(input)
    	out = fc2conv(out)
    	out = torch.flatten(out, 1)		# 512x1000
    	return out
    
    展开全文
  • 全卷积神经网络FCN用于图像分割的工具箱(FCN for image segmentation)
  • 机器学习21:全卷积神经网络FCN

    千次阅读 2020-01-09 13:30:19
    机器学习21:全卷积神经网络FCN(整理) 看了很多关于全卷积神经网络的文章和博客,首先放上三篇我认为最有帮助以及适合入门的文章图像语义分割入门+FCN/U-Net网络解析,FCN学习:Semantic Segmentation以及10分钟看...

    机器学习21:全卷积神经网络FCN(整理)

               看了很多关于全卷积神经网络的文章和博客,首先放上三篇我认为最有帮助以及适合入门的文章图像语义分割入门+FCN/U-Net网络解析FCN学习:Semantic Segmentation以及10分钟看懂全卷积神经网络( FCN ):语义分割深度模型先驱。在学习过程中因为对全卷积神经网络中的反卷积算法理解的不够透彻,因此对反卷积算法单独整理为一篇博客机器学习17:反卷积算法

               这篇博客大多整理自前三篇文章,关于反卷积算法的原理和实现,可以参考后一篇论文。

    1.CNN 与 FCN概述:

       (1)CNN概述:

                1)CNN网络结构概述:

                      CNN在图像分类方面取得了巨大的成就。通常CNN网络有卷积层提取图像特征,在卷积层之后会接上若干个全连接层, 将卷积层产生的特征图(feature map)映射成一个固定长度的特征向量。

                      CNN的强大之处在于它的多层结构能自动学习特征,并且可以学习到多个层次的特征:

                       a.较浅的卷积层感知域较小,学习到一些局部区域的特征;

                       b.较深的卷积层具有较大的感知域,能够学习到更加抽象一些的特征。

                      这些抽象特征对物体的大小、位置和方向等敏感性更低,从而有助于识别性能的提高。下图CNN分类网络的示意图:

                     这些抽象的特征对分类很有帮助,可以很好地判断出一幅图像中包含什么类别的物体,但是因为丢失了一些物体的细节,不能很好地给出物体的具体轮廓、指出每个像素具体属于哪个物体,因此做到精确的分割就很有难度。

                     以AlexNet为代表的经典CNN结构适合于图像级的分类和回归任务,因为它们最后都期望得到整个输入图像的一个概率的数值描述,用来表示输入图像属于每一类的概率(softmax归一化)。比如下图中的猫, 输入AlexNet, 得到一个长为1000的输出向量表示输入图像属于每一类的概率, 其中在“tabby cat”这一类统计概率最高。

                2)CNN网络结构的缺点:              

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

                         a.存储开销很大。不断滑动窗口给CNN进行判别分类,因此则所需的存储空间根据滑动窗口的次数和大小急剧上升。

                         b.计算效率低下。针对互有重叠的像素块逐个计算卷积使得计算有很大程度上的重复。

                         c.像素块大小的限制了感知区域的大小。通常像素块只能提取一些局部的特征,从而导致分类的性能受到限制。

       (2)FCN概述:

                     与图像分类不同的是,图像语义分割需要判断图像每个像素点的类别从而进行精确分割,图像语义分割是像素级别的但是由于CNN在进行卷积和池化的过程中特征图逐渐变小,因此丢失了图像细节,所以不能很好地指出物体的具体轮廓、指出每个像素具体属于哪个物体,无法做到精确的分割。

                     针对这个问题,Jonathan Long等人提出了Fully Convolutional Networks(FCN)用于图像语义分割。自从提出后,FCN已经成为语义分割的基本框架,后续算法其实都是在这个框架中改进而来。FCN对图像进行像素级的分类,从而解决了语义级别的图像分割(semantic segmentation)问题。

                     经典的CNN在卷积层都会在网络的最后加入一些全连接层,经过softmax后就可以获得类别概率信息,但是这个概率信息是1维的,即只能标识整个图片的类别,不能标识每个像素点的类别,所以这种全连接方法不适用于图像分割。

                     而FCN提出可以将后面几个全连接层换成卷积层,这样就可以获得一张2维的特征图,后接softmax获得每个像素点的分类信息,从而解决了分割问题,如下图所示。

     

       (3)CNN与FCN的区别总结:

                     简单的来说,FCN与CNN的区别在把于CNN最后的全连接层换成卷积层,输出的是一张已经Label好的图片,全卷积网络(FCN)则是从抽象的特征中恢复出每个像素所属的类别,即从图像级别的分类进一步延伸到像素级别的分类。

     

    2.FCN与CNN的转化:

              全连接层和卷积层之间唯一的不同就是卷积层中的神经元只与输入数据中的一个局部区域连接,并且在卷积列中的神经元共享参数,然而在两类层中,神经元都是计算点积,所以它们的函数形式是一样的。因此,将此两者相互转化是可能的。
              全连接层与卷积层的两种变换中,将全连接层转化为卷积层在实际运用中更加有用。假设一个卷积神经网络的输入是 224x224x3 的图像,一系列的卷积层和下采样层将图像数据变为尺寸为 7x7x512 的激活数据体。AlexNet使用了两个尺寸为4096的全连接层,最后一个有1000个神经元的全连接层用于计算分类评分。我们可以将这3个全连接层中的任意全部转化为卷积层:

              针对第一个连接区域是[7x7x512]的全连接层,令其滤波器尺寸为F=7,这样输出数据体就为[1x1x4096]了;

              针对第二个全连接层,令其滤波器尺寸为F=1,这样输出数据体为[1x1x4096];

              对最后一个全连接层也做类似操作,令其F=1,最终输出为[1x1x1000]。

     

    3.FCN技术梳理:         

       (1)卷积化(convolutionalization):

                    分类所使用的网络通常会在最后连接全连接层,它会将原来二维的矩阵(图片)压缩成一维的,从而丢失了空间信息,最后训练输出一个标量,这就是我们的分类标签。 而图像语义分割的输出则需要是个二维的分割图,所以需要将全连接层替换为卷积层,而这就是所谓的卷积化。

                    再次放上第1节的图片,这张图显示了AlexNet卷积化的过程,简单来说卷积化就是将其最后三层全连接层全部替换成卷积层。

                    将全连接层换成卷积有什么好处呢?这里我们要理解一句比较专业的话:如果卷积核的 kernel_size 和输入特征图 的 size一样,那么相当于该卷积核计算了全部特征图的信息,则相当于是一个 kernel_size∗1 的全连接。这句话的大概意思为:当输入的图片大小和卷积核大小一致时,其实等价于建立全连接。                    

                    但是还是有区别的,全连接的结构是固定的,当我们训练完时每个连接都是有权重的,而卷积过程我们其实为训练连接结构,学习了目标和哪些像素之间有关系,权重较弱的像素我们可以忽略。

                    全连接不会学习过滤,只会给每个连接分权重,但是并不会修改连接关系;卷积则是会学习有用的关系,没有用到的关系它会弱化或者直接 dropout,这样卷积块可以共用一套权重,减少重复计算,还可以降低模型复杂度。

       (2)上采样(Upsampling):

                    在一般的CNN结构中,如AlexNet,VGGNet均是使用池化层来缩小输出图片的size,例如VGG16中经过五次池化后图片被缩小了32倍;而在ResNet中,某些卷积层也参与到缩小图片size的过程。 而在语意分割中我们需要得到的是一个与原图像尺寸相同的分割图,因此我们需要对最后一层进行上采样,

                    上采样也就是对应于上图中最后生成heatmap的过程。实际上,上采样(upsampling)一般包括2种方式:

                    a.Resize,如双线性插值直接缩放,类似于图像缩放;

                    b.反卷积(Deconvolution),也叫转置卷积(Transposed Convolution),此处只介绍反卷积。       

                    对于一般卷积,输入蓝色4x4矩阵,卷积核大小3x3。当设置卷积参数pad=0,stride=1时,卷积输出绿色2x2矩阵,如图所示。

                    而对于反卷积,相当于把普通卷积反过来,输入蓝色2x2矩阵,卷积核大小还是3x3。当设置反卷积参数pad=0,stride=1时输出绿色4x4矩阵,这相当于完全将普通卷积的示意图倒过来。

                    传统的网络是降采样的,对应的输出尺寸会降低;上采样的意义在于将小尺寸的高维度特征图恢复回去,以便做像素级预测,获得每个点的分类信息。上采样在FCN网络中的作用如下图所示,明显可以看到经过上采样后恢复了较大的特征图(其中最后一个层21个节点是因为该数据集有20个类别+背景),这其实相当于一个编码和解码的过程。

     

                    如下图所示,a是输入图像,b是经过卷积得到的特征图,分辨率明显下降。经过上采样(反卷积)提升分辨率得到同时,还保证了特征所在区域的权重,最后将图片的分辨率提升原图一致后,权重高的区域则为目标所在区域。

                    FCN模型处理过程也是这样,通过卷积和反卷积基本能定位到目标区域,但是模型前期是通过卷积、池化、非线性激活函数等作用输出了特征权重图像,再经过反卷积等操作输出的图像实际是很粗糙的,毕竟丢了很多细节。因此需要通过某种方式填补丢失的细节数据,所以就有了跳跃结构。

       (3跳跃结构(Skip Architecture):

                    跳跃结构主要是用来优化最终结果的,思路就是将不同池化层的结果进行上采样,然后结合这些结果来优化输出,具体结构如下:

                    而不同的结构产生的结果对比如下:

     


     4.FCN的训练过程:

              训练过程分为四个阶段, 较浅层的预测结果包含了更多细节信息。比较第二、三、四阶段可以看出,跳级结构利用浅层信息辅助逐步升采样,会产生更精细的结果。

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

    这里写图片描述

              (2)第二阶段:从特征小图(16*16*4096)预测分割小图(16*16*21),之后直接升采样为大图。 反卷积(橙色)的步长为32,这个网络称为FCN-32s。

    这里写图片描述

              (3)第三阶段:升采样分为两次完成(橙色×2),在第二次升采样前,把第4个pooling层(绿色)的预测结果(蓝色)融合进来。使用跳级结构提升精确性。 第二次反卷积步长为16,这个网络称为FCN-16s。 

    这里写图片描述

              (4)第四阶段:升采样分为三次完成(橙色×3),进一步融合了第3个pooling层的预测结果。第三次反卷积步长为8,记为FCN-8s。 

    这里写图片描述

     

    5.FCN的缺点:

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

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

     

    6.实践与代码分析

              作者在github上开源了代码:Fully Convolutional Networks,首先将项目克隆到本地。项目文件结构很清晰,如果想训练自己的模型,只需要修改一些文件路径设置即可,本文应用已经训练好的模型来测试一下自己的图片:

              下载voc-fcn32s,voc-fcn16s以及voc-fcn8s的caffemodel(根据提供好的caffemodel-url),fcn-16s和fcn32s都是缺少deploy.prototxt的,根据train.prototxt稍加修改即可。

              (1)标签图片生成:

                       从VOCdevkit处下载VOC2012的训练/验证集,解压之后,在SegmentationClass文件夹下可以看到标签图像。

                       在PIL中,图像有很多种模式,如'L'模式,’P'模式,还有常见的'RGB'模式,模式'L'为灰色图像,它的每个像素用8个bit表示,0表示黑,255表示白,其他数字表示不同的灰度。

                       模式“P”为8位彩色图像,它的每个像素用8个bit表示,其对应的彩色值是按照调色板索引值查询出来的。标签图像的模式正是'P'模式,因此测试时要生成对应标签图像的图片的话,构建一个调色板即可。

                       按照上图,对应修改调色板和infer.py,就可以测试自定义图片。如上述,对代码的主要修改是增加了一个调色板,将L模式的图像转变为P模式,得到类似标签图像的图片。接下来只需要修改script中的图片路径和model的路径,就可以测试自己的图片了。

              (2)测试结果:

                        1)结果对照:

                              下图为的最终结果,可以看出skip architecture对最终的结果确实有优化作用,这里没有对最终结果上色。

                              按照VOC的颜色设置之后,可以得到论文结果。

                        2)其他图片测试结果:

                              下面是测试其他一些图片的结果:

     

    6.参考资料:

               (1)https://zhuanlan.zhihu.com/p/30195134

               (2)https://blog.csdn.net/qq_36269513/article/details/80420363

               (3)图像语义分割入门+FCN/U-Net网络解析

               (4)FCN学习:Semantic Segmentation

               (5)10分钟看懂全卷积神经网络( FCN ):语义分割深度模型先驱

    展开全文
  • 一.导论 在图像语义分割领域,困扰了计算机科学家很多年的一个问题则是我们如何才能将我们感兴趣的...而在2015年出来的FCN全卷积神经网络完美地解决了这个问题,将曾经mean IU(识别平均准确度)只有百分之40的成绩...

    一.导论

    在图像语义分割领域,困扰了计算机科学家很多年的一个问题则是我们如何才能将我们感兴趣的对象和不感兴趣的对象分别分割开来呢?比如我们有一只小猫的图片,怎样才能够通过计算机自己对图像进行识别达到将小猫和图片当中的背景互相分割开来的效果呢?如下图所示:

     

     

     而在2015年出来的FCN,全卷积神经网络完美地解决了这个问题,将曾经mean IU(识别平均准确度)只有百分之40的成绩提升到了百分之62.2(在Pascal VOC数据集上跑的结果,FCN论文上写的),像素级别识别精确度则是90.2%。这已经是一个相当完美的结果了,几乎超越了人类对图像进行区分,分割的能力。如上图所示,小猫被分割为了背景,小猫,边缘这三个部分,因此图像当中的每一个像素最后只有三个预测值,是否为小猫,背景,或者边缘。全卷积网络要做的就是这种进行像素级别的分类任务。那么这个网络是如何设计和实现的呢?

    二.网络的实现

    这个网络的实现虽然听名字十分霸气,全卷积神经网络。不过事实上使用这个名字无非是把卷积网络的最后几层用于分类的全连接层换成了1*1的卷积网络,所以才叫这个名字。这个网络的首先对图片进行卷积——>卷积——>池化,再卷积——>卷积——>池化,直到我们的图像缩小得够小为止。这个时候就可以进行上采样,恢复图像的大小,那么什么是上采样呢?你估计还没有听说过,等下咱们一 一道来。这个网络的结构如下所示(附上论文上的原图):

     从中可以看到我们输入了一个小猫和小狗在一起时的图片,最后再前向传播,在这个前向传播网络的倒数第三层,卷积神经网络的长度就变成了N*N*21,因为在VOC数据集上一共有21个softmax分类的结果,因此每个类别都需要有一个相关概率(置信度)的输出。而前面这个前向传播的卷积神经网络可以是VGG16,也可以是AlexNet,Google Inception Net,甚至是ResNet,论文作者在前三个Net上都做了相应的尝试,但是因为ResNet当时还没出来,也就没有尝试过在前面的网络当中使用它。当我们的网络变成了一个N*N*21的输出时,我们将图像进行上采样,上采用就相当于把我们刚才得到的具有21个分类输出的结果还原成一个和原图像大小相同,channel相同的图。这个图上的每个像素点都代表了21个事物类别的概率,这样就可以得到这个图上每一个像素点应该分为哪一个类别的概率了。那么什么是图像的上采样呢?

    三.图像的上采样

    图像的上采样正好和卷积的方式相反,我们可以通过正常的卷积让图像越来越小,而上采样则可以同样通过卷积将图像变得越来越大,最后缩放成和原图像同样大小的图片,关于上采样的论文在这这篇论文当专门做了详解:https://arxiv.org/abs/1603.07285。上采样有3种常见的方法:双线性插值(bilinear),反卷积(Transposed Convolution),反池化(Unpooling)。在全卷积神经网络当中我们采用了反卷积来实现了上采样。我们先来回顾一下正向卷积,也称为下采样正向的卷积如下所示,首先我们拥有一个这样的3*3的卷积核:

     

    然后对一个5*5的特征图利用滑动窗口法进行卷积操作,padding=0,stride=1,kernel size=3,所以最后得到一个3*3的特征图:

     那么上采样呢?则是这样的,我们假定输入只是一个2*2的特征图,输出则是一个4*4的特征图,我们首先将原始2*2的map进行周围填充pading=2的操作,笔者查阅了很多资料才知道,这里周围都填充了数字0,周围的padding并不是通过神经网络训练得出来的数字。然后用一个kernel size=3,stride=1的感受野扫描这个区域,这样就可以得到一个4*4的特征图了!:

     我们甚至可以把这个2*2的feature map,每一个像素点隔开一个空格,空格里的数字填充为0,周围的padding填充的数字也全都为零,然后再继续上采样,得到一个5*5的特征图,如下所示:

     这样咱们的反卷积就完成了。那么什么是1*1卷积呢?

    四.1*1卷积

    在我们的卷积神经网络前向传播的过程当中,最后是一个N*N*21的输出,这个21是可以我们进行人为通过1*1卷积定义出来的,这样我们才能够得到一个21个类别,每个类别出现的概率,最后输出和原图图像大小一致的那个特征图,每个像素点上都有21个channel,表示这个像素点所具有的某个类别输出的概率值。吴恩达教授在讲解卷积神经网络的时候,用到了一张十分经典的图像来表示1*1卷积:

     

     原本的特征图长宽为28,channel为192,我们可以通过这种卷积,使用32个卷积核将28*28*192变成一个28*28*32的特征图。在使用1*1卷积时,得到的输出长款保持不变,channel数量和卷积核的数量相同。可以用抽象的3d立体图来表示这个过程:

     

     因此我们可以通过控制卷积核的数量,将数据进行降维或者升维。增加或者减少channel,但是feature map的长和宽是不会改变的。我们在全卷积神经网络(FCN)正向传播,下采样的最后一步(可以查看本博客的第一张图片)就是将一个N*N*4096的特征图变成了一个N*N*21的特征图。

    五.全卷积神经网络的跳级实现(skip)

    我们如果直接采用首先卷积,然后上采样得到与原图尺寸相同特征图的方法的话,进行语义分割的效果经过实验是不太好的。因为在进行卷积的时候,在特征图还比较大的时候,我们提取到的图像信息非常丰富,越到后面图像的信息丢失得就越明显。我们可以发现经过最前面的五次卷积和池化之后,原图的分别率分别缩小了2,4,8,16,32倍。对于最后一层的的图像,需要进行32倍的上采样才能够得到和原图一样的大小,但仅依靠最后一层图像做上采样,得到的结果还是不太准确,一些细节依然很不准确。因此作者采用了跳级连接的方法,即将在卷积的前几层提取到的特征图分别和后面的上采样层相连,然后再相加继续网上往上上采样,上采样多次之后就可以得到和原图大小一致的特征图了,这样也可以在还原图像的时候能够得到更多原图所拥有的信息。如下图所示:

     作者最先提出的跳级连接是把第五层的输出进行上采样,然后和池化层4的预测相结合起来,最后得到原图的策略,这个策略叫做FCN-16S,之后又尝试了和所有池化层结合起来预测的方法叫做FCN-8S,发现这个方法准确率是最高的。如下图所示:

     Ground Truth表示原始图像的人为标注,前面的都是神经网络做出的预测。跳级连接,我们这类给出的原图的大小是500*500*3,这个尺寸无所谓,因为全卷积神经网络可接受任意尺寸大小的图片。我们首先从前面绿色刚刚从池化层做完maxpool的特征图上做一次卷积然后,然后再把下一个绿色的特征图做卷积,最后把16*16*21,已经做完1*1卷积的输出,把这个三个输出相加在一起,这样就实现了跳级(skip)输入的实现,再把这几个输入融合之后的结果进行上采样,得到一个568*568*21的图,将这个图通过一个softmax层变成500*500*21的特征图,因此图像的长宽和原图一模一样了,每一个像素点都有21个概率值,表示这个像素点属于某个类别的概率,除了和原图的channel不同之外没啥不同的。

    然后我们来看基于Tensorflow的代码实现。

    六.Tensorflow代码实现全卷积神经网络

    首先导包并读取图片数据:

    import tensorflow as tf
    import matplotlib.pyplot as plt
    import numpy as np
    import os
    
    import glob
    images=glob.glob(r"F:\UNIVERSITY STUDY\AI\dataset\FCN\images\*.jpg")
    #然后读取目标图像
    anno=glob.glob(r"F:\UNIVERSITY STUDY\AI\dataset\FCN\annotations\trimaps\*.png")

    glob库可以用于读取本地的图片并用来制作每一个batch的数据,我把数据集放在了F:\UNIVERSITY STUDY\AI\dataset\FCN\,这个文件夹下。

    幂image文件夹用于装载训练集的图片,annatation文件夹用于装载人们标注边界的数据集。

    标注的图片显示如下:

     

     

    原始图是一个小狗的图片,原始图在下面:

     然后制作dataset,batch数据,以及读取图片文件的函数,包括png和jpg分别进行解析为三维矩阵:

    #现在对读取进来的数据进行制作batch
    np.random.seed(2019)
    index=np.random.permutation(len(images))
    
    images=np.array(images)[index]
    anno=np.array(anno)[index]
    #创建dataset
    dataset=tf.data.Dataset.from_tensor_slices((images,anno))
    test_count=int(len(images)*0.2)
    train_count=len(images)-test_count
    data_train=dataset.skip(test_count)
    data_test=dataset.take(test_count)
    
    def read_jpg(path):
        img=tf.io.read_file(path)
        img=tf.image.decode_jpeg(img,channels=3)
        return img
    
    def read_png(path):
        img=tf.io.read_file(path)
        img=tf.image.decode_png(img,channels=1)
        return img
    
    #现在编写归一化的函数
    def normal_img(input_images,input_anno):
        input_images=tf.cast(input_images,tf.float32)
        input_images=input_images/127.5-1
        input_anno-=1
        return input_images,input_ann
    
    #加载函数
    def load_images(input_images_path,input_anno_path):
        input_image=read_jpg(input_images_path)
        input_anno=read_png(input_anno_path)
        input_image=tf.image.resize(input_image,(224,224))
        input_anno=tf.image.resize(input_anno,(224,224))
        return normal_img(input_image,input_anno)
    
    data_train=data_train.map(load_images,num_parallel_calls=tf.data.experimental.AUTOTUNE)
    data_test=data_test.map(load_images,num_parallel_calls=tf.data.experimental.AUTOTUNE)
    
    #现在开始batch的制作
    BATCH_SIZE=3#根据显存进行调整
    data_train=data_train.repeat().shuffle(100).batch(BATCH_SIZE)
    
    data_test=data_test.batch(BATCH_SIZE)

    然后我们使用VGG16进行卷积操作,同时使用imagenet的预训练模型进行迁移学习,搭建神经网络和跳级连接:

    conv_base=tf.keras.applications.VGG16(weights='imagenet',
                                         input_shape=(224,224,3),
                                         include_top=False)
    #现在创建子model用于继承conv_base的权重,用于获取模型的中间输出
    #使用这个方法居然能够继承,而没有显式的指定到底继承哪一个模型,确实神奇
    #确实是可以使用这个的,这个方法就是在模型建立完之后再进行的调用
    #这样就会继续自动继承之前的网络结构
    #而如果定义
    sub_model=tf.keras.models.Model(inputs=conv_base.input,
                                   outputs=conv_base.get_layer('block5_conv3').output)
    
    #现在创建多输出模型,三个output
    layer_names=[
        'block5_conv3',
        'block4_conv3',
        'block3_conv3',
        'block5_pool'
    ]
    
    layers_output=[conv_base.get_layer(layer_name).output for layer_name in layer_names]
    
    #创建一个多输出模型,这样一张图片经过这个网络之后,就会有多个输出值了
    #不过输出值虽然有了,怎么能够进行跳级连接呢?
    multiout_model=tf.keras.models.Model(inputs=conv_base.input,
                                   outputs=layers_output)
    
    multiout_model.trainable=False
    
    inputs=tf.keras.layers.Input(shape=(224,224,3))
    #这个多输出模型会输出多个值,因此前面用多个参数来接受即可。
    out_block5_conv3,out_block4_conv3,out_block3_conv3,out=multiout_model(inputs)
    #现在将最后一层输出的结果进行上采样,然后分别和中间层多输出的结果进行相加,实现跳级连接
    #这里表示有512个卷积核,filter的大小是3*3
    x1=tf.keras.layers.Conv2DTranspose(512,3,
                                       strides=2,
                                       padding='same',
                                       activation='relu')(out)
    #上采样之后再加上一层卷积来提取特征
    x1=tf.keras.layers.Conv2D(512,3,padding='same',
                                       activation='relu')(x1)
    #与多输出结果的倒数第二层进行相加,shape不变
    x2=tf.add(x1,out_block5_conv3)
    #x2进行上采样
    x2=tf.keras.layers.Conv2DTranspose(512,3,
                                       strides=2,
                                       padding='same',
                                       activation='relu')(x2)
    #直接拿到x3,不使用
    x3=tf.add(x2,out_block4_conv3)
    #x3进行上采样
    x3=tf.keras.layers.Conv2DTranspose(256,3,
                                       strides=2,
                                       padding='same',
                                       activation='relu')(x3)
    #增加卷积提取特征
    x3=tf.keras.layers.Conv2D(256,3,padding='same',activation='relu')(x3)
    x4=tf.add(x3,out_block3_conv3)
    #x4还需要再次进行上采样,得到和原图一样大小的图片,再进行分类
    x5=tf.keras.layers.Conv2DTranspose(128,3,
                                       strides=2,
                                       padding='same',
                                       activation='relu')(x4)
    #继续进行卷积提取特征
    x5=tf.keras.layers.Conv2D(128,3,padding='same',activation='relu')(x5)
    #最后一步,图像还原
    preditcion=tf.keras.layers.Conv2DTranspose(3,3,
                                       strides=2,
                                       padding='same',
                                       activation='softmax')(x5)
    
    model=tf.keras.models.Model(
    inputs=inputs,
    outputs=preditcion
    )

    编译和fit模型:

    model.compile(
    optimizer='adam',
        loss='sparse_categorical_crossentropy',
        metrics=['acc']#这个参数应该是用来打印正确率用的,现在终于理解啦啊
    )
    
    model.fit(data_train,
             epochs=1,
             steps_per_epoch=train_count//BATCH_SIZE,
             validation_data=data_test,
             validation_steps=train_count//BATCH_SIZE)

    输出:

    Train for 1970 steps, validate for 1970 steps
    1969/1970 [============================>.] - ETA: 1s - loss: 0.3272 - acc: 0.8699WARNING:tensorflow:Your input ran out of data; interrupting training. Make sure that your dataset or generator can generate at least `steps_per_epoch * epochs` batches (in this case, 1970 batches). You may need to use the repeat() function when building your dataset.
    1970/1970 [==============================] - 3233s 2s/step - loss: 0.3271 - acc: 0.8699 - val_loss: 0.0661 - val_acc: 0.8905

    结果只用了一个epoch,像素精确度就已经达到了百分之89了,是不是很神奇呢?嘿嘿

    展开全文
  • AI 全卷积神经网络 FCN

    2019-05-26 23:51:45
    FCN Demo: https://github.com/shelhamer/fcn.berkeleyvision.org Last Edited: Mar 29, 2019 9:08 AM Tags: FCN 论文地址: https://arxiv.org/pdf/1411.4038.pdf 前言 全称:Fully Convolution ...
  • 一.导论 在图像语义分割领域,困扰了计算机科学家很多年的一个问题则是我们如何才能将我们...而在2015年出来的FCN全卷积神经网络完美地解决了这个问题,将曾经mean IU(识别平均准确度)只有百分之40的成绩提升到了...
  • 神经网络大神Jonathan Long发表了《Fully Convolutional Networks for Semantic Segmentation》在图像语义分割挖了一个坑,于是无穷无尽的人往坑里面跳。 全卷积网络 Fully Convolutional Netw...
  • FCN全卷积神经网络

    千次阅读 2019-01-15 16:20:25
    CNN的强大之处在于它的多层神经网络结构能够自动学习影像的深层次特征。同时CNN的局部感知、权值共享、下采样的特点,是学习到的特征具有平移、旋转、缩放不变性,这保证了网络结构能够适应不同形态的二维图像,更...
  • 图像分割之FCN全卷积神经网络

    千次阅读 2022-04-13 15:41:13
    图像分割开山之作:全卷积神经网络FCN
  • 这篇论文使用全卷积神经网络来做语义上的图像分割,开创了这一领域的先河。看了一天这个论文,结合网上别的其他资料,对这篇论文比较好的解读有: 1 https://leonardoaraujosantos.gitbooks.io/artificial-in...
  • 全卷积神经网络FCN)和卷积神经网络(CNN)的主要区别在于FCN将CNN末尾的全连接层转化成了卷积层。 例如,经过卷积、池化后,图像的大小变为4(长)×4(宽)×512(通道数)。CNN将图像送入全连接层,而FCN将...
  • 语义分割: 简单地说,分割就是抠图。...这项技术在医学上的作用也同样巨大,我们可以识别病灶并将其与正常组织分割,大脑神经系统内我们可以分离出同一组功能的神经系统,这些假如依赖人工去完成,所需时间至少为数小
  • 全卷积神经网络FCN模型Unet 图像分割项目实践

    千次阅读 多人点赞 2019-05-15 01:40:30
    前言 本文基于下面链接的项目, 实践一次基于Unet模型的图像分割. 个人在实现时遇到很多问题, 许多问题在网上并没有找到解答, 所以写下本文, 记录了在实现过程中遇到的问题和大部分代码的注解, 主要从代码逻辑入手, ...
  • 什么是全卷积神经网络(Fully Convolutional Networks)2. FCN是语义分割的奠基性工作3. 使用FCN进行语义分割3.1 模型构建3.2 初始化转置卷积层3.3 读取数据集3.4 训练3.5 预测 参考: 【1】https://zh-v2.d2l.ai/ ...
  • 11.连接卷积神经网络 FCN

    千次阅读 2022-04-27 21:40:45
    视频:48 全连接卷积神经网络 FCN【动手学深度学习v2】_哔哩哔哩_bilibili 书籍:13.11. 全卷积网络 — 动手学深度学习 2.0.0-beta0 documentation (d2l.ai) PPT:part-2_16.pdf (d2l.ai) 代码:fcn slides (d2l.ai)...
  • 全卷积神经网络FCN-TensorFlow代码精析

    万次阅读 多人点赞 2018-04-24 20:38:19
    FCN-TensorFlow完整代码Github:https://github.com/EternityZY/FCN-TensorFlow.git这里解析所有代码 并加入详细注释注意事项:请按照代码中要求,将VGG-19模型和训练集下载好,运行下载很慢。MODEL_URL = '...
  • 感受域 感受野的计算公式:RFl+1 = RFl + ...在全卷积神经网络中感受域问题存在????和熊掌不可兼得的问题: 增大stride能够获得更大的感受野,但同时会丢失图像中的信息。 解决方法 deeplab系列提出了空洞卷积的方
  • FCN全卷积神经网络)详解

    千次阅读 2021-09-27 16:15:18
    全卷积网络(Fully Convolutional Networks,FCN)是Jonathan Long等人于2015年在Fully Convolutional Networks for Semantic Segmentation一文中提出的用于图像语义分割的一种框架,是深度学习用于语义分割领域的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,028
精华内容 2,411
关键字:

全卷积神经网络fcn