文献阅读笔记:全卷积神经网络

文献阅读笔记:全卷积神经网络

  • 摘要
  • Abstract
  • 1. 全卷积神经网络
    • 1.1 文献摘要
    • 1.2 全卷积神经网络
      • 1.2.1 网络结构
      • 1.2.0 从分类器到密集 FCN
      • 1.2.2 上采样 Upsampling
      • 1.2.3 跳级结构
      • 1.2.4 FCN训练
    • 1.3 实验
    • 1.4 总结
  • 2. 代码实现

摘要

本周学习了全卷积神经网络,全卷积神经网络(Fully Convolutional Network,FCN)是深度学习在语义分割领域的开山之作,其特点在于将传统卷积神经网络(CNN)中的全连接层替换为卷积层,使得网络的输出为热力图而非类别,这种设计使得FCN可以接受任意尺寸的输入图像,并对其进行像素级的分类,从而解决了语义级别的图像分割问题,FCN的主要优势在于其灵活性和高效性。由于去除了全连接层,FCN可以适应任意尺寸的输入,这在处理不同尺寸的图像时非常有用。本文将详细介绍全卷积神经网络。

Abstract

This week, we learned about Fully Convolutional Neural Networks (FCN), which is the groundbreaking work of deep learning in the field of semantic segmentation, and is characterized by replacing the fully-connected layer in traditional Convolutional Neural Networks (CNNs) with a convolutional layer so that the output of the network is a heat map instead of a category, and this design allows FCNs to accept input images of arbitrary size and classify them at the pixel level, thus solving the problem of image segmentation at the semantic level.The main advantages of FCN are its flexibility and efficiency. Due to the removal of the fully connected layer, FCNs can adapt to inputs of arbitrary size, which is very useful when dealing with images of different sizes. In this paper, we will introduce Full Convolutional Neural Networks in detail.

Translated with DeepL.com (free version)

1. 全卷积神经网络

文献链接:

1.1 文献摘要

作者在本文中提出了全卷积神经网络,该网络接受任意大小的输入并通过有效的推理和学习产生相应大小的输出。作者在本文中定义并详细介绍了全卷积网络的空间,解释了它们在空间密集预测任务中的应用,并与先前的模型建立了联系。该网络中还有跳跃架构,它将来自深层、粗糙层的语义信息与来自浅层、精细层的外观信息相结合,以产生准确而详细的分割。

1.2 全卷积神经网络

卷积网络中的每一层数据都是一个大小为 h × w × d 的三维数组,其中 h 和 w 是空间维度,d 是特征或通道维度。第一层是图像,像素大小为 h × w,有 d 个颜色通道。较高层中的位置对应于它们路径连接到的图像中的位置,称为它们的感受野。

卷积网络建立在平移不变性的基础上。它们的基本组件(卷积、池化和激活函数)在局部输入区域上运行,并且仅依赖于相对空间坐标。将 x i j x_{ij} xij 写入特定层中位置 (i, j) 处的数据向量,并将 y i j y_{ij} yij 写入后续层,这些函数通过以下方式计算输出 y i j y_{ij} yij

1.2.1 网络结构

FCN网络结构主要分为两个部分:全卷积部分和反卷积部分。其中全卷积部分为一些经典的CNN网络(如VGG,ResNet等),用于提取特征;反卷积部分则是通过上采样得到原尺寸的语义分割图像。FCN的输入可以为任意尺寸的彩色图像,输出与输入尺寸相同,通道数为n(目标类别数)+1(背景)。FCN网络结构如下:
在这里插入图片描述

1.2.0 从分类器到密集 FCN

对于GoogLeNet,作者仅使用最终的损失层,并通过丢弃最终的平均池化层来提高性能。我们通过丢弃最终的分类器层来斩首每个网络,并将所有全连接层转换为卷积层。 作者附加一个通道维度为 21 的 1 × 1 卷积来预测每个粗略输出位置处每个 PASCAL 类(包括背景)的分数,然后是一个反卷积层,将粗略输出双线性上采样为像素密集输出,下表比较了初步验证结果以及每个网络的基本特征。
在这里插入图片描述
从分类到分割的微调为每个网络提供了合理的预测。即使是最差的模型也能达到最先进性能的 75%。

