草庐IT

BiSeNet - 轻量级实时语义分割

张北海。 2024-01-26 原文

前言

在语义分割领域,由于需要对输入图片进行逐像素的分类,运算量很大。通常,为了减少语义分割所产生的计算量,通常而言有两种方式:减小图片大小和降低模型复杂度。

减小图片大小可以最直接地减少运算量,但是图像会丢失掉大量的细节从而影响精度。

降低模型复杂度则会导致模型的特征提取能力减弱,从而影响分割精度。

所以,如何在语义分割任务中应用轻量级模型,兼顾实时性和精度性能具有相当大的挑战性。

BiseNet

论文地址:[1808.00897] BiSeNet: Bilateral Segmentation Network for Real-time Semantic Segmentation (arxiv.org)

本文对之前的实时性语义分割算法进行了总结,发现当前主要有三种加速方法:

  1. 通过剪裁或 resize 来限定输入大小,以降低计算复杂度。尽管这种方法简单而有效,空间细节的损失还是让预测打了折扣,尤其是边界部分,导致度量和可视化的精度下降
  2. 通过减少网络通道数量加快处理速度,尤其是在骨干模型的早期阶段,但是这会弱化空间信息
  3. 追求极其紧凑的框架而丢弃模型的最后阶段(比如ENet)。该方法的缺点也很明显:由于 ENet 抛弃了最后阶段的下采样(Downsampling-缩减像素采样),模型的感受野不足以涵盖大物体,导致判别能力较差。

【下采样 —— 降低图片总像素数的方法,一般采用抽取像素的方式,有时候也用卷积来实现】

BiSeNet是一种新的双向分割网络,设计了一个带有小步长的空间路径来保留空间位置信息生成高分辨率的特征图;同时设计了一个带有快速下采样率的语义路径来获取客观的感受野。在这两个模块之上引入一个新的特征融合模块将二者的特征图进行融合,实现速度和精度的平衡。

【感受野(Receptive Field) —— 卷积神经网络每一层输出的特征图(feature map)上的像素点映射回输入图像上的区域大小。通俗点的解释是,特征图上一点,相对于原图的大小,也是卷积神经网络特征所能看到输入图像的区域,与卷积核大小有关。】

  • 空间路径Spatial Path使用较多的 Channel、较浅的网络来保留丰富的空间信息生成高分辨率特征
  • 上下文路径Context Path使用较少的 Channel、较深的网络快速 downsample来获取充足的 Context。
  • 基于这两路网络的输出,文中还设计了一个Feature Fusion Module(FFM)来融合两种特征。

结构解析:

 

 

特征叠加方式的区别(add与concate)

 损失函数

通过辅助损失函数监督模型的训练,通过主损失函数监督整个 BiSeNet 的输出。另外,还通过添加两个特殊的辅助损失函数监督 Context Path 的输出,就像多层监督一样。上述所有损失函数都是 Softmax。最后借助参数 α 以平衡主损失函数与辅助损失函数的权重。

