FCN-8s源码理解

news2024/9/28 23:37:38

        FCN网络用于对图像进行分割,由于是全卷积网络,所以对输入图像的分辨率没有要求。本文重点对fcn8s.py中图像降采样和上采样后图像分辨率的变换进行理解。

相关知识

       为准确理解图像分辨率的变换,对网络结构中影响图像分辨率变换的几个函数进行简单回顾

  • nn.Conv2d的参数详见这里,其输入和输出之间的关系如下,其中dilation默认为1.
     
  • nn.MaxPool2d的参数详见这里,其输入和输出之间的关系如下:
  • nn.ConvTranspose2d的参数详见这里,其输入和输出之间的关系如下,其中dilation默认为1

Hout =(Hin−1)×stride[0]−2×padding[0]+dilation[0]×(kernel_size[0]−1)+output_padding[0]+1

Wout=(Win−1)×stride[1]−2×padding[1]+dilation[1]×(kernel_size[1]−1)+output_padding[1]+1

网络模型中特征图
  • 前两次上采样均是针对中间特征图进行的,故计算过程一样,只是在特征合并时偏移量不同,这主要是因为前向传播时经历的网络层不一样。此处重点以第一次上采样为例子,介绍偏移量的由来:第一次上采样后进行合并时5个像素的偏移量是如何来的。首先该部分模型代码和网络层参数如下:
A.网络结构
        pool4 = h  # 1/16

        h = self.relu5_1(self.conv5_1(h))
        h = self.relu5_2(self.conv5_2(h))
        h = self.relu5_3(self.conv5_3(h))
        h = self.pool5(h)

        h = self.relu6(self.fc6(h))
        h = self.drop6(h)

        h = self.relu7(self.fc7(h))
        h = self.drop7(h)

        h = self.score_fr(h)
        h = self.upscore2(h)
        upscore2 = h  # 1/16

        h = self.score_pool4(pool4)
        h = h[:, :, 5:5 + upscore2.size()[2], 5:5 + upscore2.size()[3]]
B.不同网络层的参数
        # conv5
        self.conv5_1 = nn.Conv2d(512, 512, 3, padding=1)
        self.relu5_1 = nn.ReLU(inplace=True)
        self.conv5_2 = nn.Conv2d(512, 512, 3, padding=1)
        self.relu5_2 = nn.ReLU(inplace=True)
        self.conv5_3 = nn.Conv2d(512, 512, 3, padding=1)
        self.relu5_3 = nn.ReLU(inplace=True)
        self.pool5 = nn.MaxPool2d(2, stride=2, ceil_mode=True)  # 1/32

        # fc6
        self.fc6 = nn.Conv2d(512, 4096, 7)
        self.relu6 = nn.ReLU(inplace=True)
        self.drop6 = nn.Dropout2d()

        # fc7
        self.fc7 = nn.Conv2d(4096, 4096, 1)
        self.relu7 = nn.ReLU(inplace=True)
        self.drop7 = nn.Dropout2d()

        self.score_fr = nn.Conv2d(4096, n_class, 1)
        self.score_pool3 = nn.Conv2d(256, n_class, 1)
        self.score_pool4 = nn.Conv2d(512, n_class, 1)

        self.upscore2 = nn.ConvTranspose2d(
            n_class, n_class, 4, stride=2, bias=False)

结合相关知识中,模型中仅如下三行代码对特征图分辨率有影响。

        #假设特征图分辨率中宽高一致,均为I
        h = self.pool5(h)  #池化后特征图分辨率变为I/2

        h = self.relu6(self.fc6(h))  #根据fc6中卷积参数,得到卷积后特征图分辨率为(I/2+2*0-7)/1+1=I/2-6

        …………

        h = self.upscore2(h) #根据upscore2上采样的参数,得到等号左侧特征图分辨率为(I/2-6-1)*2+1*(4-1)+1=I-10

从如上变换可以看到,最后上采样后的特征图分辨率相对于pool4特征图的小了10个像素,所以在进行特征合并时,需要进行偏移10/2=5个像素,即如下代码中参数的由来。

