【论文阅读总结】用于目标检测的特征金字塔网络(FPN)

news/2024/4/29 9:58:57/文章来源:https://blog.csdn.net/m0_46926492/article/details/129118183

Feature Pyramid Networks for Object Detection

  • 1.摘要
  • 2.引言
    • 2.1 低级特征对于检测小物体很重要
    • 2.2 算法目标
  • 3. 文献综述
    • 3.1 Hand-engineered features and early neural networks
    • 3.2 Deep ConvNet object detectors
    • 3.3 Methods using multiple layers
  • 4.Feature Pyramid Networks【特征金字塔】
    • 4.1 Bottom-up pathway【自下而上路径】
    • 4.2 Top-down pathway and lateral connections【自上而下路径和横向连接】
  • 5. 应用
    • 5.1 Feature Pyramid Networks for RPN【用于RPN的特征金字塔网络】
    • 5.2 Feature Pyramid Networks for Fast R-CNN【Fast R-CNN的特征金字塔网络】
  • 6.特征金字塔的优点与结论
  • 7.论文阅读总结
  • 8. `mask rcnn`使用`FPN`相关代码实现
    • 8.1 Resnets模块构建
    • 8.2 FPN构建
    • 8.3 源码问题

本文参加新星计划人工智能(Pytorch)赛道: https://bbs.csdn.net/topics/613989052

  • 论文链接:
    • https://arxiv.org/pdf/1612.03144.pdf

1.摘要

  • 特征金字塔
    • 用于检测不同尺度对象的识别系统的基本组成部分。
    • 特征金字塔需要大量计算和内存
    • 特征金字塔计算和内存都是密集型的。
  • 特征金字塔网络(FPN)的体系结构
    • 利用深度卷积网络固有的多尺度金字塔层次来构造具有边际额外成本特征金字塔
    • 具有横向连接的自顶向下架构,用于在所有尺度上构建高级语义特征图
    • 是一种通用的特征提取器,在一些应用中显示出显著改进

2.引言

  • 基于图像金字塔构建的特征金字塔 【特征化图像金字塔】 为识别不同尺度的物体构成了标准解决方案的基础。
    • 这些金字塔比例不变,因为对象的比例变化通过在金字塔中移动其级别来抵消
    • 该特性使模型能够通过在位置和金字塔级别上扫描模型来检测大范围内的对象
      在这里插入图片描述
  • 手工提取特征很大程度上被深度卷积网络(ConvNets)提取的特征所取代的原因。
    • 能够表示更高层次的语义
    • ConvNets虽然对尺度变化也具鲁棒性,从而有助于从单个输入尺度上计算的特征中进行识别。即使有了这种稳健性但是仍然需要金字塔来获得最准确的结果
  • 图像金字塔的每个级别进行特征化的主要优点
    • 产生了多尺度特征表示,所有级别都是语义强的,包括高分辨率级别
  • 图像金字塔问题
    • 图像金字塔的每个层次特征化具有明显的局限性。推断时间显著增加,使得这种方法对于实际应用来说不切实际
    • 图像金字塔上的端到端网络在测试集内存方面是不可行
    • 因此,如果利用图像金字塔,则仅在测试时间使用图像金字塔,这会在训练/测试时间推断之间产生不一致
  • 注意图像金字塔并不是计算多尺度特征表示的唯一方法
    • 深层ConvNet逐层计算特征层次,通过下采样层,特征层次具有固有的多尺度金字塔形状
    • 网络中的这种特征层次结构产生了不同空间分辨率的特征图,引入了由不同深度引起的较大语义差距导致高分辨率特征图具有低水平的特征,这些特征损害了它们识别物体的表现能力

2.1 低级特征对于检测小物体很重要

  • 单镜头检测器(SSD)是第一次尝试使用ConvNet的金字塔特征层次结构。
  • 理想情况下,SSD样式的金字塔将重用在正向过程中计算的来自不同层的多尺度特征图,因此不会产生成本。
  • 但为了避免使用低级特征,SSD放弃了重复使用已经计算的层,而是从网络的高层开始构建金字塔,然后添加几个新层。
  • 因此,它错过了重用特征层次结构的高分辨率特征图的机会。我们证明这些对于检测小物体很重要