尽管完全卷积分类器可以像上述所示进行微调以进行分割,甚至在标准指标上得分很高,但它们的输出却非常粗糙(见图 4)。最终预测层的 32 像素步长限制了上采样输出中的细节比例。作者通过添加跳跃融合连接来解决这个问题,该跳跃将最终预测层与具有更精细步长的较低层结合起来。这会将线型拓扑转变为 DAG,其边缘从较低层跳到较高层。由于他们看到的像素更少,更精细的尺度预测应该需要更少的层,因此从更浅的网络输出中制作它们是有意义的。结合精细层和粗略层,模型可以做出尊重全局结构的局部预测。
在这里插入图片描述

1.2.2 上采样 Upsampling

在卷积过程的卷积操作和池化操作会使得特征图的尺寸变小,为得到原图像大小的稠密像素预测,需要对得到的特征图进行上采样操作。可通过双线性插值(Bilinear)实现上采样,且双线性插值易于通过固定卷积核的转置卷积(transposed convolution)实现,转置卷积即为反卷积(deconvolution)。在论文中,作者并没有固定卷积核,而是让卷积核变成可学习的参数。转置卷积操作过程如下:

在这里插入图片描述

1.2.3 跳级结构

如果仅对最后一层的特征图进行上采样得到原图大小的分割,最终的分割效果往往并不理想。因为最后一层的特征图太小,这意味着过多细节的丢失。因此,通过跳级结构将最后一层的预测(富有全局信息)和更浅层(富有局部信息)的预测结合起来,在遵守全局预测的同时进行局部预测。

将底层(stride 32)的预测(FCN-32s)进行2倍的上采样得到原尺寸的图像,并与从pool4层(stride 16)进行的预测融合起来(相加),这一部分的网络被称为FCN-16s。随后将这一部分的预测再进行一次2倍的上采样并与从pool3层得到的预测融合起来,这一部分的网络被称为FCN-8s。图示如下:
在这里插入图片描述

1.2.4 FCN训练

阶段1:以经典的分类网络为初始化,最后两级为全连接(红色),参数弃去不用。
在这里插入图片描述
阶段2:FCN-32s 网络—从特征小图预测分割小图,之后直接升采样为大图。
在这里插入图片描述
阶段3:FCN-16s 网络—上采样分为两次完成。在第二次升采样前,把第4个pooling层的预测结果融合进来,使用跳级结构提升精确性。
在这里插入图片描述
阶段4:FCN-8s 网络—升采样分为三次完成。 进一步融合了第3个pooling层的预测结果。
在这里插入图片描述

1.3 实验

作者在语义分割和场景解析上测试 FCN,探索 PASCAL VOC、NYUDv2 和 SIFT Flow。尽管这些任务历史上区分了对象和区域,但作者将它们统一视为像素预测。我们在每个数据集上评估我们的 FCN 跳跃架构,然后将其扩展到 NYUDv2 的多模态输入以及 SIFT Flow 的语义和几何标签的多任务预测。下表给出了作者提出的 FCN-8 在 PASCAL VOC 2011 和 2012 测试集上的性能,并将其与之前最先进的 SDS和著名的 R-CNN。我们在平均 IU8 上取得了最佳结果,相对优势为 20%。推理时间减少了 114 倍(仅限卷积网络,忽略提案和细化)或 286 倍(总体)。
在这里插入图片描述
NYUDv2 是使用 Microsoft Kinect 收集的 RGB-D 数据集。它有 1449 张 RGB-D 图像,带有像素标签,已被 Gupta 等人合并为 40 类语义分割任务。我们报告了 795 个训练图像和 654 个测试图像的标准分割结果。 (注:所有模型选择均在 PASCAL 2011 val 上进行。)下表给出了我们的模型在几种变体中的性能。首先,我们在 RGB 图像上训练未经修改的粗略模型 (FCN-32s)。为了添加深度信息,我们对升级后的模型进行训练,以采用四通道 RGB-D 输入(早期融合)。
在这里插入图片描述

1.4 总结