h = h[:, :, 5:5 + upscore2.size()[2], 5:5 + upscore2.size()[3]]
  • 输出时的偏移计算方法如下。
        #由于相对于输入X经conv1_1卷积后得到的I而言,pool4之后输出的特征图分辨率变为I/16
        h = self.upscore2(h)   #(I/16/2-6-1)*2+4=I/16-10  ps:I/16之后还有pool5,故又减小一半
        upscore2 = h  # 1/16

        h = self.score_pool4(pool4)
        h = h[:, :, 5:5 + upscore2.size()[2], 5:5 + upscore2.size()[3]]
        score_pool4c = h  # 1/16

        h = upscore2 + score_pool4c  # 1/16
        h = self.upscore_pool4(h)    #(I/16-10-1)*2+4=I/8-18
        upscore_pool4 = h  # 1/8

        h = self.score_pool3(pool3)
        h = h[:, :,
              9:9 + upscore_pool4.size()[2],
              9:9 + upscore_pool4.size()[3]]
        score_pool3c = h  # 1/8

        h = upscore_pool4 + score_pool3c  # 1/8

        h = self.upscore8(h)    #(I/8-18-1)*8+16=I-136

通过上采样后输出图像的分辨率较conv1_1的减小136个像素,由于conv1_1进行了填充(padding=100)故输入x与卷积后I的关系如下。

self.conv1_1 = nn.Conv2d(3, 64, 3, padding=100) #(x+2*100)-3+1=x+198=I

由于在输入x进行了198像素的填充,然后经网络输出后像素减少136个,所以最后网络上采样得到的结果相对于输入x还是增加了(198-136)=62个像素,故而得到最终结果是。

h = h[:, :, 31:31 + x.size()[2], 31:31 + x.size()[3]].contiguous()

此时最终输出的特征图分辨率与输入x的分辨率保持一致,且网络中与浅层特征进行混合时充分考虑了实际的偏移。

参考文献:

  1. pytorch-fcn
  2. Conv2d — PyTorch 2.1 documentation
  3. MaxPool2d — PyTorch 2.1 documentation
  4. ConvTranspose2d — PyTorch 2.1 documentation

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux基础命令@echo、tail、重定向符

目录 echo概念语法作用演示一演示二 反引号作用 tail概念语法作用不带选项,演示一带选项 -num,演示二带选项 -f , 持续跟踪 重定向符概念作用覆盖重定向,>演示一演示二 追加重定向,>>演示一演示二 总结 echo …

腾讯云取消免费10G CDN流量包:免费CDN时代结束

关注卢松松,会经常给你分享一些我的经验和观点。 免费送了7-8年的腾讯云10G免费流量包,从2024年开始,停止赠送了!自此,国内绝大多数互联网大厂的CDN都开收费了! 大概从2016年开始,腾讯云为了抢夺CDN客户&#xff0…

CentOS使用docker安装mysql并使用navicat 远程链接

这篇文章没用开启mysql的挂载功能,如果想开启的话可以和我的下篇文章结合着看。 CentOS中开启mysql挂载-CSDN博客 docker在之前的文章中已经安装完成了 这里输入命令查询已被上传的MySQL镜像 docker search mysql这里stars代表点赞数,official代表官…

瓢虫目标检测数据集VOC格式400张

瓢虫,一种小巧玲珑、色彩鲜艳的昆虫,因其独特的形态和生态习性而受到广泛欢迎。 瓢虫的体型小巧,一般为圆球形,体色鲜艳,有红、黄、黑等多种颜色。它们通常有一个坚硬的外壳,可以保护自己不受天敌的侵害。…

一文讲透使用SPSS统计分析软件绘制双轴线图

双轴线图主要用来展示两个因变量和一个自变量的关系,并且两个因变量的数值单位不同时的情形。具体来说,双轴线图是指在一幅图上有一个横轴和两个纵轴,适用于三个变量。两个纵轴分别表示一个变量,横轴变量同时适用于两个纵轴上的变…

案例098:基于微信小程序的电子购物系统的设计与实现

文末获取源码 开发语言:Java 框架:SSM JDK版本:JDK1.8 数据库:mysql 5.7 开发软件:eclipse/myeclipse/idea Maven包:Maven3.5.4 小程序框架:uniapp 小程序开发软件:HBuilder X 小程序…

【LeetCode每日一题】383. 赎金信(计数模拟)

