resnet50、FPN、Panet结构及代码

article/2025/9/19 16:55:58

     起初faster-r-cnn,只采用最后一层特作为rpn以及head部分的特征图 ,后来不断改进,有了FPN, 再后来有了Panet,一般来说网络的层数越深它的语义信息越丰富。但是随着网络层数的加深,检测所需的位置信息就会越差,CNN分类网络只需要知道一张图像的种类即可所以很多时候网络越深效果越好,但是不是分类效果越好的网越适合检测。FPN如下图所示,它用了不同大小的特征图进行预测,图中:下方的特征图较大,对应的感受野较小可以用来检测小目标,上部分的特征图尺寸较小,但是感受野较大适合检测大目标。

                                                              

        Panet 是对FPN的改进,如下图红线所示,在fpn中顶层底层信息距离太远,不要看红线中间只有三四个框,这是一个示意,其中 有好多的卷积操作所以顶层底层距离很远,所以在右侧 开辟了一条新的路(绿线),只要几个个卷积层,顶层信息就能快速与底层信息汇合。特征提取对结果的影响特别大,融合不同尺度的信息十分必要,M2det在SSD的基础上增加了部分网络来优化特征提取,得到的效果就比SSD效果好得多    

   
   

代码是基于resnet50的特征提取部分实现的,上一张resnet50的网络结构

 

        具体实现如下,其中fpn参考mmdetection种fpn的结构,Panet部分自己写的,如有不对请告知。

        其中图像经过下采样再进行上采样的时候有可能大小不同,某一层图像下采样前的尺寸为单数。可以提前计算图像大小对输入图像直接padding,我用的是上采样时直接输入尺寸。

import torch
from torch import nn
import torch.nn.functional as Fclass Bottleneck(nn.Module):expansion = 4def __init__(self, in_size, size_u, stride=1, is_down=False):super(Bottleneck, self).__init__()self.conv1 = nn.Conv2d(in_size, size_u, kernel_size=1, stride=stride, bias=False)self.bn1 = nn.BatchNorm2d(size_u)self.conv2 = nn.Conv2d(size_u, size_u, kernel_size=3, padding=1, bias=False)self.bn2 = nn.BatchNorm2d(size_u)self.conv3 = nn.Conv2d(size_u, size_u * self.expansion, kernel_size=1, bias=False)self.bn3 = nn.BatchNorm2d(size_u * self.expansion)self.relu = nn.ReLU(inplace=True)self.downsample = nn.Sequential(nn.Conv2d(in_size, size_u * self.expansion, kernel_size=1, stride=stride, bias=False),nn.BatchNorm2d(size_u * self.expansion))self.stride = strideself.is_down = is_downdef forward(self, x):identity = xout = self.conv1(x)out = self.bn1(out)out = self.relu(out)out = self.conv2(out)out = self.bn2(out)out = self.relu(out)out = self.conv3(out)out = self.bn3(out)if self.is_down:identity = self.downsample(x)out += identityout = self.relu(out)return outclass Resnt50(nn.Module):def __init__(self):super(Resnt50, self).__init__()self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3, bias=False)self.bn1 = nn.BatchNorm2d(64)self.relu = nn.ReLU(inplace=True)self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)self.lysize = [64, 128, 256, 512, 1024, 2048]self.layer1 = nn.Sequential(Bottleneck(self.lysize[0], self.lysize[0], 1, True),Bottleneck(self.lysize[2], self.lysize[0], 1, False),Bottleneck(self.lysize[2], self.lysize[0], 1, False))self.layer2 = nn.Sequential(Bottleneck(self.lysize[2], self.lysize[1], 2, True),Bottleneck(self.lysize[3], self.lysize[1], 1, False),Bottleneck(self.lysize[3], self.lysize[1], 1, False),Bottleneck(self.lysize[3], self.lysize[1], 1, False))self.layer3 = nn.Sequential(Bottleneck(self.lysize[3], self.lysize[2], 2, True),Bottleneck(self.lysize[4], self.lysize[2], 1, False),Bottleneck(self.lysize[4], self.lysize[2], 1, False),Bottleneck(self.lysize[4], self.lysize[2], 1, False),Bottleneck(self.lysize[4], self.lysize[2], 1, False),Bottleneck(self.lysize[4], self.lysize[2], 1, False))self.layer4 = nn.Sequential(Bottleneck(self.lysize[4], self.lysize[3], 2, True),Bottleneck(self.lysize[5], self.lysize[3], 1, False),Bottleneck(self.lysize[5], self.lysize[3], 1, False))# self.avgpool = nn.AdaptiveAvgPool2d((1, 1))# self.fc = nn.Linear(self.lysize[5], 3)for m in self.modules():if isinstance(m, nn.Conv2d):nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')elif isinstance(m, nn.BatchNorm2d):nn.init.constant_(m.weight, 1)nn.init.constant_(m.bias, 0)def forward(self, x):conv1 = self.conv1(x)bn1 = self.bn1(conv1)relu = self.relu(bn1)maxpool = self.maxpool(relu)layer1 = self.layer1(maxpool)layer2 = self.layer2(layer1)layer3 = self.layer3(layer2)layer4 = self.layer4(layer3)# x = self.avgpool(layer4)# x = x.view(x.shape[0], -1)# x = self.fc(x)return layer1, layer2, layer3, layer4class FPN(nn.Module):def __init__(self):super(FPN, self).__init__()self.resnet_feature = Resnt50()self.conv1 = nn.Conv2d(in_channels=2048, out_channels=256, kernel_size=1, stride=1, padding=0)self.conv2 = nn.Conv2d(1024, 256, 1, 1, 0)self.conv3 = nn.Conv2d(512, 256, 1, 1, 0)self.conv4 = nn.Conv2d(256, 256, 1, 1, 0)self.fpn_convs = nn.Conv2d(256, 256, 3, 1, 1)def forward(self, x):layer1, layer2, layer3, layer4 = self.resnet_feature(x)  # channel 256 512 1024 2048P5 = self.conv1(layer4)P4_ = self.conv2(layer3)P3_ = self.conv3(layer2)P2_ = self.conv4(layer1)size4 = P4_.shape[2:]size3 = P3_.shape[2:]size2 = P2_.shape[2:]P4 = P4_ + F.interpolate(P5, size=size4, mode='nearest')P3 = P3_ + F.interpolate(P4, size=size3, mode='nearest')P2 = P2_ + F.interpolate(P3, size=size2, mode='nearest')P5 = self.fpn_convs(P5)P4 = self.fpn_convs(P4)P3 = self.fpn_convs(P3)P2 = self.fpn_convs(P2)return P2, P3, P4, P5class Panet(nn.Module):def __init__(self, class_number=512):super(Panet, self).__init__()self.fpn = FPN()self.convN = nn.Conv2d(256, 256, 3, 2, 1)self.relu = nn.ReLU(inplace=True)def forward(self, x):P2, P3, P4, P5 = self.fpn(x)N2 = P2N2_ = self.convN(N2)N2_ = self.relu(N2_)N3 = N2_ + P3N3_ = self.convN(N3)N3_ = self.relu(N3_)N4 = N3_ + P4N4_ = self.convN(N4)N4_ = self.relu(N4_)N5 = N4_ + P5return N2, N3, N4, N5if __name__ == '__main__':from torchsummary import summarydevice = torch.device("cuda" if torch.cuda.is_available() else "cpu")model = FPN().to(device)summary(model, (3, 512, 512))

