语义分割—FCN网络 学习笔记 (附代码)

论文地址:https://arxiv.org/abs/1411.4038
代码地址:https://gitcode.com/mirrors/wzmiaomiao/deep-learning-for-image-processing/overview?utm_source=csdn_github_accelerator

1.是什么?

全卷积网络(Fully Convolutional Networks,FCN)是Jonathan Long等人于2015年在Fully Convolutional Networks for Semantic Segmentation一文中提出的用于图像语义分割的一种框架,是首个端对端的针对像素级预测的全卷积网络。
与传统的卷积神经网络(CNN)只能输出一个固定大小的标量值或向量不同,FCN可以输出与输入图像相同大小的像素级别的预测结果,即对每个像素进行分类。
FCN的核心思想是将传统的全连接层替换为卷积层,从而使得网络可以接受任意尺寸的输入图像,并输出相应尺寸的预测结果。FCN的网络结构主要分为两个部分:全卷积部分和反卷积部分。其中全卷积部分为一些经典的CNN网络(如VGG,ResNet等),用于提取特征;反卷积部分则是通过上采样得到原尺寸的语义分割图像。FCN的输入可以为任意尺寸的彩色图像,输出与输入尺寸相同,通道数为n(目标类别数)+1(背景)。

2.怎么样

2.1网络结构

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

21张概率图中每个像素处是一个概率,表明当前像素属于哪一种类别

 这里为什么会产生568*568大小的图片呢,是因为原论文的源码中在第一个卷积层处将padding设置为100,这样做的目的是防止图片下采样32倍后尺寸小于7x7(因为下采样32倍后会经过7x7大小的卷积层),之后上采样32倍后会产生与原图不一样大小的图片,需要进行裁剪才能得到原图大小的输出。
 

2.2 官方模型

官方模型是采用了VGG16作为backbone,VGG16网络结果如下图所示:

其中最大池化层为2x2 步长为2,论文中提出了三个模型分别是FCN-32s、FCN-16s、FCN-8s。

2.2.1 FCN-32s

pool5的输出直接上采样32倍恢复到原图大小,将损失了原图很多细节信息的特征图直接上采样,效果较差

现在的FCN的源码中FC6的卷积层的padding为3,这样可以使输出的图片高宽不变,防止输入图片过小导致该卷积层报错,例如若没有该padding,那么输入192x192的图片FC6的输入会是6x6大小的图片,FC6就报错了。
论文源码中的转置卷积的参数是冻结的,因为作者发现冻结和不冻结的结果相差不大,为了提高效率,所以就冻结了。此时转置卷积层相当于是双线性插值。这里效果不明显的原因是上采样倍数太大了

2.2.2 FCN-16s

pool5的输出上采样2倍(采样后大小与pool4的输出相同)然后与pool4输出相加然后再直接上采样16倍恢复到原图大小 

2.2.3  FCN-8s

pool5的输出上采样2倍(采样后大小与pool4的输出相同)然后与pool4输出相加然后再上采样2倍(采样后大小与pool3的输出相同),然后与pool3输出相加然后再直接上采样8倍恢复到原图大小。

 实现FCN-8s时的参数如下

参数名称参数值
f6.stride1
f6.padding3
f7.stride1
f7.padding1
转置卷积1.padding1
转置卷积1.stride2
转置卷积2.padding1
转置卷积2.stride2
转置卷积3.padding4
转置卷积3.stride8

规律:设倍率为x,当转置卷积的2*padding -x = k.size、 s为上采样倍率x时恰好可以上采样  

转置卷积计算公式:

o'为卷积输出大小,i‘为卷积输入大小,s为卷积核stride,k为卷积核大小,p为填充

2.3 代码实现

 FCN-32s

pre_model = models.vgg16_bn(weights=True)