2024-1-7 文章目录 [383. 赎金信](https://leetcode.cn/problems/ransom-note/)思路:计数模拟 383. 赎金信 思路:计数模拟 1.通过数组对字母进行计数 2.magazine 中的每个字符只能在 ransomNote 中使用一次。 3.判断减一后,是否小于等于0。…

VS2019出现按F12或Ctrl+鼠标左键跳转到函数位置不准的解决

程序有时会出现大部分函数都不能准确的从头文件中正确定位到函数定位,这是因为数据库错乱造成的,可以通过重构数据库来解决,操作方法如下: 1、菜单栏:工具——选项 2、在打开选项对话框左边的树形框中选择C——高级: 3、然后在右边的浏览/导…

如何找到 niche 出海细分市场的 IDEA

先说结论就是:看榜单 Why:为什么看榜单? 大家会问为什么?原因很简单: 熟读唐诗三百首,不会作诗也会吟不天天看榜单上相关的优秀同行,你想干啥 心法就是下苦功夫坚持,量变引起质变…

微信小程序 获取地址信息(uniapp)

参考API地址&#xff1a;微信小程序JavaScript SDK | 腾讯位置服务 <script> // 引入SDK核心类&#xff0c;js文件根据自己业务&#xff0c;位置可自行放置var QQMapWX require(../../js/uploadImg/qqmap-wx-jssdk.js);export default {data(){return{qqmapsdk:}},onL…

[VUE]2-vue的基本使用

目录 vue基本使用方式 1、vue 组件 2、文本插值 3、属性绑定 4、事件绑定 5、双向绑定 6、条件渲染 7、axios 8、⭐跨域问题 &#x1f343;作者介绍&#xff1a;双非本科大三网络工程专业在读&#xff0c;阿里云专家博主&#xff0c;专注于Java领域学习&#xff0c;擅…

RabbitMQ(八)消息的序列化

目录 一、为什么需要消息序列化&#xff1f;二、常用的消息序列化方式1&#xff09;Java原生序列化&#xff08;默认&#xff09;2&#xff09;JSON格式3&#xff09;Protobuf 格式4&#xff09;Avro 格式5&#xff09;MessagePack 格式 三、总结 RabbitMQ 是一个强大的消息中间…

Java 11中的新字符串APIs详解

第1章 引言 大家好&#xff0c;我是小黑&#xff0c;咱们都知道&#xff0c;Java作为一种广泛使用的编程语言&#xff0c;每一次更新都会带来不少新鲜事物。而Java 11&#xff0c;作为长期支持&#xff08;LTS&#xff09;版本之一&#xff0c;更是引起了广大开发者的关注。好…

数据结构期末复习

章节知识点分析 第一章绪论 基本概念 数据 数据元素&#xff08;记录、表目&#xff0c;是数据集合中一个个体&#xff09; 数据项&#xff1a;一个数据元素可由若干数据项组成 数据对象&#xff1a;性质相同的数据元素的集合&#xff0c;是数据的一个子集 数据结构&…

超维空间M1无人机使用说明书——51、ROS无人机使用AR二维码识别与定位

引言&#xff1a;二维码识别与定位是指ROS通过创建AR标签并且对AR标签进行识别&#xff0c;标签可以由自己任意创建&#xff0c;具体方法会在文中给出&#xff0c;摄像头可以通过识别AR标签大小和姿态获取到标签对应的ID和位置等信息&#xff0c;实现识别与定位 注意&#xff…

深入分析-Spring BeanDefinition构造元信息

**## Spring BeanDefinition元信息定义方式 Bean Definition是一个包含Bean元数据的对象。它描述了如何创建Bean实例、Bean属性的值以及Bean之间的依赖关系。可以使用多种方式来定义 Bean Definition 元信息&#xff0c;包括&#xff1a; XML 配置文件&#xff1a;使用<be…

Qt/QML编程学习之心得:Linux下读写文件File(24)

在Linux嵌入式系统中,经常会使用Qt来读写一个文件,判断一个文件是否存在,具体如何实现呢? 首先,要使用linux系统中相关的头文件: #include <unistd.h> #include <stdio.h> #include <stdlib.h> 其次,判断路径是否存在, if(!dir.exists()){mkdir(…

C#,字符串匹配算法(模式搜索)Z算法的源代码与数据可视化

Z算法也是模式搜索&#xff08;Pattern Search Algorithm&#xff09;的常用算法。 本文代码的运算效果&#xff1a; 一、Z 算法 线性时间模式搜索算法的Z算法&#xff0c;在线性时间内查找文本中模式的所有出现。 假设文本长度为 n&#xff0c;模式长度为 m&#xff0c;那么…

SSR 服务器端渲染:提升用户体验的新趋势(上)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

关于目标检测中按照比例将数据集随机划分成训练集和测试集

1. 前言 在做目标检测任务的时候&#xff0c;不少网上的数据&#xff0c;没有划分数据集&#xff0c;只是将数据和标签放在不同的文件夹下&#xff0c;没有划分数据集 虽然代码简单&#xff0c;每次重新编写还是颇为麻烦&#xff0c;这里记录一下 如下&#xff0c;有的数据集…