ENet——实时语义分割的深度神经网络架构与代码实现
概述
在移动设备上执行实时像素级分割任务具有重要意义。现有的基于分割的深度神经网络需要大量的浮点运算,并且通常需要较长时间才能投入使用。本文提出的ENet架构旨在减少潜在的计算负担。ENet在保持或提高分割精度的同时,相比现有的分割网络,速度提升了18倍,参数量减少了79倍。
论文地址:https://arxiv.org/abs/1606.02147
介绍
随着增强现实设备、智能家居设备和自动驾驶技术的兴起,将语义分割算法移植到性能较低的移动设备上变得尤为迫切。语义分割算法对图像中的每个像素进行分类标记。近期,大规模数据集的可用性以及强大的计算资源(如GPU和TPU)的出现,推动了卷积神经网络在超越传统计算机视觉算法方面取得了显著进展。尽管卷积网络在分类和识别任务上取得了良好的效果,但在进行像素级分割时,往往产生粗糙的空间结果。因此,通常需要将其他算法(如基于颜色的分割、条件随机场等)与之结合,以增强分割结果。
为了实现图像的空间分类和精细分割,已经出现了如SegNet、FCN等网络结构,这些结构通常基于VGG-16等大型多分类网络。然而,这些网络由于参数量大和推理时间长,不适用于要求图像处理速度超过10fps的移动设备或电池供电的应用设备。
本文提出的网络结构旨在实现快速推理和高准确率的分割。
相关工作
语义分割在图像理解和目标检测中扮演着关键角色,尤其在增强现实和自动驾驶中,其实时性要求极高。当前的计算机视觉应用普遍采用深度神经网络,其中场景分析较好的卷积网络采用编码-解码结构,受自编码器启发。SegNet中的编码-解码结构得到了改进,编码部分类似于VGG的卷积网络用于分类,解码部分主要用于上采样。但这些网络的参数量大,导致推理时间长。SegNet通过移除VGG16的全连接层来减少浮点运算和内存占用,但其轻量级网络仍无法实现实时分割。
其他结构采用简单的分类器后接CRF作为后处理步骤,但这些复杂的后处理操作常常无法准确标记图像中的小物体。CNN结合RNN可以提高准确率,但无法解决速度问题。RNN可作为后处理手段与其他技术结合使用。
网络结构
ENet网络结构参考了ResNet,描述为一个主分支和一个带有卷积核的附加分支,最后通过像素级相加进行融合。每个block包含三个卷积层:一个1x1的映射用于维度减少,一个主卷积层,一个1x1的扩张。在这些层之间穿插批量归一化(BN)层和PReLU层,定义为bottleneck模型。如果bottleneck进行下采样,则在主分支上添加最大池化层,并将第一个1x1的映射替换为2x2、步长为2的卷积,对激活值进行padding以匹配feature map尺寸。卷积核大小为3x3,类型包括普通卷积、空洞卷积和转置卷积,有时用1x5或5x1的非对称卷积替换。为进行正则化,在bottleneck2.0之前使用p=0.01,其他条件下使用p=0.1。
ENet的初始部分包含一个单独的block,第一阶段包含五个bottleneck部分。第二、三阶段结构相同,但第三阶段开始时没有下采样过程。前三个阶段为编码阶段,第四、五阶段为解码阶段。为减少内核调用和内存占用,网络未使用偏差项。在每个卷积层和pReLU层之间添加BN层。在解码网络部分,最大池化层被最大上采样层代替,padding被无偏差项的空间卷积替换。ENet在最后一个上采样过程中未使用最大池化索引,因为输入图像的通道数为3,而输出通道数为类别数。最终,使用全卷积模型作为网络的最后部分,占用部分解码网络的处理时间。
设计选择
Feature map尺寸:在语义分割中,对图像进行下采样存在两个缺点:一是分辨率减少导致空间位置信息损失,如边界信息;二是全像素级分割要求输出与输入尺寸相同,意味着下采样后必须进行同等程度的上采样,增加了模型大小和计算资源。为解决第一个问题,ENet采用SegNet的方式,保留最大池化过程中最大值的索引,以在解码网络中生成稀疏的上采样maps。考虑到内存需求,避免过度下采样,以免影响分割准确率。
下采样的优点:下采样后的图像进行卷积操作具有较大的感受野,有助于获取更多上下文信息,有利于不同类别的区分。研究发现使用空洞卷积效果更佳。
Early downsampling:为实现良好的分割效果和实时操作,需处理大尺寸输入图像,这非常消耗资源。ENet的前两个block大幅减小输入尺寸,同时只使用部分feature map。由于可视化信息具有高度空间冗余,可以压缩为更有效的表达形式。网络初始部分作为特征提取和预处理输入。
解码尺寸大小:SegNet具有高度对称的网络结构,而ENet是非对称的,包含较大的编码层和较小的解码网络。编码层类似于原始分类网络,处理较小数据并进行信息处理和滤波,解码网络对编码网络输出进行上采样,微调细节。
非线性操作:研究发现,去除网络初始层中的大部分ReLU层可提升分割效果,认为网络深度不足。随后,将所有ReLU替换为PReLUs,为每张feature map增加额外参数。
信息保留的维度变化:下采样是必要的,但剧烈维度衰减不利于信息流动。为解决这一问题,ENet在池化层后接卷积层以增加维度,进而增加计算资源。将池化和卷积操作并行执行,然后进行拼接。在ResNet结构中,下采样时第一个1x1映射使用步长为2的卷积,丢弃了约75%的输入信息。将卷积核增至2x2有助于信息保留。
分解卷积核:二维卷积可分解为两个一维卷积核(nxn -> nx1, 1xn)。ENet使用5x1, 1x5的非对称卷积,减小过拟合风险,增加感受野。卷积核分解还减少了参数量,加上非线性处理,使计算功能更丰富。
空洞卷积:ENet将bottleneck中的卷积层替换为空洞卷积并进行串联,增大感受野,提高分割的IOU。
正则化:现有分割数据集有限,网络训练易过拟合。ENet采用空间Dropout进行处理。
代码PyTorch实现
initial block
class InitialBlock(nn.Module):def __init__(self,in_channels,out_channels):super(InitialBlock, self).__init__()self.conv = nn.Conv2d(in_channels, out_channels-in_channels, kernel_size=3, stride=2,padding=1, bias=False)self.pool = nn.MaxPool2d(kernel_size=3,stride=2,padding=1)self.bn = nn.BatchNorm2d(out_channels)self.relu = nn.PReLU()def forward(self, x):return self.relu(self.bn(torch.cat([self.conv(x),self.pool(x)],dim=1)))
bottleneck module
class RegularBottleneck(nn.Module):def __init__(self,in_places,places, stride=1, expansion = 4,dilation=1,is_relu=False,asymmetric=False,p=0.01):super(RegularBottleneck, self).__init__()mid_channels = in_places // expansion self.bottleneck = nn.Sequential(Conv1x1BNReLU(in_places, mid_channels, False),AsymmetricConv(mid_channels, 1, is_relu) if asymmetric else Conv3x3BNReLU(mid_channels, mid_channels, 1,dilation, is_relu),Conv1x1BNReLU(mid_channels, places,is_relu),nn.Dropout2d(p=p))self.relu = nn.ReLU(inplace=True) if is_relu else nn.PReLU()def forward(self, x):residual = x out = self.bottleneck(x)out += residual out = self.relu(out)return outclass DownBottleneck(nn.Module):def __init__(self,in_places,places, stride=2, expansion = 4,is_relu=False,p=0.01):super(DownBottleneck, self).__init__()mid_channels = in_places // expansion self.bottleneck = nn.Sequential(Conv2x2BNReLU(in_places, mid_channels, is_relu),Conv3x3BNReLU(mid_channels, mid_channels, 1, 1, is_relu),Conv1x1BNReLU(mid_channels, places,is_relu),nn.Dropout2d(p=p))self.downsample = nn.MaxPool2d(3,stride=stride,padding=1,return_indices=True)self.relu = nn.ReLU(inplace=True) if is_relu else nn.PReLU()def forward(self, x):out = self.bottleneck(x)residual,indices = self.downsample(x)n, ch, h, w = out.size()ch_res = residual.size()[1]padding = torch.zeros(n, ch - ch_res, h, w)residual = torch.cat((residual, padding), 1)out += residual out = self.relu(out)return out, indicesclass UpBottleneck(nn.Module):def __init__(self,in_places,places, stride=2, expansion = 4,is_relu=True,p=0.01):super(UpBottleneck, self).__init__()mid_channels = in_places // expansion self.bottleneck = nn.Sequential(Conv1x1BNReLU(in_places,mid_channels,is_relu),TransposeConv3x3BNReLU(mid_channels,mid_channels,stride,is_relu),Conv1x1BNReLU(mid_channels,places,is_relu),nn.Dropout2d(p=p))self.upsample_conv = Conv1x1BN(in_places, places)self.upsample_unpool = nn.MaxUnpool2d(kernel_size=2)self.relu = nn.ReLU(inplace=True) if is_relu else nn.PReLU()def forward(self, x, indices):out = self.bottleneck(x)residual = self.upsample_conv(x)residual = self.upsample_unpool(residual,indices)out += residual out = self.relu(out)return
architecture
class ENet(nn.Module):def __init__(self, num_classes):super(ENet, self).__init__()self.initialBlock = InitialBlock(3,16)self.stage1_1 = DownBottleneck(16, 64, 2)self.stage1_2 = nn.Sequential(RegularBottleneck(64, 64, 1),RegularBottleneck(64, 64, 1),RegularBottleneck(64, 64, 1),RegularBottleneck(64, 64, 1),)self.stage2_1 = DownBottleneck(64, 128, 2)self.stage2_2 = nn.Sequential(RegularBottleneck(128, 128, 1),RegularBottleneck(128, 128, 1, dilation=2),RegularBottleneck(128, 128, 1, asymmetric=True),RegularBottleneck(128, 128, 1, dilation=4),RegularBottleneck(128, 128, 1),RegularBottleneck(128, 128, 1, dilation=8),RegularBottleneck(128, 128, 1, asymmetric=True),RegularBottleneck(128, 128, 1, dilation=16),)self.stage3 = nn.Sequential(RegularBottleneck(128, 128, 1),RegularBottleneck(128, 128, 1, dilation=2),RegularBottleneck(128, 128, 1, asymmetric=True),RegularBottleneck(128, 128, 1, dilation=4),RegularBottleneck(128, 128, 1),RegularBottleneck(128, 128, 1, dilation=8),RegularBottleneck(128, 128, 1, asymmetric=True),RegularBottleneck(128, 128, 1, dilation=16),)self.stage4_1 = UpBottleneck(128, 64, 2, is_relu=True)self.stage4_2 = nn.Sequential(RegularBottleneck(64, 64, 1, is_relu=True),RegularBottleneck(64, 64, 1, is_relu=True),)self.stage5_1 = UpBottleneck(64, 16, 2, is_relu=True)self.stage5_2 = RegularBottleneck(16, 16, 1, is_relu=True)self.final_conv = nn.ConvTranspose2d(in_channels=16, out_channels=num_classes, kernel_size=3, stride=2, padding=1,output_padding=1, bias=False)def forward(self, x):x = self.initialBlock(x)x,indices1 = self.stage1_1(x)x = self.stage1_2(x)x, indices2 = self.stage2_1(x)x = self.stage2_2(x)x = self.stage3(x)x = self.stage4_1(x, indices2)x = self.stage4_2(x)x = self.stage5_1(x, indices1)x = self.stage5_2(x)out = self.final_conv(x)return
相关文章:
ENet——实时语义分割的深度神经网络架构与代码实现
概述 在移动设备上执行实时像素级分割任务具有重要意义。现有的基于分割的深度神经网络需要大量的浮点运算,并且通常需要较长时间才能投入使用。本文提出的ENet架构旨在减少潜在的计算负担。ENet在保持或提高分割精度的同时,相比现有的分割网络…...
游戏领域AI智能视频剪辑解决方案
游戏行业作为文化创意产业的重要组成部分,其发展和创新速度令人瞩目。然而,随着游戏内容的日益丰富和直播文化的兴起,传统的视频剪辑方式已难以满足玩家和观众日益增长的需求。美摄科技,凭借其在AI智能视频剪辑领域的深厚积累和创…...
腾讯云轻量2核2G3M云服务器优惠价格61元一年,限制200GB月流量
腾讯云轻量2核2G3M云服务器优惠价格61元一年,配置为轻量2核2G、3M带宽、200GB月流量、40GB SSD盘,腾讯云优惠活动 yunfuwuqiba.com/go/txy 活动链接打开如下图: 腾讯云轻量2核2G云服务器优惠价格 腾讯云:轻量应用服务器100%CPU性能…...
leecode 331 |验证二叉树的前序序列化 | gdb 调试找bug
计算的本质是数据的计算 数据的计算需要采用格式化的存储, 规则的数据结果,可以快速的按照指定要求存储数据 这里就不得不说二叉树了,二叉树应用场景真的很多 本题讲的是,验证二叉树的前序序列化 换言之,不采用建立树的…...
服务器安全事件应急响应排查方法
针对服务器操作系统的安全事件也非常多的。攻击方式主要是弱口令攻击、远程溢出攻击及其他应用漏洞攻击等。分析安全事件,找到入侵源,修复漏洞,总结经验,避免再次出现安全事件,以下是参考网络上文章,总结的…...
数码视讯Q7盒子刷armbian或emuelec的一些坑
首先,我手头的盒子是nand存储的,如果是emmc的,会省事很多…… 以下很多结论是我的推测,不一定准确。 1,原装安卓系统不支持SD卡或U盘启动,所以只能进uboot修改启动参数 2,原装安卓系统应该是…...
2_2.Linux中的远程登录服务
# 一.Openssh的功能 # 1.sshd服务的用途# #作用:可以实现通过网络在远程主机中开启安全shell的操作 Secure SHell >ssh ##客户端 Secure SHell daemon >sshd ##服务端 2.安装包# openssh-server 3.主配置文件# /etc/ssh/sshd_conf 4.…...
Spring Boot集成JPA快速入门demo
1.JPA介绍 JPA (Java Persistence API) 是 Sun 官方提出的 Java 持久化规范。它为 Java 开发人员提供了一种对象/关联映射工具来管理 Java 应用中的关系数据。他的出现主要是为了简化现有的持久化开发工作和整合 ORM 技术,结束现在 Hibernate,TopLink&am…...
深度学习理解及学习推荐(持续更新)
主推YouTuBe和Bilibili 深度学习博主推荐: Umar Jamil - YouTubehttps://www.youtube.com/umarjamilai StatQuest with Josh Starmer - YouTubehttps://www.youtube.com/statquest RNN Illustrated Guide to Recurrent Neural Networks: Understanding the Int…...
【C语言】贪吃蛇【附源码】
欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 一、游戏说明: 一个基于C语言链表开发的贪吃蛇游戏: 1. 按方向键上下左右,可以实现蛇移动方向的改变。 2. 短时间长按方向键上下左右其中之一,可实现蛇向该方向的短时间…...
【技巧】压缩文件如何设置“自动加密”?
很多人会在压缩文件的时候,同时设置密码,以此保护私密文件。如果经常需要压缩文件并设置密码,不妨使用解压缩软件的“自动加密”功能,更省时省力。 下面介绍WinRAR解压缩软件的两种“自动加密”的方法,一起来看看吧&a…...
内网穿透时报错【Bad Request This combination of host and port requires TLS.】的原因
目录 前言:介绍一下内网穿透 1.内网直接https访问(可以正常访问) 程序配置的证书 2.内网穿透后,通过外网访问 3.原因 4.内网非https的Web应用,使用https后,也变成了https访问 5.题外话 感觉自己的web应用配置了…...
计算机网络:物理层 - 信道复用
计算机网络:物理层 - 信道复用 频分复用时分复用统计时分复用波分复用码分复用 计算机网络中,用户之间通过信道进行通信,但是信道是有限的,想要提高网络的效率,就需要提高信道的利用效率。因此计算机网络中普遍采用信道…...
【算法集训】基础算法:滑动窗口
定义一个快慢指针,用于截取数组中某一段信息。同时可以改变快慢指针的值来获取结果,这个过程比较像滑动。 1493. 删掉一个元素以后全为 1 的最长子数组 定义快慢指针快指针先走,如果到了第二个0上的时候。前面1的个数就是fast - slow - 1&a…...
QT 二维坐标系显示坐标点及点与点的连线-通过定时器自动添加随机数据点
QT 二维坐标系显示坐标点及点与点的连线-通过定时器自动添加随机数据点 功能介绍头文件C文件运行过程 功能介绍 上面的代码实现了一个简单的 Qt 应用程序,其功能包括: 创建一个 MainWindow 类,继承自 QMainWindow,作为应用程序的…...
C语言TCP服务器模型 : select + 多线程与双循环单线程阻塞服务器的比较
观察到的实验现象: 启动三个客户端: 使用双循环阻塞服务器:只能accept后等待收发,同时只能与一个客户端建立连接,必须等已连接的客户端多次收发 明确断开后才能与下个客户端连接 使用IO多路复用select:可以同时接收所有的连接请求,并且连接状态一直是存活的,直到客户端关闭连…...
【数字IC/FPGA】手撕代码:模3检测器(判断输入序列能否被3整除)
今天我们来手撕一个常见的笔试题,使用的方法是三段式Moore状态机。 题目描述: 输入端口是串行的1bit数据,每个时钟周期进来一位新数据后,实时检查当前序列是否能整除3,若能则输出1,否则输出0。 例如&#…...
最小可行产品需要最小可行架构——可持续架构(三)
前言 最小可行产品(MVP)的概念可以帮助团队专注于尽快交付他们认为对客户最有价值的东西,以便在投入大量时间和资源之前迅速、廉价地评估产品的市场规模。MVP不仅需要考虑产品的市场可行性,还需要考虑其技术可行性,以…...
笔记: 数据结构与算法--时间复杂度二分查找数组
算法复杂度 不依赖于环境因素事前分析法 计算最坏情况的时间复杂度每一条语句的执行时间都按照t来计算 时间复杂度 大O表示法 n 数据量 ; f(n) 实际的执行条数当存在一个n0 , 使得 n > n0,并且 c * g(n) 恒> f(n) : 渐进上界(算法最坏的情况)那么f(n)的时间复杂度 …...
AI绘画教程:Midjourney使用方法与技巧从入门到精通
文章目录 一、《AI绘画教程:Midjourney使用方法与技巧从入门到精通》二、内容介绍三、作者介绍🌤️粉丝福利 一、《AI绘画教程:Midjourney使用方法与技巧从入门到精通》 一本书读懂Midjourney绘画,让创意更简单,让设计…...
Spring-事务管理
1、事务管理 1.1、回滚方式 默认回滚方式:发生运行异常时异常和error时回滚,发生受查(编译)异常时提交。不过,对于受查异常,程序员也可以手工设置其回滚方式 1.2、事务定义接口 1.2.1、事务隔离级别常量 这些常量…...
MySql实战--为什么我的MySQL会“抖”一下
时的工作中,不知道你有没有遇到过这样的场景,一条SQL语句,正常执行的时候特别快,但是有时也不知道怎么回事,它就会变得特别慢,并且这样的场景很难复现,它不只随机,而且持续时间还很短…...
【蓝桥杯第十三届省赛B】(部分详解)
九进制转十进制 #include <iostream> #include<math.h> using namespace std; int main() {cout << 2*pow(9,3)0*pow(9,2)2*pow(9,1)2*pow(9,0) << endl;return 0; }顺子日期 #include <iostream> using namespace std; int main() {// 请在此…...
[linux初阶][vim-gcc-gdb] OneCharter: vim编辑器
一.vim编辑器基础 目录 一.vim编辑器基础 ①.vim的语法 ②vim的三种模式 ③三种模式的基本切换 ④各个模式下的一些操作 二.配置vim环境 ①手动配置(不推荐) ②自动配置(推荐) vim是vi的升级版,包含了更加丰富的功能. ①.vim的语法 vim [文件名] ②vim的三种模式 命令…...
【Lazy ORM 框架学习】
Gitee 点赞关注不迷路 项目地址 快速入门 模块所属层级描述快照版本正式版本wu-database-lazy-lambdalambda针对不同数据源wu-database-lazy-orm-coreorm 核心orm核心处理wu-database-lazy-sqlsql核心处理成处理sql解析、sql执行、sql映射wu-elasticsearch-starterESESwu-hb…...
安科瑞路灯安全用电云平台解决方案【电不起火、电不伤人】
背景介绍 近年来 ,随着城市规模的不断扩大 ,路灯事业蓬勃发展。但有的地方因为观念、技术、管理等方面不完善 ,由此引发了一系列安全问题。路灯点多面广 ,一旦漏电就极容易造成严重的人身安全事故。不仅给受害者家庭带来痛苦 &am…...
MYSQL——索引概念索引结构
索引 索引是帮助数据库高效获取数据的排好序的数据结构。 有无索引时,查询的区别 主要区别在于查询速度和系统资源的消耗。 查询速度: 在没有索引的情况下,数据库需要对表中的所有记录进行扫描,以找到符合查询条件的记录&#…...
Linux(CentOS7)配置系统服务以及开机自启动
目录 前言 两种方式 /etc/systemd/system/ 进入 /etc/systemd/system/ 文件夹 创建 nginx.service 文件 重新加载 systemd 配置文件 编辑 配置开机自启 /etc/init.d/ 进入 /etc/init.d/ 文件夹 创建 mysql 文件 编写脚本内容 添加/删除系统服务 配置开机自启 …...
0 决策树基础
目录 1 绪论 2 模型 3 决策树面试总结 1 绪论 决策树算法包括ID3、C4.5以及C5.0等,这些算法容易理解,适用各种数据,在解决各种问题时都有良好表现,尤其是以树模型为核心的各种集成算法,在各个行业和领域都有广泛的…...
Linux速览(2)——环境基础开发工具篇(其一)
本章我们来介绍一些linux的常用工具 目录 一. Linux 软件包管理器 yum 1.什么是软件包? 2. 查看软件包 3. 如何安装软件 4. 如何卸载软件 5.yum补充 6. 关于 rzsz 二. Linux编辑器-vim使用 1. vim的基本概念 2. vim的基本操作 3. vim正常模式命令集 4. vim末行模式…...
如何建立一个公网可以访问的网站/2022年热点营销案例
首先下载安装git:https://git-scm.com/downloads/ 一路默认,安装完成后,打开文件夹C:\Users\Administrator\.ssh(Administrator是当前用户名),在空白处点鼠标右键选择“Git Bush Here” ,打开g…...
做做网站/企业网站优化方案案例
我们把黎曼积分推广一下.黎曼积分里要求对区间$[a,b]$进行任意的有限分割.我们看看对区间$[a,b]$进行任意的分割(有限或无限的分割)会发生什么事.更具体地叙述如下: 设$f$是闭区间$[a,b]$上的有界函数(之所以规定有界,是因为$[a,b]$上的无界函数不是黎曼…...
山东钢结构建设局网站/搜狗提交入口网址
美国研究者表示,卫星传回的新数据显示,南极半岛的气候变化带来了显著的影响。 两年前崩塌的“守护神B”冰架(巨大的浮动冰层)加快了冰河流入附近的威德尔海的速度。 研究小组对《地球物理研究快报》(Geophysical Resea…...
做国外有那些网站/推广平台app
1:贝塞尔曲线实际应用案例 QQ小红点拖拽效果平滑的折线图的制作阅读软件的翻书效果 1.1 :实现平滑的折线图效果 1.2 :实现效果步骤分解 1.3 :代码案例...
张家口做网站公司/云搜索app
小米一纸公告宣布米聊关闭,这背后的影响可能将是相当深远,或许说明小米更适合做硬件业务,缺乏互联网基因,这导致它的硬件业务做得越来越成功,而互联网业务却似乎进入瓶颈。小米业绩增长主要靠硬件业务小米在2020年Q3公…...
凡科互动平台/开封网站快速排名优化
ASP.NET Core 是一个由微软创建的,用于构建 web 应用、API、微服务 的 web 框架。 通过本文的学习就能快速的入门ASP.NET Core,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 本来这篇只是想简单介…...