class FCN32(nn.Module):
    def __init__(self, num_classes = 1):
        super(FCN32, self).__init__()

        self.stage1 = pre_model.features[:7]
        self.stage2 = pre_model.features[7:14]
        self.stage3 = pre_model.features[14:24]
        self.stage4 = pre_model.features[24:34]
        self.stage5 = pre_model.features[34:]


        self.stage6 = nn.Sequential(
                    nn.Conv2d(512, 4096, kernel_size=(7,7), stride=1, padding=3),
                    nn.ReLU(inplace=True),
                    nn.Dropout())
        self.stage7 = nn.Sequential(
                    nn.Conv2d(4096, 4096, kernel_size=(1,1), stride=1),
                    nn.ReLU(inplace=True),
                    nn.Dropout())

        self.conv1 = nn.Sequential(
                    nn.Conv2d(4096, num_classes, kernel_size=(1,1), stride=1))

        self.invers_conv1 = nn.ConvTranspose2d(num_classes,num_classes,kernel_size=(64,64), stride=32, padding=16)


    def forward(self, x):
        x_size = x.size()
        out = self.stage1(x)
        out = self.stage2(out)
        out = self.stage3(out)
        out = self.stage4(out)
        out = self.stage5(out)


        out = self.stage6(out)
        out = self.stage7(out)
        out = self.conv1(out)

        out = self.invers_conv1(out)
        return out 

 FCN-16s

class FCN16(nn.Module):
    def __init__(self, num_classes = 1):
        super(FCN16, self).__init__()

        self.stage1 = pre_model.features[:7]
        self.stage2 = pre_model.features[7:14]
        self.stage3 = pre_model.features[14:24]
        self.stage4 = pre_model.features[24:34]
        self.stage5 = pre_model.features[34:]

        self.score_pool4 = nn.Conv2d(512, num_classes, kernel_size=1)

        self.stage6 = nn.Sequential(
                    nn.Conv2d(512, 4096, 7, padding=3),
                    nn.ReLU(inplace=True),
                    nn.Dropout())
        self.stage7 = nn.Sequential(
                    nn.Conv2d(4096, 4096, 1),
                    nn.ReLU(inplace=True),
                    nn.Dropout())

        self.conv1 = nn.Sequential(
                    nn.Conv2d(4096, num_classes, 1))
        self.invers_conv1 = nn.ConvTranspose2d(num_classes,num_classes,4, stride=2, padding=1)
        self.invers_conv2 = nn.ConvTranspose2d(num_classes,num_classes,kernel_size=(32,32), stride=16, padding=8)


    def forward(self, x):
        x_size = x.size()
        out = self.stage1(x)
        out = self.stage2(out)
        out = self.stage3(out)
        out_4 = self.stage4(out)
        out = self.stage5(out_4)

        out = self.stage6(out)
        out = self.stage7(out)
        mid1 = self.conv1(out)
        upscore2 = self.invers_conv1(mid1)
        score_pool4 = self.score_pool4(out_4)
        upscore16 = self.invers_conv2(score_pool4 + upscore2)
        return upscore16

FCN-8s 

class FCN8(nn.Module):
    def __init__(self, num_classes = 1):
        super(FCN8, self).__init__()

        self.stage1 = pre_model.features[:7]
        self.stage2 = pre_model.features[7:14]
        self.stage3 = pre_model.features[14:24]
        self.stage4 = pre_model.features[24:34]
        self.stage5 = pre_model.features[34:]

        self.score_pool4 = nn.Conv2d(512, num_classes, kernel_size=1)
        self.score_pool3 = nn.Conv2d(256, num_classes, kernel_size=1)

        self.stage6 = nn.Sequential(
                    nn.Conv2d(512, 4096, 7, padding=3),
                    nn.ReLU(inplace=True),
                    nn.Dropout())
        self.stage7 = nn.Sequential(
                    nn.Conv2d(4096, 4096, 1),
                    nn.ReLU(inplace=True),
                    nn.Dropout())
        self.conv1 = nn.Sequential(
                    nn.Conv2d(4096, num_classes, 1))

        self.invers_conv0 = nn.ConvTranspose2d(num_classes,num_classes,4, stride=2, padding=1)
        self.invers_conv1 = nn.ConvTranspose2d(num_classes,num_classes,4, stride=2, padding=1)
        self.invers_conv2 = nn.ConvTranspose2d(num_classes,num_classes,kernel_size=(16,16), stride=8, padding=4)


    def forward(self, x):
        x_size = x.size()
        out = self.stage1(x)
        out = self.stage2(out)
        out_3 = self.stage3(out)
        out_4 = self.stage4(out_3)
        out = self.stage5(out_4)

        out = self.stage6(out)
        out = self.stage7(out)
        mid1 = self.conv1(out)

        upscore2 = self.invers_conv0(mid1)
        score_pool4 = self.score_pool4(out_4)
        fc16 = self.invers_conv1(score_pool4 + upscore2)
        score_pool3 = self.score_pool3(out_3)
        upscore16 = self.invers_conv2(fc16+score_pool3)
        return upscore16