----------------------------------------------------------------------------------end---------------------------------------------------------------------------------


http://chatgpt.dhexx.cn/article/19B2ece6.shtml

相关文章

实例分割--(PANet)Path Aggregation Network for Instance Segmentation

PANet Path Aggregation Network for Instance Segmentation 收录:CVPR2018(IEEE Conference on Computer Vision and Pattern Recognition) 相关: COCO2017/CityScapes instance segmentation 第一 论文提出了PANet,在Mask R-CNN的基础上…

PANet路径聚合

是最重要的计算机视觉过程之一,它将图像分割成更小的、多个片段,这样的话,目标的表示和进一步的分析就变得简单。这个过程有各种各样的应用,从在医学图像定位肿瘤和发展机器视觉中的生物测量识别的目标检测。图像分割过程主要分为…

PANet 实例分割

Path Aggregation Network for Instance Segmentation(PANet) 用于实例分割的路径聚合网络 代码:https://github.com/ShuLiu1993/PANet CVPR2018 Spotlight paper, coco2017实例分割第一名目标检测第二名 当前实例分割最佳模型Mask-RCNN的…

计算机视觉——day95 PANet:基于样本原型对齐的Few-Shot图像语义分割

PANet:基于样本原型对齐的Few-Shot图像语义分割 1. Introduction2. Related workFew-shot segmentation 3. Method3.1. Problem setting3.2. Method overview3.3. Prototype learning(原型学习)3.4. 非参数度量学习3.5. 原型对准正则化(PAR) 4. Experime…

PANet(2018)

关键:根据提议的ROI在每层特征图上都裁剪相应区域的特征,然后池化为指定大小,然后用max将特征融合。使用融合后的特征做预测 Abstract: 神经网络中信息的流通路径很重要。我们提出PANet,通过增加从最底层到最上层的信息传输路径&…

PANet网络简介

个人总结 简介Bottom-up Path Augmentation待解决: Adaptive Feature Pooling待解决: Fully-connected Fusion 先上论文链接: https://arxiv.org/abs/1803.01534 欢迎交流 简介 这篇论文总体上是Mask-Rcnn的改进版本,整体思路是…

PANet[详解]