2.2 算法目标

  • 自然地利用ConvNet特征层次结构的金字塔形状,同时创建在所有尺度上都具有强语义的特征金字塔
  • 为了实现目标,我们依赖于通过自上而下的路径横向连接低分辨率、语义强的特征高分辨率、语义弱的特征相结合的架构。
  • 结果是一个在所有级别都具有丰富语义的特征金字塔,并是从单个输入图像尺度快速构建【单张图片构建的】。
  • 这些特征金字塔可用于替换特征化的图像金字塔,而不牺牲表现力、速度或内存
  • 使用架构的区别
    • 其他论文采用自上而下和跳过连接的类似架构目标是生成一个精细分辨率的高级特征图,在该图上进行预测。
    • 我们的方法利用该体系结构作为特征金字塔,其中在每个级别上独立地进行预测(例如,对象检测)
  • 特征金字塔很容易扩展到掩模方案,并与严重依赖图像金字塔的最先进方法相比,提高了实例分割平均召回率(AR)和速度
  • 特征金字塔结构可以用所有尺度进行端到端训练,并在训练/测试时一致使用,这将是使用图像金字塔不可行的内存 【解决内存不足问题】
  • FPN能够实现比所有现有的最先进的方法更高的精度。此外,这种改进是在不增加单尺度基线测试时间的情况下实现的。
    在这里插入图片描述

3. 文献综述

3.1 Hand-engineered features and early neural networks

  • 手工提取特征和早期神经网络
    • SIFT特征最初是在尺度空间极值处提取的,并用于特征点匹配。
    • HOG特征,以及后来的SIFT特征,都是在整个图像金字塔上密集计算的。
    • 这些HOG和SIFT金字塔已被用于图像分类、物体检测、人体姿态估计等许多工作。
    • Dollár等人通过首先计算稀疏采样(按比例)的金字塔,然后对缺失水平进行插值证明了快速金字塔计算

3.2 Deep ConvNet object detectors

  • 深度卷积物体检测
    • 随着现代深度ConvNets的发展,OverFeat和R-CNN等物体探测器在精度上有了显著提高。
    • OverFeat采用了一种类似于早期神经网络人脸检测器的策略,将ConvNet作为图像金字塔上的滑动窗口检测器
    • R-CNN采用了基于区域提案的策略,其中每个提案在使用ConvNet进行分类之前都进行了规模归一化
    • SPPnet证明了这种基于区域的检测器可以更有效地应用于在单个图像尺度上提取的特征图。
    • 最近更准确的检测方法,如Fast R-CNN和Faster R-CNN提倡使用从单个尺度计算的特征,因为它在准确性和速度之间提供了良好的权衡。然而,多尺度检测仍然表现更好,尤其是对于小物体。

3.3 Methods using multiple layers

  • 使用多层特征的方法
    • 通过在ConvNet中使用不同的层来改进检测和分割
    • FCN在多个尺度上对每个类别的部分分数求和,以计算语义分割
    • 其他几种方法(HyperNet、ParseNet和ION)在计算预测之前连接多层的特征,这相当于对转换后的特征求和。
    • SSD和MS-CNN在不组合特征或分数的情况下预测特征层次的多个层的对象
    • 最近有一些方法利用横向/跳跃连接,在分辨率和语义级别上关联低级别特征图,包括用于分割的U-Net和SharpMask,用于人脸检测的重组器网络,以及用于关键点估计的堆叠沙漏网络。
    • Ghiasi等人提出了FCN的拉普拉斯金字塔表示,以逐步细化分割。
    • 尽管这些方法采用了金字塔形状的体系结构,但它们不同于在所有级别上独立进行预测的特征化图像金字塔
    • 对于金字塔结构,仍然需要图像金字塔来识别多个尺度的对象
      在这里插入图片描述