参考: 

FCN(全卷积神经网络)详解 

语义分割——FCN模型pytorch实现

B站霹雳吧啦

全卷积网络 FCN 详解

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

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

相关文章

解决 from . import _imaging as core ImportError: DLL load failed: 找不到指定的模块。

升级pillow版本就完事了 卸载掉之前的旧版本 conda uninstall pillow升级到新的版本就解决了 pip uninstall pillow 那个错误就解决了

项目实战-编写ssm整合配置文件

1、父工程pom.xml <properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><spring.version>…

【Android知识笔记】架构专题(三)

如何用工程手段,提高写代码的生产力?(元编程) 即如何写同样多的代码,花费更少的时间?如何自动生成代码,哪种代码可以被自动生成?哪些环节能够作为自动生成代码的切入点? 代码自动生成技术 代码自动生成,指的并不是让计算机凭自己的意愿生成代码。而是让预先实现好…

Unity 注释的方法

1、单行注释&#xff1a;使用双斜线&#xff08;//&#xff09;开始注释&#xff0c;后面跟注释内容。通常注释一个属性或者方法&#xff0c;如&#xff1a; //速度 public float Speed;//打印输出 private void DoSomething() {Debug.Log("运行了我"); } …

使用JDBC操作数据库时,插入数据中文乱码

如图&#xff1a; 解决办法&#xff1a; 修改连接数据库的路径&#xff0c;即url 如下&#xff1a; 设置编码格式为utf-8 urljdbc:mysql://localhost:3306/qfedu?useUnicodetrue&characterEncodingUTF-8再次运行&#xff0c;插入数据即可

CRM系统:让企业商机管理变得轻松愉快

传统企业的经常出现团队分工不合理、实施过程不可见、进度难以把控等情况。这样不仅会让项目实施周期变长&#xff0c;还会导致客户满意度降低&#xff0c;给企业的发展带来了不好的影响。因此&#xff0c;进行商机管理至关重要。那么&#xff0c;CRM系统如何进行企业的商机阶段…

速通MySql

一、简介 1、什么是数据库 数据仓库&#xff0c;用来存储数据。访问必须用SQL语句来访问 2、数据库的类型 1、关系型数据库&#xff1a;Oracle、DB2、Microsoft SQL Server、Microsoft Access、MySQL等 可以用SQL语句方便的在一个表以及多个表之间做非常复杂的数据查询&#…

TA-Lib学习研究笔记(八)——Momentum Indicators 上

TA-Lib学习研究笔记&#xff08;八&#xff09;——Momentum Indicators 上 Momentum Indicators 动量指标&#xff0c;是最重要的股票分析指标&#xff0c;能够通过数据量化分析价格、成交量&#xff0c;预测股票走势和强度&#xff0c;大部分指标都在股票软件中提供。 1. A…

SSM框架(四):SSM整合 案例 + 异常处理器 +拦截器

文章目录 一、整合流程图1.1 Spring整合Mybatis1.2 Spring整合SpringMVC 二、表现层数据封装2.1 问题引出2.2 统一返回结果数据格式 代码设计 三、异常处理器3.1 概述3.2 异常处理方案 四、前端五、拦截器5.1 概念5.2 入门案例5.3 拦截器参数5.4 拦截器链 一、整合流程图 1.1 S…

如何做一名合格的班主任

班主任是学生在校园内最直接的“家长”&#xff0c;担负着对学生全面管理和教育的责任。该如何才能成为一名合格的班主任呢&#xff1f; 一、具备扎实的专业知识 班主任是一名教师&#xff0c;扎实的专业知识是成为合格班主任的基本条件。在教学过程中&#xff0c;班主任要能够…