全卷积网络是一类丰富的模型,现代分类卷积网络是其中的一个特例。认识到这一点,将这些分类网络扩展到分段,并通过多分辨率层组合改进架构,可以显着提高最先进的水平,同时简化和加速学习和推理。全卷积神经网络(Fully Convolutional Network,FCN)是深度学习在语义分割领域的开山之作,其特点在于将传统卷积神经网络(CNN)中的全连接层替换为卷积层,使得网络的输出为热力图而非类别。这种设计使得FCN可以接受任意尺寸的输入图像,并对其进行像素级的分类,从而解决了语义级别的图像分割问题。FCN的主要优势在于其灵活性和高效性。由于去除了全连接层,FCN可以适应任意尺寸的输入,这在处理不同尺寸的图像时非常有用。此外,FCN使用转置卷积(也称为反卷积)层对特征图进行上采样,使其恢复到输入图像相同的尺寸,从而可以对每一个像素都产生一个预测。这种设计保留了原始输入图像中的空间信息,使得预测结果更加精确。在实际应用中,FCN已被广泛应用于目标分割、目标检测、目标分类等研究领域,并取得了令人瞩目的成果。例如,在医学图像分割中,FCN可以精确地识别出病变区域;在自动驾驶领域,FCN可以用于识别道路、车辆和行人等关键元素。

然而,值得注意的是,虽然FCN在图像分割方面取得了显著进展,但它仍然存在一些挑战和限制。例如,对于某些复杂的场景或物体,FCN可能难以准确地进行分割;此外,由于FCN需要进行像素级的预测,因此其计算复杂度相对较高,可能需要大量的计算资源和时间。

2. 代码实现

此处使用paddle深度学习框架进行网络模型的搭建,以下为网络结构代码:

class FCN8s(nn.Layer):
    def __init__(self, num_classes=21):
        super(FCN8s, self).__init__()
        # num_classes要包含背景,如果是PASCAL VOC则是20+1
        self.layer1 = self.make_block(num=2, in_channels=3, out_channels=64)
        self.layer2 = self.make_block(num=2, in_channels=64, out_channels=128)
        self.layer3 = self.make_block(num=3, in_channels=128, out_channels=256)
        self.layer4 = self.make_block(num=3, in_channels=256, out_channels=512)
        self.layer5 = self.make_block(num=3, in_channels=512, out_channels=512)
        # 下面的两个卷积层代替了原来VGG网络的全连接层(原本为4096,此处可根据gpu性能,设置为其他数,此处设为2048)
        mid_channels = 2048
        self.conv6 = nn.Conv2D(in_channels=512, out_channels=mid_channels, kernel_size=7, padding=3)
        self.conv7 = nn.Conv2D(in_channels=mid_channels, out_channels=mid_channels, kernel_size=1)
        
        # 3个1*1的卷积,用于改变pool的通道数,为了后续融合语义信息
        self.score32 = nn.Conv2D(in_channels=mid_channels, out_channels=num_classes, kernel_size=1)
        self.score16 = nn.Conv2D(in_channels=512, out_channels=num_classes, kernel_size=1)
        self.score8 = nn.Conv2D(in_channels=256, out_channels=num_classes, kernel_size=1)
        
        # 3个转置卷积,用于扩大特征图
        # 若参数kernel_size:stride:padding=4:2:1,此时stride为扩大倍数
        weight_8x = paddle.ParamAttr(
            initializer=paddle.nn.initializer.Assign(bilinear_kernel(num_classes, num_classes, 16))
        )
        self.up_sample8x = nn.Conv2DTranspose(
            in_channels=num_classes,
            out_channels=num_classes,
            kernel_size=16, stride=8, padding=4,
            weight_attr=weight_8x
        )
        
        weight_16x = paddle.ParamAttr(
            initializer=paddle.nn.initializer.Assign(bilinear_kernel(num_classes, num_classes, 4))
        )
        self.up_sample16x = nn.Conv2DTranspose(
            in_channels=num_classes,
            out_channels=num_classes,
            kernel_size=4, stride=2, padding=1,
            weight_attr=weight_16x
        )
        
        weight_32x = paddle.ParamAttr(
            initializer=paddle.nn.initializer.Assign(bilinear_kernel(num_classes, num_classes, 4))
        )
        self.up_sample32x = nn.Conv2DTranspose(
            in_channels=num_classes,
            out_channels=num_classes,
            kernel_size=4, stride=2, padding=1,
            weight_attr=weight_32x
        )  
        
    def make_block(self, num: int, in_channels: int, out_channels: int, padding=1):
        """根据传入的in,out和需要构建的块数搭建网络块"""
        blocks = []
        blocks.append(nn.Conv2D(in_channels=in_channels, out_channels=out_channels, kernel_size=3, padding=padding))
        blocks.append(nn.ReLU())
        for i in range(num-1):
            blocks.append(nn.Conv2D(in_channels=out_channels, out_channels=out_channels, kernel_size=3, padding=1))
            blocks.append(nn.ReLU())
        blocks.append(nn.MaxPool2D(kernel_size=2, stride=2, ceil_mode=True))
        
        return nn.Sequential(*blocks)
    
    def forward(self, inputs):
        # inputs [3, 1, 1],以原始输入图像尺寸为1
        # features
        out = self.layer1(inputs)  # [64, 1/2, 1/2]
        out = self.layer2(out)  # [128, 1/4, 1/4]
        pool3 = self.layer3(out)  # [256, 1/8, 1/8]
        pool4 = self.layer4(pool3)  # [512, 1/16, 1/16]
        pool5 = self.layer5(pool4)  # [512, 1/32, 1/32]
        x = self.conv6(pool5)  # [mid_channels, 1/32, 1/32]
        x = self.conv7(x)  # [mid_channels, 1/32, 1/32]
        score32 = self.score32(x)  # [num_classes, 1/32, 1/32]
        
        up_pool16 = self.up_sample32x(score32)  # [num_classes, 1/16, 1/16]
        score16 = self.score16(pool4)  # [num_classes, 1/16, 1/16]
        fuse_16 = paddle.add(up_pool16, score16)
        
        up_pool8 = self.up_sample16x(fuse_16)  # [num_classes, 1/8, 1/8]
        score8 = self.score8(pool3)  # [num_classes, 1/8, 1/8]
        fuse_8 = paddle.add(up_pool8, score8)
        heatmap = self.up_sample8x(fuse_8)
        
        return heatmap

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/449450.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

