当前位置: 首页 > news >正文

2.Fully Convolutional Networks for Semantic Segmentation论文记录


欢迎访问个人网络日志🌹🌹知行空间🌹🌹


文章目录

    • 1.基础介绍
    • 2.分类网络转换成全卷积分割网络
    • 3.转置卷积进行上采样
    • 4.特征融合
    • 5.一个pytorch源码实现
    • 参考资料

1.基础介绍

论文:Fully Convolutional Networks for Semantic Segmentation

Fully Convolutional Networks, FCN是2014年11月UC BerkeleyJonathan Long等提交的论文中提出的。论文的主要工作是设计了用于语义分割的全卷积网络结构,能够实现端到端的训练,输出逐像素的稠密预测结果。因为使用了全卷积结构,可以不用限制输入的大小。全卷积网络借用了分类网络的预训练权重,在下采样特征提取部分可以使用分类网络模型的权重。

FCN网络中作者的主要工作有三部分:

  • 1)将分类网络转换成用于分割任务的全卷积网络
  • 2)使用转置卷积进行上采样得到分割输出,不再同以往的方法使用shift-stitch方法
  • 3)将低层的空间信息和高层的语义信息相融合,fuse what and where information

2.分类网络转换成全卷积分割网络

分类任务中,网络模型中多使用了全连接层,因此要求固定的网络输入,如alexnet/vgg/googlenet等,作者认为,全连接和卷积操作是类似的,都是加权求和,只不过全连接层应当被看成感受野是整个特征图的卷积层。将全连接层换成卷积层,可以给模型任意大小的输入,输出相应大小的分割图。

在这里插入图片描述

如上图,移除特征提取后的全连接层前的flatten操作,将全连接换成卷积层,在这里可以得到10x10的带空间位置信息的预测热力图。

通过对此添加上采样层,并对网络使用带空间信息的损失函数,可以得到用于语义分割的全连接网络模型:

在这里插入图片描述

如上图就是一个可以端到端训练的全卷积语义分割模型。

3.转置卷积进行上采样

使用分类网络进行特征提取的过程中,使用了池化层,对特征图进行了下采样,这会导致细节信息的丢失,导致得到的分割结果比较粗糙。在以往的分割算法中,对于这种情况使用的是shift-stitch方法。

假设降采样因子为s,那么output map(这里为了简单起见,仅考虑二维)的spatial size则是input的 1/s,向左或向上(向右向下情况一样平移input map,偏移量为(x,y), 其中,x,y∈{0,1,..,s−1}x,y\in\{0,1,..,s-1\}x,y{0,1,..,s1}。这样就得到 s2s^2s2个 inputs,通过网络前向传播自然得到 s2s^2s2 个outputs,将outputs 交织成与origin input 大小相同的output map,就实现了pixel级别的dense prediction。

设网络只有一层 2x2 的maxpooling 层且 stride = 2,所以下采样因子 为2, 我们需要对input image 的 pixels 平移 (x,y)个单位,即将 image 向左平移 x 个pixels , 再向上平移y个单位,整幅图像表现向左上方向平移,空出来的右下角就以0 padding 。我们当然可以采取 FCN论文中的做法,将图像向右下角平移,空出来的左上角用 0 padding ,这两种做法产生的结果是一致的,没有本质区别。(x,y) 取(0,0), (0,1),(1,0),(1,1) 后,就产生了 s2=4s^2=4s2=4个input,不妨记为: shifted input (0,0)、shifted input (0,1),shifted input (1,0),shifted input (1,1)(图中的数字表示像素值,不是索引值 )。

在这里插入图片描述

4个input分别进行 2x2 的maxpooling操作后,共产生了4个output,
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OVbCsXXV-1678278382307)(/images/Segmentation/2FCN/3.jpeg)]

最后,stitch the 4 different output获得dense prediction,
在这里插入图片描述

以上就是shift-and-stitch的过程,引用自1

以上可以看到,对于一个图像需要输入预测s2s^2s2次,比较耗时。

FCN中作者使用转置卷积作为上采样层,通过可学习的参数对特征图进行插值上采样,能够得到更好的结果。

在这里插入图片描述

关于转置卷积的详细介绍可以参考3.转置卷积

4.特征融合

作者在论文中还提到的是combine what and where,具体是指在分类网络的特征提取下采样过程中,随着网络变深,卷积感受野变大,因此,高层卷积的特征图中包含更多的语义信息(更有全局视野,空间信息丰富,know where),而低层卷积的特征图包含更多的细节信息(know what),为了改善语义分割的结果,自然的想法就是将低层和高层特征图信息相融合。

在这里插入图片描述