代码随想录算法训练营第三十七天 _ 贪心算法_738.单调自增的数字、968.监督二叉树

学习目标&#xff1a; 60天训练营打卡计划&#xff01; 学习内容&#xff1a; 738.单调自增的数字 听不懂的时候就到该动手了。必须要从后向前操作&#xff0c;才能把压力逐级传给最前面的这一位。入如&#xff1a;322 class Solution {// java中的String不能修改&#xf…

探索数据之美:深入学习Plotly库的强大可视化

1. 引言&#xff1a; Plotly 是一个交互性可视化库&#xff0c;可以用于创建各种漂亮的图表和仪表板。它支持多种编程语言&#xff0c;包括Python、R、JavaScript。在Python中&#xff0c;Plotly提供了Plotly Express和Graph Objects两个主要的绘图接口。 2. Plotly库简介&am…

SQL中left join、right join、inner join等的区别

一张图可以简洁明了的理解出left join、right join、join、inner join的区别&#xff1a; 1、left join 就是“左连接”&#xff0c;表1左连接表2&#xff0c;以左为主&#xff0c;表示以表1为主&#xff0c;关联上表2的数据&#xff0c;查出来的结果显示左边的所有数据&#…

visual Studio MFC 平台实现图像增强中Gray-level slicing,Bit-plane slicing,对比度拉伸三种方法

MFC 实现图像增强–分段式变换 本文使用visual Studio MFC 平台实现图像增强中的第三大类分段式变换中的三种方法&#xff0c;包括Gray-level slicing&#xff0c;Bit-plane slicing&#xff0c;对比度拉伸&#xff0e; 关于其他MFC单文档工程可参考 01-Visual Studio 使用MFC …

android https 证书过期

有的时候 我们android https 证书过期 &#xff0c;或者使用明文等方式去访问服务器 可能会碰到类似的 问题 &#xff1a; javax.net.ssl.SSLHandshakeException: Chain validation failed java.security.cert.CertPathValidatorException: Response is unreliable: its validi…

JavaScript类型判断:解密变量真实身份的神奇技巧

文章目录 1. typeof运算符2. instanceof运算符3. Object.prototype.toString4. Array.isArray5. 使用constructor属性6. 使用Symbol.toStringTag7. 使用is类型判断库8. 谨慎使用隐式类型转换结语 &#x1f389;JavaScript类型判断&#xff1a;解密变量真实身份的神奇技巧 ☆* o…

OpenTSDB(CVE-202035476)漏洞复现及利用

任务一&#xff1a; 复现环境中的命令注入漏洞。 任务二&#xff1a; 利用命令注入执行whoami&#xff0c;使用DNS外带技术获取结果 任务三&#xff1a;使用反弹shell&#xff0c;将漏洞环境中的shell反弹到宿主机或者vps服务器。 任务一&#xff1a; 1.搭建好环境 2.先去了…

Amazon CTO Werner Vogels:2024年及未来四大技术趋势预测

纵观历史&#xff0c;人类已经开发出各种工具和系统来增强自身能力。无论是印刷机还是装配线&#xff0c;这些创新拓宽了我们的能力范围&#xff0c;造就新的工作和职业&#xff0c;我们也不断适应着新生活。这种变化的速度在过去的一年里迅速加快&#xff0c;云技术、机器学习…

整体迁移SVN仓库到新的windows服务器

一、背景 公司原有的SVN服务器年代比较久远经常出现重启情况&#xff0c;需要把SVN仓库重新迁移到新的服务器上&#xff0c;在网上也搜到过拷贝Repositories文件直接在新服务器覆盖的迁移方案&#xff0c;但考虑到原有的操作系统和现有的操作系统版本不一致&#xff0c;SVN版本…

Redis缓存——Spring Cache入门学习

Spring Cache 介绍 Spring Cache 是一个框架&#xff0c;实现了基于注解的缓存功能&#xff0c;只需要简单地加一个注解&#xff0c;就能实现缓存功能。 Spring Cache 提供了一层抽象&#xff0c;底层可以切换不同的缓存实现&#xff0c;例如&#xff1a; EHCacheCaffeineR…