嵌入式面经-ARM体系架构-计算机基础

嵌入式系统分层 操作系统的作用:向下管理硬件,向上提供接口(API) 应用开发:使用操作系统提供的接口(API),做上层的应用程序开发,基本不用去关内核操作硬件是怎么实现的 …

数字电子技术笔记——组合逻辑功能

1.Adder(加法器) Half-Adder(半加器) Full-Adder(全加器) 74LS283(4-bit parallel adders) carry look-ahead adder (超前进位加法器) 2.Comparator(比较器)…

hadoop报错:HADOOP_HOME and hadoop.home.dir are unset. 解决方法

参考:https://blog.csdn.net/weixin_45735242/article/details/120579387 解决方法 1.下载apache-hadoop-3.1.0-winutils-master 官网下载地址: https://github.com/s911415/apache-hadoop-3.1.0-winutils win配置系统环境: 然后重启idea…

【golang】28、用 httptest 做 web server 的 controller 的单测

文章目录 一、构建 HTTP server1.1 model.go1.2 server.go1.3 curl 验证 server 功能1.3.1 新建1.3.2 查询1.3.3 更新1.3.4 删除 二、httptest 测试2.1 完整示例2.2 实现逻辑2.3 其他示例2.4 用 TestMain 避免重复的测试代码2.5 gin 框架的 httptest 一、构建 HTTP server 1.1…

[密码学]Base64编码

一、相关指令 1. 查看工具版本号 base64 --version2. 对字符串加密 echo 字符串 | base64 echo "Hello base64" | base643. 对字符串解密 echo 字符串 |base64 -d echo "SGVsbG8gTGV0aWFuLVJTQQo" | base64 -d4. 对文件加密 base64 文件名 base64 tex…

Linux Centos系统 磁盘分区和文件系统管理 (深入理解)

CSDN 成就一亿技术人! 作者主页:点击! Linux专栏:点击! CSDN 成就一亿技术人! 前言———— 磁盘 在Linux系统中,磁盘是一种用于存储数据的物理设备,可以是传统的硬盘驱动器&am…