一、Abstract摘要&Introduction介绍 Abstract 信息在神经网络中的传播方式非常重要。本文提出了一种基于提议的实例分割框架下的路径聚合网络Path Aggregation Network (PANet),旨在促进信息的流动。具体地说,我们通过自底向上的路径增强&#xff…

深度学习论文导航 | 07 PANet:用于实例分割的路径聚合网络

文章目录 一、PANet简介二、整体结构分析2.1 自底向上的路径增强2.2 自适应特征层2.3 全连接融合层 三、性能表现3.1 在COCO上的测试效果3.2 在Cityscapes 和 MVD上的测试效果 四、总结 前言: 同图像识别、目标检测一样,实例分割也是最重要和最具挑战性的…

(论文阅读)实例分割之PANet

PANet 一、论文简介1.1、论文和代码链接1.2、论文基本信息 二、详细解读2.1、摘要2.2、介绍2.3、网络架构2.4、改进与创新2.5、实验结果2.6、使用的数据集 三、总结与思考 一、论文简介 1.1、论文和代码链接 paper:http://xxx.itp.ac.cn/pdf/1803.01534.pdf code:https://cod…

AI大视觉(十七) | PANet(路径聚合网络)

本文来自公众号“AI大道理”。 这里既有AI,又有生活大道理,无数渺小的思考填满了一生。 ​ 目标检测或者实例分割不仅要关心语义信息,还要关注图像的精确到像素点的浅层信息。 所以需要对骨干网络中的网络层进行融合,使其同时…

深度学习-路径聚合网络(PANet网络)

文章目录 1、概括2、介绍3、特征金字塔网络(FPN)4、PANet5、改进点 1、概括 信息在神经网络中的传播方式非常重要。为了促进信息的流动,提出了一种基于提议的实例分割框架下的路径聚合网络Path Aggregation Network (PANet)。具体地说,我们通过自底向上…

Linux | Strace使用

文章目录 1、strace的基本介绍2、strace的使用实例2.1、直接运行结果2.2、strace追踪系统调用(strace ./test)2.3、strace跟踪信号传递2.4、系统调用统计使用-c参数,它会将进程的所有系统调用做一个统计分析展示出来-o选项重定向输出-T选项对系统调用进行计时系统调…

linux下strace的使用

strace是一款用于跟踪Linux系统调用和信号的工具,可以帮助开发者排除程序运行时的问题。 具体来说,strace可以跟踪一个程序执行时所涉及到的系统调用,包括读写文件、网络通信、进程管理、内存管理等操作,通过分析程序运行过程中发…

linux strace命令--跟踪系统调用

简介 strace常用来跟踪进程执行时的系统调用和所接收的信号。 在Linux世界,进程不能直接访问硬件设备,当进程需要访问硬件设备(比如读取磁盘文件,接收网络数据等等)时,必须由用户态模式切换至内核态模式,通 过系统调用…

Linux常用命令——strace命令

在线Linux命令查询工具(http://www.lzltool.com/LinuxCommand) strace 跟踪系统调用和信号 补充说明 strace命令是一个集诊断、调试、统计与一体的工具,我们可以使用strace对应用的系统调用和信号传递的跟踪结果来对应用进行分析,以达到解决问题或者…

【转】strace命令详解

Article1: strace是什么? 按照strace官网的描述, strace是一个可用于诊断、调试和教学的Linux用户空间跟踪器。我们用它来监控用户空间进程和内核的交互,比如系统调用、信号传递、进程状态变更等。 strace底层使用内核的ptrace特性来实现其…

强大的strace命令用法详解

strace是什么? 按照strace官网的描述, strace是一个可用于诊断、调试和教学的Linux用户空间跟踪器。我们用它来监控用户空间进程和内核的交互,比如系统调用、信号传递、进程状态变更等。 strace底层使用内核的ptrace特性来实现其功能。 在运维的日常工作…

Linux命令之strace命令

一、命令简介 strace是一个有用的诊断、指导和调试工具。系统管理员、诊断专家和故障解决人员将发现,对于解决源代码不易获得的程序的问题,这是非常宝贵的,因为它们不需要重新编译以跟踪它们。学生、黑客和过分好奇的人会发现,通过…

strace命令使用分析

strace命令介绍与用法 1.1 strace概述 在操作系统中,进程分为用户态进程和内核态进程,应用程序运行在用户态,内核态负责对资源包括网络,磁盘,内存等管理,用户态进程要访问这些资源时,需要通过…

【已解决】安装Ubuntu时怎样分区--利用EasyBCD在win7下进行ubuntu安装(双系统)时遇到报错:没有根文件系统,请回到分区菜单以修正此错误

由于我们离不开Windows操作,并且因为不熟悉而不习惯ubuntu的操作方式,固采用Win7和Ubuntu双系统方式比较合理。在Win7基础上安装Ubuntu,Ubuntu会自动建立一个启动菜单,让我们在开机时自行选择启动Win7还是Ubuntu。 1、在win7上安…