4.Feature Pyramid Networks【特征金字塔】

  • 目标
    • 利用ConvNet的金字塔特征层次结构,该层次结构具有从低到高的语义,并构建一个贯穿始终的具有高级语义的特征金字塔。产生的特征金字塔网络是通用的
  • 重点关注模块
    • 滑动窗口提议器(区域提议网络,简称RPN
    • 基于区域的检测器(Fast R-CNN)
  • 实现方法
    • 任意大小的单尺度图像作为输入,并以全卷积的方式在多个级别上输出成比例大小的特征图
    • 该过程独立于骨干卷积架构,使用ResNets骨干卷积架构。
  • 金字塔的构建包括
    • 自下而上路径
    • 自上而下路径
    • 横向连接

4.1 Bottom-up pathway【自下而上路径】

  • 自下而上路径
    • 主干ConvNet的前馈计算,它计算由几个尺度的特征图组成的特征层次,尺度步长为2
    • 通常有许多层产生相同大小的输出映射,这些层处于同一网络阶段。
    • 对于特征金字塔,为每个阶段定义一个金字塔级别。
    • 选择每个阶段最后一层的输出作为我们的特征图参考集,将对其进行丰富以创建我们的金字塔。
    • 因为每个阶段的最深层都应该具有最强的特征
  • 具体使用方法
    • 对于ResNets,使用每个阶段的最后一个残差块输出的特征激活
    • 对于conv2、conv3、conv4和conv5输出,将这些最后残差块的输出表示为{C2、C3、C4、C5},并注意到它们相对于输入图像具有{4、8、16、32}个像素的步长。
    • 由于conv1占用大量内存,因此没有将其包含在金字塔中。
      在这里插入图片描述

4.2 Top-down pathway and lateral connections【自上而下路径和横向连接】

  • 自上而下路径和横向连接

    • 通过从更高的金字塔级别上采样空间上更粗糙但语义上更强的特征图来产生更高分辨率的特征
    • 然后,通过横向连接,利用自下而上路径的特征增强特征
    • 每个横向连接合并来自自下而上路径和自上而下路径的相同空间大小的特征图。
    • 自下而上的特征图具有较低级别的语义,但它的激活更准确地定位,因为它被下采样的次数更少
      在这里插入图片描述
  • 自上而下特征图的构建块

    • 对于较粗分辨率的特征图,将空间分辨率上采样2倍(使用最近邻上采样)。
    • 然后通过逐元素相加将上采样映射与相应的自下而上映射(其经历1×1卷积层以减小通道维度)合并。
    • 迭代此过程,直到生成最精细的分辨率映射。
    • 开始迭代时,需在C5上附加一个1×1的卷积层,即可生成最粗略的分辨率图。
    • 最后,在每个合并的图上附加一个3×3的卷积来生成最终的特征图,这是为了减少上采样的混叠效应。
    • 最后一组特征图被称为{P2,P3,P4,P5},对应于分别具有相同空间大小{C2,C3,C4,C5}
  • 因为金字塔的所有级别都使用共享分类器/回归器,所以固定了所有特征图中的特征维度(通道数,表示为d,设置d=256)。所有额外的卷积层都有256个通道输出

  • 在这些额外的层中不存在非线性,我们根据经验发现这些层的影响很小。
    在这里插入图片描述

5. 应用

  • 此方法是在深层ConvNets中构建特征金字塔的通用解决方案。
  • 在下文中,在RPN中采用了特征金字塔来生成边界框建议,在Fast R-CNN中采用了方法来进行对象检测。
  • 为了证明方法的简单性和有效性,对的原始系统进行了最小的修改,使其适应特征金字塔

5.1 Feature Pyramid Networks for RPN【用于RPN的特征金字塔网络】

  • RPN是一种滑动窗口类不可知对象检测器RPN称区域建议网络,用来提取前景与背景】。
    • 最初RPN设计中,在单尺度卷积特征图的顶部,在密集的3×3滑动窗口上评估小型子网络,执行对象/非对象二元分类和边界框回归。
    • 是通过3×3卷积层和两个用于分类和回归的2个1×1卷积来实现的,我们称之为网络头【network head】
    • 对象/非对象标准和边界框回归目标是关于一组称为锚点的参考框定义的。
    • 具有多个预定义的比例和纵横比,以覆盖不同形状的对象
  • 通过用FPN替换单比例特征图来调整RPN
    • 特征金字塔的每个级别上附加一个相同设计的头部(3×3conv和两个节点1×1个conv)。因为头部在所有金字塔级别的所有位置上密集滑动,因此没有必要在特定级别上设置多尺度

    • 为每个级别分配一个单一比例的锚点

      • 将锚点定义为在{P2、P3、P4、P5、P6}上,分别具有{32*32、64*64、128*128、256*256、512*512}像素的区域。
      • 在每个级别使用多个纵横比{1:2、1:1、2:1}的锚点。所以金字塔上总共有15个锚。
        在这里插入图片描述
    • 根据锚点的交集(IoU)比率和ground-truth bounding boxes为锚点分配训练标签。

    • 如果对于给定的ground-truth bounding boxes具有最高的IoU,或者对于任何ground-truth bounding boxesIoU超过0.7,则被分配正标签,如果IoU对于所有ground-truth bounding boxes都低于0.3,则将被分配负标签
      在这里插入图片描述

    • ground-truth框的比例并没有明确用于将其分配给金字塔的级别;

    • ground-truth框与相关联,已被分配到金字塔级别。

  • 头部【heads】参数在所有特征金字塔级别上是共享的
    • 评估了不共享参数的替代方案,并观察到了类似的准确性。
    • 共享参数的良好性能表明:特征金字塔的所有级别共享相似的语义级别
    • 这一优点类似于使用特征化图像金字塔的优点,其中公共头部分类器可以应用于以任何图像尺度计算的特征
  • 总结:通过调整,RPN可以用FPN进行训练和测试。

5.2 Feature Pyramid Networks for Fast R-CNN【Fast R-CNN的特征金字塔网络】

  • Fast R-CNN

    • 一种基于区域的对象检测器,使用感兴趣区域(RoI)来提取特征。
    • Fast R-CNN最常见的是在单尺度特征图上执行。
    • 要将其与FPN一起使用,需要将不同规模的ROI分配到金字塔级别
      在这里插入图片描述
  • 特征金字塔训练Fast R-CNN实现

    • 当基于区域的检测器在图像金字塔上运行时,需要调整它们的分配策略。
    • 通过将宽度w和高度hRoI(在网络的输入图像上)分配给我们的特征金字塔的层PkP_kPk
      • 224是规范的ImageNet预训练大小
      • k0k_0k0w×h=2242w×h=224^2w×h2242RoI应该映射到的目标层
        在这里插入图片描述
      • 类似于使用C4C_4C4作为单尺度特征图的基于ResNet的Faster R-CNN系统,将k0k_0k0设置为4
      • 意味着如果RoI的尺度变小(例如,224的1/2),则应该将其映射到更精细的分辨率级别(例如,k=3)。
    • 将预测头部(在Fast R-CNN中,头是类特定的分类器和边界框回归器)附加到所有级别的所有ROI
      • 头部都共享参数,无论在那一级别。
    • ResNet模块与特征金字塔的不同
      • ResNetconv5层(一个9层深子网络)被用作conv4特征的顶部,特征金字塔使用conv5最为顶部
      • ResNet不同的是,我们只简单地采用RoI池来提取7×7个特征,并在最终分类和边界框回归层之前附加两个隐藏的1024-d完全连接(fc)层(每个层后面跟着ReLU)。
      • 这些层是随机初始化的,因为ResNets中没有可用的预训练fc层。
      • 与标准conv5头相比,我们的2-fc MLP head头重量更轻、速度更快
  • 总结:基于这些调整,可以在特征金字塔的顶部训练和测试Fast R-CNN

6.特征金字塔的优点与结论

  • 优点
    • 特征金字塔大大提高了RPN对对象尺度变化的鲁棒性【在小物体(AR1ks)上的性能提高了12.9分】
    • 自下而上的金字塔上,不同级别之间存在很大的语义差距,尤其是对于非常深的ResNets,即自上而下路径非常重要。
    • 通过横向连接从自下而上的映射的更精细级别直接传递到自上而下映射找到更精确的特征位置
    • RPN是一种具有固定窗口大小的滑动窗口检测器,因此在金字塔级别上扫描可以提高其对尺度方差的鲁棒性
    • FPN在检测器要识别的小物体上具有良好的性能
    • 对于基于区域的对象检测器,我们的特征金字塔优于单尺度特征
    • Fast R-CNN在高分辨率特征图上使用低级别特征,删除自上而下的连接会显著降低准确性
    • 共享特征可以小幅度提高准确性,还减少了测试时间
    • 特征金字塔不依赖于图像金字塔,只使用单个输入图像比例,但在小规模对象上仍然具有出色的AP。
    • 是一个通用的特征提取器,可以取代图像金字塔来解决其他多尺度检测问题
  • 结论
    • 提出了一个干净简单的框架,用于在ConvNets中构建特征金字塔
    • 该方法比几个强大的基线和竞赛获胜者有了显著的改进。
    • 它为特征金字塔的研究和应用提供了一个实用的解决方案,而不需要计算图像金字塔
    • 研究表明:尽管深度ConvNets具有强大的代表能力及其对尺度变化的隐含鲁棒性,但使用金字塔表示来明确解决多尺度问题仍然至关重要。

7.论文阅读总结

  • 低级特征对于检测小物体很重要,所以不可以舍弃前期特征图
  • 特征金字塔每个阶段的最深层都应该具有最强的特征,提出了自下而上路径
  • 低级特征对于检测小物体很重要,需将特征图大小与通道统一,即较粗分辨率的特征图**【小的特征图】**生成最精细的分辨率映射 【大的特征图】,提出了自上而下路径和横向连接

8. mask rcnn使用FPN相关代码实现

  • tensorflow相关文章链接:Mask R-cnn 代码运行报错总结
  • pytorch相关文章链接:pytorch环境之mask-rcnn源码实现

8.1 Resnets模块构建

  • dentity_block:输入维度和输出维度相同,可以串联,用于加深网络的

    • 代码位置
      在这里插入图片描述
    def identity_block(input_tensor, kernel_size, filters, stage, block,use_bias=True, train_bn=True):"""The identity_block is the block that has no conv layer at shortcut【identity_block是在快捷方式中没有对流层的块】IdentityBlock输入维度和输出维度相同,可以串联,用于加深网络的:param input_tensor:input tensor 【输入张量】:param kernel_size: default 3, the kernel size of middle conv layer at main path 【默认值3,主路径上中间conv层的内核大小】:param filters: list of integers, the nb_filters of 3 conv layer at main path 【整数列表,主路径上3个conv层的nbfilter】:param stage: integer, current stage label, used for generating layer names 【整数,当前阶段标签,用于生成图层名称】:param block: 'a','b'..., current block label, used for generating layer names 【“a”,“b”。。。,当前块标签,用于生成图层名称】:param use_bias: Boolean. To use or not use a bias in conv layers. 【布尔值。在对流层中使用或不使用偏置。】:param train_bn: Boolean. Train or freeze Batch Norm layers 【布尔值。训练或冻结批次标准层】:return:"""nb_filter1, nb_filter2, nb_filter3 = filtersconv_name_base = 'res' + str(stage) + block + '_branch'bn_name_base = 'bn' + str(stage) + block + '_branch'x = KL.Conv2D(nb_filter1, (1, 1), name=conv_name_base + '2a',use_bias=use_bias)(input_tensor)x = BatchNorm(name=bn_name_base + '2a')(x, training=train_bn)x = KL.Activation('relu')(x)x = KL.Conv2D(nb_filter2, (kernel_size, kernel_size), padding='same',name=conv_name_base + '2b', use_bias=use_bias)(x)x = BatchNorm(name=bn_name_base + '2b')(x, training=train_bn)x = KL.Activation('relu')(x)x = KL.Conv2D(nb_filter3, (1, 1), name=conv_name_base + '2c',use_bias=use_bias)(x)x = BatchNorm(name=bn_name_base + '2c')(x, training=train_bn)x = KL.Add()([x, input_tensor])x = KL.Activation('relu', name='res' + str(stage) + block + '_out')(x)return x
    
  • conv_block:输入和输出的维度是不一样的,所以不能连续串联,它的作用是改变网络的维度;

    • 代码位置
      在这里插入图片描述
    def conv_block(input_tensor, kernel_size, filters, stage, block,strides=(2, 2), use_bias=True, train_bn=True):"""conv_block is the block that has a conv layer at shortcut 【conv块是在快捷方式中具有conv层的块】ConvBlock输入和输出的维度是不一样的,所以不能连续串联,它的作用是改变网络的维度;:param input_tensor:input tensor 【输入张量】:param kernel_size:default 3, the kernel size of middle conv layer at main path 【默认值3,主路径上中间conv层的内核大小】:param filters:list of integers, the nb_filters of 3 conv layer at main path 【整数列表,主路径上3个conv层的nbfilter】卷积核个数,channel个数:param stage:integer, current stage label, used for generating layer names 【整数,当前阶段标签,用于生成图层名称】:param block:'a','b'..., current block label, used for generating layer names 【“a”,“b”。。。,当前块标签,用于生成图层名称】:param strides:步长 strides=(2, 2):param use_bias:Boolean. To use or not use a bias in conv layers. 【布尔值。在对流层中使用或不使用偏置。】:param train_bn:Boolean. Train or freeze Batch Norm layers Note that from stage 3, the first conv layer at main path is with subsample=(2,2) And the shortcut should have subsample=(2,2) as well【布尔值。训练或冻结批次标准层 注意,从第3阶段开始,主路径上的第一个对流层具有子样本=(2,2) 快捷方式也应具有子采样=(2,2)】:return:"""nb_filter1, nb_filter2, nb_filter3 = filtersconv_name_base = 'res' + str(stage) + block + '_branch'bn_name_base = 'bn' + str(stage) + block + '_branch'x = KL.Conv2D(nb_filter1, (1, 1), strides=strides,name=conv_name_base + '2a', use_bias=use_bias)(input_tensor)x = BatchNorm(name=bn_name_base + '2a')(x, training=train_bn)x = KL.Activation('relu')(x)# 使用kernel_size大小的卷积核卷积,padding="same",特征图大小不变x = KL.Conv2D(nb_filter2, (kernel_size, kernel_size), padding='same',name=conv_name_base + '2b', use_bias=use_bias)(x)x = BatchNorm(name=bn_name_base + '2b')(x, training=train_bn)x = KL.Activation('relu')(x)# 升维,增加channel通道数x = KL.Conv2D(nb_filter3, (1, 1), name=conv_name_base +'2c', use_bias=use_bias)(x)x = BatchNorm(name=bn_name_base + '2c')(x, training=train_bn)# 恒等映射shortcut = KL.Conv2D(nb_filter3, (1, 1), strides=strides,name=conv_name_base + '1', use_bias=use_bias)(input_tensor)shortcut = BatchNorm(name=bn_name_base + '1')(shortcut, training=train_bn)x = KL.Add()([x, shortcut])x = KL.Activation('relu', name='res' + str(stage) + block + '_out')(x)return x
    
  • resnet_graph:Resnets结构

    • 代码位置
      在这里插入图片描述
    def resnet_graph(input_image, architecture, stage5=False, train_bn=True):"""Build a ResNet graph.【构建ResNet图。】:param input_image::param architecture: Can be resnet50 or resnet101 【可以是resnet50或resnet101】:param stage5: Boolean. If False, stage5 of the network is not created【布尔值。如果为False,则不创建网络的阶段5】:param train_bn:Boolean. Train or freeze Batch Norm layers 【布尔值。训练或冻结批次标准层】:return:"""assert architecture in ["resnet50", "resnet101"]# Stage 1x = KL.ZeroPadding2D((3, 3))(input_image) # 将特征图外部添加0,使边缘特征提取更加充分x = KL.Conv2D(64, (7, 7), strides=(2, 2), name='conv1', use_bias=True)(x) # 卷积,卷积核为7*7,channel=64,扫描步长为2,卷积核有偏差项,总参数为7*7+1x = BatchNorm(name='bn_conv1')(x, training=train_bn) # 批量归一化x = KL.Activation('relu')(x)  # 非线性激活函数C1 = x = KL.MaxPooling2D((3, 3), strides=(2, 2), padding="same")(x) # 最大池化# Stage 2x = conv_block(x, 3, [64, 64, 256], stage=2, block='a', strides=(1, 1), train_bn=train_bn)# 残差网络映射操作x = identity_block(x, 3, [64, 64, 256], stage=2, block='b', train_bn=train_bn)C2 = x = identity_block(x, 3, [64, 64, 256], stage=2, block='c', train_bn=train_bn)# Stage 3x = conv_block(x, 3, [128, 128, 512], stage=3, block='a', train_bn=train_bn)x = identity_block(x, 3, [128, 128, 512], stage=3, block='b', train_bn=train_bn)x = identity_block(x, 3, [128, 128, 512], stage=3, block='c', train_bn=train_bn)C3 = x = identity_block(x, 3, [128, 128, 512], stage=3, block='d', train_bn=train_bn)# Stage 4x = conv_block(x, 3, [256, 256, 1024], stage=4, block='a', train_bn=train_bn)block_count = {"resnet50": 5, "resnet101": 22}[architecture]for i in range(block_count):x = identity_block(x, 3, [256, 256, 1024], stage=4, block=chr(98 + i), train_bn=train_bn)C4 = x# Stage 5if stage5:x = conv_block(x, 3, [512, 512, 2048], stage=5, block='a', train_bn=train_bn)x = identity_block(x, 3, [512, 512, 2048], stage=5, block='b', train_bn=train_bn)C5 = x = identity_block(x, 3, [512, 512, 2048], stage=5, block='c', train_bn=train_bn)else:C5 = Nonereturn [C1, C2, C3, C4, C5]
    

8.2 FPN构建

  • 代码位置
    在这里插入图片描述
if callable(config.BACKBONE):# 特征图大小在减小,channel通道数再增加_, C2, C3, C4, C5 = config.BACKBONE(input_image, stage5=True,train_bn=config.TRAIN_BN)
else:_, C2, C3, C4, C5 = resnet_graph(input_image, config.BACKBONE,stage5=True, train_bn=config.TRAIN_BN)
# Top-down Layers 【自上而下层:特征融合,对应位置相加】
# ,通道数全部要统一为config.TOP_DOWN_PYRAMID_SIZE=256
P5 = KL.Conv2D(config.TOP_DOWN_PYRAMID_SIZE, (1, 1), name='fpn_c5p5')(C5)
# p5上采样(使用线性插值),与c4(统一通道数的c4)特征融合
P4 = KL.Add(name="fpn_p4add")([KL.UpSampling2D(size=(2, 2), name="fpn_p5upsampled")(P5),KL.Conv2D(config.TOP_DOWN_PYRAMID_SIZE, (1, 1), name='fpn_c4p4')(C4)])
# p4上采样,与c3(统一通道数的c3)特征融合
P3 = KL.Add(name="fpn_p3add")([KL.UpSampling2D(size=(2, 2), name="fpn_p4upsampled")(P4),KL.Conv2D(config.TOP_DOWN_PYRAMID_SIZE, (1, 1), name='fpn_c3p3')(C3)])
# p3上采样,与c2(统一通道数的c2)特征融合
P2 = KL.Add(name="fpn_p2add")([KL.UpSampling2D(size=(2, 2), name="fpn_p3upsampled")(P3),KL.Conv2D(config.TOP_DOWN_PYRAMID_SIZE, (1, 1), name='fpn_c2p2')(C2)])
# Attach 3x3 conv to all P layers to get the final feature maps.【将3x3 conv附加到所有P层以获得最终的要素地图。】
# 特征再次融合:通道数不变
P2 = KL.Conv2D(config.TOP_DOWN_PYRAMID_SIZE, (3, 3), padding="SAME", name="fpn_p2")(P2)
P3 = KL.Conv2D(config.TOP_DOWN_PYRAMID_SIZE, (3, 3), padding="SAME", name="fpn_p3")(P3)
P4 = KL.Conv2D(config.TOP_DOWN_PYRAMID_SIZE, (3, 3), padding="SAME", name="fpn_p4")(P4)
P5 = KL.Conv2D(config.TOP_DOWN_PYRAMID_SIZE, (3, 3), padding="SAME", name="fpn_p5")(P5)
# P6 is used for the 5th anchor scale in RPN. Generated by subsampling from P5 with stride of 2.【P6用于RPN中的第五锚定标度。通过步距为2的P5的二次采样生成。】
P6 = KL.MaxPooling2D(pool_size=(1, 1), strides=2, name="fpn_p6")(P5)  # 以p6特征图大小作为区域框的生成# Note that P6 is used in RPN, but not in the classifier heads.【注意,P6用于RPN,但不用于分类器头部。】
rpn_feature_maps = [P2, P3, P4, P5, P6]
mrcnn_feature_maps = [P2, P3, P4, P5]

8.3 源码问题

  • tensorflow版本这个源码并没有实际运行起来,tensorflow2版本改动太大,官网是1版本的,虽然报错修改,但是运行的输出有问题,并且出现了损失为nan1后期使用的pytorch框架实现的,只是使用这个代码看如何实现的,因为pytorch版本封装好了,看不到实际如何构建步骤。

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

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

相关文章

LangChain:Prompt Templates介绍及应用

❤️觉得内容不错的话,欢迎点赞收藏加关注😊😊😊,后续会继续输入更多优质内容❤️👉有问题欢迎大家加关注私戳或者评论(包括但不限于NLP算法相关,linux学习相关,读研读博…

WPF+WebView2+react/vue/angular

创建WPF项目 安装WbeView2 Nuget包 在窗体中添加命名空间 xmlns:wv2"clr-namespace:Microsoft.Web.WebView2.Wpf;assemblyMicrosoft.Web.WebView2.Wpf"使用控件 <wv2:WebView2 x:Name"webview"/>在MainWindow中初始化 public MainWindow(){Initia…

什么是语法糖?Java中有哪些语法糖?

本文从 Java 编译原理角度&#xff0c;深入字节码及 class 文件&#xff0c;抽丝剥茧&#xff0c;了解 Java 中的语法糖原理及用法&#xff0c;帮助大家在学会如何使用 Java 语法糖的同时&#xff0c;了解这些语法糖背后的原理1 语法糖语法糖&#xff08;Syntactic Sugar&#…

Linux syslog 日志服务

文章目录Syslog 概述syslog 协议标准syslog APIsyslog 日志文件日志文件介绍日志配置产生本地日志参考文章Syslog 概述 syslog 常被称为系统日志或系统记录&#xff0c;系统日志通过 syslog 进程记录系统的有关事件&#xff0c;也可以记录应用程序运作事件。通过适当配置&…

Python批量删除或移动指定图像

Python批量删除或移动指定图像前言一、批量删除指定名称的图像二、批量移动指定名称的图像前言 笔者的研究方向为计算机视觉&#xff0c;因此经常和大量图像打交道&#xff0c;有时需要批量删除一些图像&#xff0c;有时需要批量移动一些图像&#xff0c;因此编写了下述代码。下…

flink 读取文件数据写入ElasticSearch

前言 es是大数据存储的必备中间件之一,通过flink可以读取来自日志文件,kafka等外部数据源的数据,然后写入到es中,本篇将通过实例演示下完整的操作过程; 一、前置准备 1、提前搭建并开启es服务(本文使用docker搭建的es7.6的服务); 2、提前搭建并开启kibana服务(便于操…

【Java 】Java NIO 底层原理

文章目录1、 Java IO读写原理1.1 内核缓冲与进程缓冲区1.2 java IO读写的底层流程2、 四种主要的IO模型3、 同步阻塞IO&#xff08;Blocking IO&#xff09;4、 同步非阻塞NIO&#xff08;None Blocking IO&#xff09;5、 IO多路复用模型(I/O multiplexing&#xff09;6、 异步…

Cursor编程初体验,搭载GPT-4大模型,你的AI助手,自然语言编程来了

背景 这两天体验了下最新生产力工具Cursor&#xff0c;基于最新的 GPT-4 大模型&#xff0c;目前免费&#xff0c;国内可访问&#xff0c;不限次数&#xff0c;跨平台&#xff0c;你确定不来体验一把&#xff1f;官方的 Slogan &#xff1a; Build Software. Fast. Write, edi…

差速巡线机器人设计-良好(80+)的报告-2023

如何提分&#xff1f;将一篇报告提升20分以上呢&#xff1f;差速巡线机器人设计-及格&#xff08;60&#xff09;的报告-2023_zhangrelay的博客-CSDN博客姓名&#xff1a; 学号&#xff1a; 实践项目1名称&#xff1a;差速巡线机器人设计 60分&#xff1a;缺乏思考、没有对比、…

攻防世界-first

题目下载&#xff1a;下载 IDA载入 __int64 __fastcall main(int a1, char **a2, char **a3) {__useconds_t *v3; // rbpunsigned int v4; // eaxint *v5; // rcxint v6; // edxunsigned int v7; // eaxsigned __int64 v8; // rcx__int64 v9; // raxchar v10; // blchar v11;…

为知笔记私有化部署

前言 原来一直买的为知笔记vip&#xff0c;但是随着内容越来越&#xff0c;并且不好整理。同时还不能一键全部导出&#xff0c;最后决定将数据迁移到自己服务器上。为止笔记提供了docker镜像&#xff0c;这也方便了部署&#xff08;其实吧&#xff0c;从产品层面&#xff0c;可…

C++ Lambda表达式的常见用法

⭐️我叫忆_恒心&#xff0c;一名喜欢书写博客的在读研究生&#x1f468;‍&#x1f393;。 如果觉得本文能帮到您&#xff0c;麻烦点个赞&#x1f44d;呗&#xff01; 近期会不断在专栏里进行更新讲解博客~~~ 有什么问题的小伙伴 欢迎留言提问欧&#xff0c;喜欢的小伙伴给个三…

【Django 网页Web开发】05. 数据库操作,实战用户管理(保姆级图文)

目录1. 安装第三方模块2. ORM2.1 自己手动创建数据库2.2 django连接数据库2.3 建表语句写在哪里&#xff1f;2.4 建表语句写好后如何运行生效&#xff1f;3. 操作表3.1 创建数据表3.2 修改数据表4. 操作数据4.1 插入数据4.2 删除数据4.3 修改数据4.4 查询数据5. 实战&#xff1…

pytest学习和使用22-allure特性 丨总览中的Environment、Categories设置以及Flaky test使用

22-allure特性 丨总览中的Environment和Categories设置1 Environment设置1.1 设置方法1.2 创建文件2 Categories设置2.1 设置方式2.2 创建文件3 关于Flaky test3.1 Flaky test介绍3.2 产生Flaky Tests的原因3.3 Flaky安装3.4 Flaky使用3.5 小结小结1小结2如下图&#xff0c;我们…

开始学习HTML5

HTML5 简介 HTML5是HTML最新的修订版本&#xff0c;2014年10月由万维网联盟&#xff08;W3C&#xff09;完成标准制定。 HTML5的设计目的是为了在移动设备上支持多媒体。 HTML5简单易学。 什么是 HTML5? HTML5 是下一代 HTML 标准。 HTML , HTML 4.01的上一个版本诞生于 1…

如何将3张图片横向拼在一起

如何将3张图片横向拼在一起&#xff1f;遇到这个情况你可能马上就会说出很多图片处理的app&#xff0c;比如用某秀秀来操作&#xff0c;但是也有很多时候某秀秀也处理不了的。当我们的图片非常大&#xff0c;图片数量很多&#xff0c;图片的格式不是jpg那种通用的格式&#xff…

如何监控和诊断JVM堆内和堆外内存使用?

第26讲 | 如何监控和诊断JVM堆内和堆外内存使用&#xff1f; 上一讲我介绍了 JVM 内存区域的划分&#xff0c;总结了相关的一些概念&#xff0c;今天我将结合 JVM 参数、工具等方面&#xff0c;进一步分析 JVM 内存结构&#xff0c;包括外部资料相对较少的堆外部分。 今天我要…

Java栈和队列·下

Java栈和队列下2. 队列(Queue)2.1 概念2.2 实现2.3 相似方法的区别2.4 循环队列3. 双端队列 (Deque)3.1 概念4.java中的栈和队列5. 栈和队列面试题大家好&#xff0c;我是晓星航。今天为大家带来的是 Java栈和队列下 的讲解&#xff01;&#x1f600; 继上一个讲完的栈后&…

视听场景理解经典任务

文章目录1. 视听场景理解简介2. 主要任务2.1 Audio-visual Event Localization (AVE) 2.2 Audio-visual Video Parsing &#xff08;AVVP&#xff09;2.3 Audio-visual Question Answering &#xff08;AVQA&#xff09;2.4 Audio-visual Segmentation &#xff08;AVS&#xf…

STM32中systick中断的优先级

1、systick中断的优先级 systick为内核外设中断&#xff0c;与普通外设中断的优先级有些区别&#xff0c;并没有抢占优先级和子优先级的说法。 对于M3来说内核外设的中断优先级由内核SCB这个外设的寄存器&#xff1a;SHPRx&#xff08;x1.2.3&#xff09;来配置。 内核外设的中…