有关BiSeNet - 轻量级实时语义分割的更多相关文章

  1. (附源码)vue3.0+.NET6实现聊天室(实时聊天SignalR) - 2

    参考文章搭建文章gitte源码在线体验可以注册两个号来测试演示图:一.整体介绍  介绍SignalR一种通讯模型Hub(中心模型,或者叫集线器模型),调用这个模型写好的方法,去发送消息。  内容有:    ①:Hub模型的方法介绍    ②:服务器端代码介绍    ③:前端vue3安装并调用后端方法    ④:聊天室样例整体流程:1、进入网站->调用连接SignalR的方法2、与好友发送消息->调用SignalR的自定义方法 前端通过,signalR内置方法.invoke()  去请求接口3、监听接受方法(渲染消息)通过new signalR.HubConnectionBuilder().on

  2. ruby-on-rails - 在 Rails 应用程序的前端获取实时日志 - 2

    在Rails3.x应用程序中,我正在使用net::ssh并向远程pc运行一些命令。我想向用户的浏览器显示实时日志。比如,如果两个命令在net中运行::ssh执行即echo"Hello",echo"Bye"被传递然后"Hello"应该在执行后立即显示在浏览器中。这是代码我在ruby​​onrails应用程序中使用ssh连接和运行命令Net::SSH.start(@servers['local'],@machine_name,:password=>@machine_pwd,:timeout=>30)do|ssh|ssh.open_channeldo|channel|channel.requ

  3. ruby - 使用 cedet 语义 wisent-ruby - 2

    我刚刚开始按照包括AlexOtt在内的各种指南设置cedet。这是我的init文件中目前的内容。(require'cedet)(semantic-load-enable-code-helpers);;imenubreaksifIdon'tenablethis(global-semantic-highlight-func-mode1)(global-semantic-tag-folding-mode)我非常喜欢代码折叠,因为语义比hideshow等包更了解代码我想对ruby​​进行相同的折叠。我知道cedet还可以做其他事情,但我现在只是试一试。所以我在contrib/文件夹中看到了wi

  4. ruby - 为什么 Gemfile 语义版本控制运算符 (~>) 会产生与一个数字不一致的结果? - 2

    gemspec语义版本控制运算符~>(又名twiddle-wakka,又名pessimistic运算符)允许限制gem版本但允许进行一些升级。我经常看到它可以读作:"~>3.1"=>"Anyversion3.x,butatleast3.1""~>3.1.1"=>"Anyversion3.1.x,butatleast3.1.1"但是有了一个数字,这条规则就失效了:"~>3"=>"Anyversionx,butatleast3"*NOTTRUE!*"~>3"=>"Anyversion3.x"*True.Butwhy?*如果我想要“任何版本3.x”,我可以只使用“~>3.0”,这是一致的。就

  5. ruby - 用逗号将字符串分割成数组,除非逗号在引号内 - 2

    给定一个Ruby数组字符串,其中一些项目在引号中包含逗号:my_string.inspect#=>"\"hey,you\",21"我怎样才能得到一个数组:["hey,you","21"] 最佳答案 Ruby标准CSV库的.parse_csv就是这样做的。require'csv'"\"hey,you\",21".parse_csv#=>["hey,you","21"] 关于ruby-用逗号将字符串分割成数组,除非逗号在引号内,我们在StackOverflow上找到一个类似的问题:

  6. ruby-on-rails - Ruby on Rails 3 - 公共(public)实时聊天 - 2

    我想使用Rails3创建一个公共(public)实时聊天应用程序。我在rails2上找到了一些例子。任何人都可以告诉你一个很好的例子/教程来使用rails3开发一个实时聊天应用程序。 最佳答案 当我试图在我的Rails3应用程序中实现一个公共(public)和私有(private)聊天系统时,我遇到了几个障碍。我查看了faye、juggernaut、node.js等。最终在尝试了几种方法之后,我能够实现一个运行良好的系统:1)我开始关注Railscast260中的faye消息传递视频指南。正如DevinM所提到的,我能够快速设置一个

  7. 接受对象或其 id 作为参数的 Ruby 语义 - 2

    我在这里尝试按照最小意外原则工作...假设您有一个接受两个对象的方法。该方法需要这些是对象实例,但在您初始化类的地方,您可能只有引用ID。例如,这在网络服务的路由器/Controller中很常见。设置可能看起来像这样:post"/:foo_id/add_bar/:bar_id"doAddFooToBar.call(...)end有许多不同的方法可以解决这个问题。对我来说,这里最“惯用的”是这样的:defAddFooToBar.call(foo:nil,foo_id:nil,bar:nil,bar_id:nil)@foo=foo||Foo[foo_id]@bar=bar||Bar[bar

  8. ruby - 由两个不同的分隔符分割的字符串 - 2

    我有这样的字符串'some-dasd\dasd-dasdas\dasdas-dasd-das\dsad'。我需要通过两个不同的符号'\'和'-'将字符串拆分为数组,所以我想得到数组['some','dasd','dasd','dasdas','dasdas','dasd','das','dsad']。最好的方法是什么? 最佳答案 "ome-dasd\dasd-dasdas\dasdas-dasd-das\dsad".split(/\\|-/)应该可以解决问题。 关于ruby-由两个不同的

  9. ruby - Ruby 如何在语义上处理赋值? - 2

    在Ruby中,我们使用=运算符为对象赋值。将此与隐式类型结合起来,我们经常会遇到这样的情况:myVar=:asymbol上面的行既创建了一个新的符号对象,又将该对象绑定(bind)到变​​量名myVar。语义上,这是如何完成的?我一直在脑海中反复强调,=运算符不是解释器中内置的神奇语法,但实际上只是对象的语法糖.=(value)方法。考虑到这一点,我最好的猜测是,当解释器看到我们试图给一个undefinedvariable名赋值时,它首先创建一个特殊类型的新对象,比如undefined或null或其他东西,然后将:=消息传递给该对象,有效负载是我们尝试分配的值。但是,在未实例化的对象上

  10. ruby - 正则表达式用逗号和空格分割字符串,但忽略带连字符的单词? - 2

    我需要一个正则表达式来用逗号和/或空格分隔字符串,但忽略带连字符的单词——最好的方法是什么?所以,例如——我想要这个……"foobar,zap-foo,baz".split(/[\s]+/)返回["foo","bar","zap-foo","baz"]但是当我这样做时,它包括像这样的逗号......["foo","bar,","zap-foo,","baz"] 最佳答案 "foobar,zap-foo,baz".split(/[\s,]+/) 关于ruby-正则表达式用逗号和空格分割字符

随机推荐