在这里FCN-32s直接将pooling5层的输出进行32倍上采样得到的分割结果,FCN-16s是将pooling4的结果和pool5的结果2x上采样后element-wise求和得到的,同样的方式可以得到FCN-8s。作者在实验部分也指出了,融合what and where特征后输出的分割结果更好,如下图所示。

在这里插入图片描述

在这里特征融合使用的方式是size相同的特征图,元素间相加求和,如此将低层卷积的结果传递给高层特征图,这种方式和ResNet的恒等映射思想有些相似,不过ResNet是2015年12月提交的论文。除了element-wise求和外,还有不少论文使用的是concatenation on channel,像2015年05月份的U-Net,2021年04月份的STDCNet等。

5.一个pytorch源码实现

参考自3

class FCN16s(nn.Module):def __init__(self, pretrained_net, n_class):super().__init__()self.n_class = n_classself.pretrained_net = pretrained_netself.relu    = nn.ReLU(inplace=True)self.deconv1 = nn.ConvTranspose2d(512, 512, kernel_size=3, stride=2, padding=1, dilation=1, output_padding=1)self.bn1     = nn.BatchNorm2d(512)self.deconv2 = nn.ConvTranspose2d(512, 256, kernel_size=3, stride=2, padding=1, dilation=1, output_padding=1)self.bn2     = nn.BatchNorm2d(256)self.deconv3 = nn.ConvTranspose2d(256, 128, kernel_size=3, stride=2, padding=1, dilation=1, output_padding=1)self.bn3     = nn.BatchNorm2d(128)self.deconv4 = nn.ConvTranspose2d(128, 64, kernel_size=3, stride=2, padding=1, dilation=1, output_padding=1)self.bn4     = nn.BatchNorm2d(64)self.deconv5 = nn.ConvTranspose2d(64, 32, kernel_size=3, stride=2, padding=1, dilation=1, output_padding=1)self.bn5     = nn.BatchNorm2d(32)self.classifier = nn.Conv2d(32, n_class, kernel_size=1)def forward(self, x):output = self.pretrained_net(x)x5 = output['x5']  x4 = output['x4']  score = self.relu(self.deconv1(x5))               score = self.bn1(score + x4)                      score = self.bn2(self.relu(self.deconv2(score)))  score = self.bn3(self.relu(self.deconv3(score)))  score = self.bn4(self.relu(self.deconv4(score)))  score = self.bn5(self.relu(self.deconv5(score)))  score = self.classifier(score)                   return score  

欢迎访问个人网络日志🌹🌹知行空间🌹🌹


参考资料

  • 1.https://zhuanlan.zhihu.com/p/56035377
  • 2.https://medium.com/image-processing-and-ml-note/fcn-fully-convolutional-network-semantic-segmentation-b81fdcc3c845
  • 3.https://github.com/bat67/pytorch-FCN-easiest-demo/blob/master/FCN.py
http://www.lryc.cn/news/35039.html

相关文章:

  • 深度解析Spring Boot自动装配原理
  • Redis性能分析相关-channel=[id: 0xbee27bd4, L:/127.0.0.1:63156
  • Linux:环境变量
  • Codeforces Round 703 (Div. 2)(A~D)
  • Django项目5——基于tensorflow serving部署深度模型——windows版本
  • MySQL基础篇3
  • 携程 x TiDB丨应对全球业务海量数据增长,一栈式 HTAP 实现架构革新
  • 记一次Kafka warning排查过程
  • MySQL学习笔记(6.视图)
  • java多线程与线程池-01多线程知识复习
  • Typescript - 将命名空间A导入另一个命名空间B作为B的子命名空间,并全局暴露命名空间B
  • Windows下实现Linux内核的Python开发(WSL2+Conda+Pycharm)
  • 新闻发布网站分析及适用场景
  • 云原生时代顶流消息中间件Apache Pulsar部署实操之Pulsar IO与Pulsar SQL
  • Input子系统(一)启动篇
  • WuThreat身份安全云-TVD每日漏洞情报-2023-03-08
  • ABP IStringLocalizer部分场景不生效的问题
  • 数组(四)-- LC[167] 两数之和-有序数组
  • Mac电脑,python+appium+安卓模拟器使用步骤
  • Linux命令·find进阶
  • R语言ggplot2 | 用百分比格式表示数值
  • 【代码训练营】day53 | 1143.最长公共子序列 1035.不相交的线 53. 最大子序和
  • 消息队列理解
  • 【Linux内核一】在Linux系统下网口数据收发包的具体流向是什么?
  • 南京、西安集成电路企业和高校分布一览(附产业链主要厂商及高校名录)
  • 后端Java随机比大小游戏实战讲解
  • dolphinschedule使用shell任务结束状态研究
  • 如何用postman实现接口自动化测试
  • AHRS(航姿参考系统)IMU(惯性测量单元)和INS的分析对比研究-2023-3-8
  • 企业管理经典书籍推荐