个人商城系统开源(配置支付宝支付!)

原文地址:个人商城系统开源(配置支付宝支付!) - Pleasure的博客 下面是正文内容: 前言 由于近期实在没有什么话题可写和一些有趣的项目教程可以分享。所以我只能决定将我自己亲手编写的一个迷你迷你商城系统进行开源…

HYBBS 表白墙网站PHP程序源码,支持封装成APP

PHP表白墙网站源码,适用于校园内或校区间使用,同时支持封装成APP。告别使用QQ空间的表白墙。 简单安装,只需PHP版本5.6以上即可。 通过上传程序进行安装,并设置账号密码,登录后台后切换模板,适配手机和PC…

软考 系统架构设计师之回归及知识点回顾(6)

接前一篇文章:软考 系统架构设计师之回归及知识点回顾(5) 10. 边缘计算 边云协同 边缘计算与云计算各有所长,云计算擅长全局性、非实时、长周期的大数据处理与分析,能够在长周期维护、业务决策支撑等领域发挥优势&…

【汇编】#4 8086与转移地址有关有关的寻址方式

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一、CS与IP功能tips:CS、IP复位值 二、修改CS与IP的指令1. jmp指令 三、与转移地址有关的寻址方式1、段内转移1.1 段内直接寻址1.2 段内间接寻址 2. 段间…

RK3588-PCIe

1. 简介 PCIe(Peripheral Component Interconnect Express)是一种用于连接主板和外部设备的高速串行接口标准。它是 PCI 技术的后继者,旨在提供更高的带宽和更好的性能。 高速传输: PCIe接口提供了高速的数据传输通道&#xff0…

AHU 汇编 实验四

实验名称:实验四 两个数的相乘 实验内容: 用子程序形式编写: A*B:从键盘输入a和b,计算A*B,其中乘法采用移位和累加完成 实验过程: 源代码: data segmentmul1 db 16,?,16 dup(?…

Jenkins cron定时构建触发器

from: https://www.jenkins.io/doc/book/pipeline/syntax/#cron-syntax 以下内容为根据Jenkins官方文档cron表达式部分翻译过来,使用机翻加个人理解补充内容,包括举例。 目录 介绍举例:设置方法方法一:方法二&#xf…

web | http 的一些问题 | get/post的区别 | http版本 | http与https的区别 | session、cookie、token

怎么来说呢?这应该算一个大类了,基本上设计网络的应用层 当然重要的是从网络层----->应用层 (杠精勿杠,知道中间还有其他层) 先来讲一下http的结构 都知道http 有三部分,头部、请求头和body 头部&#x…

SQLiteC/C++接口简介

上一篇:SQLite——世界上部署最广泛的开源数据库(简介) 下一篇:SQLiteC/C接口详细介绍(一) 引言: 作为一种轻量级、嵌入式关系型数据库,SQLite已经成为许多应用和系统的首选解决方…

Discord OAuth2授权以及机器人监听群事件

下面文章讲解获取OAuth2授权整个流程,创建机器人,使用机器人监听工会(工会就是创建的服务器)成员变化等等,对接国外的都是需要VPN的哦,对接的时候记得提前准备。 创建应用 点击 此页面添加应用,&#xff…

使用kettle批量加载数据到kadb

测试环境 达梦数据库版本:DM Database Server 64 V8 03134284132-20240115-215128-20081(官网测试版)KADB版本:KADB V003R002C001B0181Kettle版本:pdi-ce-9.4.0.0-343(官网下载)Python版本&…

解释“RNN encode-decode”

“RNN encode-decode” 涉及使用循环神经网络(Recurrent Neural Network,RNN)来执行编码和解码操作。这种结构常用于处理序列数据,例如自然语言处理、语音识别和时间序列预测等任务。 以下是 “RNN encode-decode” 的一般概念&a…

Flink实操:Flink SQL实现SFTP文件读写操作

一、背景 公司需要将Doris数据库中的部分表数据同步至SFTP服务器,以供其他合作企业安全读取和使用。目前,平台数据同步功能统一使用Flink引擎进行实时同步、离线同步的工作。因此,希望能够充分利用现有的Flink引擎,并将其复用于这…