新型深度神经网络架构:ENet模型

语义分割技术能够为图像中的每个像素分配一个类别标签,这对于理解图像内容和在复杂场景中找到目标对象至关重要。在自动驾驶和增强现实等应用中,实时性是一个硬性要求,因此设计能够快速运行的卷积神经网络非常关键。
尽管深度卷积神经网络(如VGG16等)在分类和识别任务上取得了巨大成功,但它们在像素级图像标注上提供的空间结果较为粗糙。通常需要将CNN与其他算法(例如基于颜色的分割或条件随机场)级联以细化结果。许多移动或电池供电的应用需要以高于每秒10帧(fps)的速率处理图像,这对算法的运行效率提出了更高的要求。然而,现有的基于深度学习的方法往往因为参数众多和推理时间长而难以满足这一需求。

为了解决这些问题,论文提出了ENet,这是一个专为低延迟操作而设计的新型深度神经网络架构。ENet在保持相似或更高准确度的同时,显著减少了计算量、参数数量,并提高了运行速度。ENet的主要目标是在资源受限的移动设备上实现高效的语义分割,同时在高端GPU上也展现出高效的性能,以满足数据中心等场景下对大规模高分辨率图像处理的需求。

不同数据集上的ENet预测(从左到右为cityscape、CamVid和SUN):
image.png

ENet(Efficient Neural Network)

模型架构

ENet网络框架是一种专为实时语义分割任务设计的深度学习模型,它采用了高效的编码器-解码器结构,包含多个阶段,每个阶段由多个瓶颈模块(bottleneck blocks)组成。

1. 初始阶段: 这个阶段使用一个单独的卷积块,包括一个3x3的卷积层,步长为2,用于快速将输入图像下采样,减少分辨率,同时增加特征图的数量。
image.png

2. 编码器:

瓶颈模块(Bottleneck Modules):ENet的编码器由多个瓶颈模块组成,每个模块包含以下子层:

  • 1x1投影卷积:用于降维,减少特征图的数量。
  • 主卷积层:可以是3x3的常规卷积、扩张卷积或5x5的不对称卷积(由5x1和1x5的卷积组成)。
  • 1x1扩展卷积:用于升维,恢复特征图的数量。
  • 批量归一化(Batch Normalization)PReLU激活函数:在所有卷积层之后使用,以加速训练并提高模型稳定性。
  • 下采样:通过最大池化层或步长为2的卷积层实现,减少特征图的空间尺寸。

3. 重复部分: 编码器中包含重复的部分,其中不包含下采样的瓶颈模块,以进一步提取特征。

4. 解码器: 解码器同样由瓶颈模块组成,但执行的是上采样操作,逐步恢复特征图的空间尺寸。

  • 上采样模块:与编码器中的下采样相对应,使用上采样卷积层逐步增加特征图的分辨率。
  • 最大池化与最大反池化(Max Unpooling):编码器中使用最大池化减少尺寸,在解码器中使用最大反池化恢复尺寸。

5. 全卷积层:
在解码器的最后,使用一个全卷积层将特征图转换成最终的语义分割图,该层的输出通道数等于类别数。

模型特点

  • 速度快:比现有模型快18倍。
  • 计算量低:需要的浮点运算次数(FLOPs)少75倍。
  • 参数少:参数数量少79倍。
  • 精度高:提供与现有模型相似或更好的精度。

模型代码

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

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

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

实验步骤

数据集:在CamVid、Cityscapes和SUN数据集上进行测试。

评估指标:使用类平均精度(class average accuracy)和交并比(intersection-over-union, IoU)作为性能评估指标。

训练过程:首先训练编码器,然后添加解码器并训练整个网络进行上采样和像素级分类。

优化算法:使用Adam优化算法,设置学习率为5e-4,L2权重衰减为2e-4,批量大小为10。

实验结果

1.性能对比:ENet在NVIDIA Jetson TX1嵌入式系统模块和NVIDIA Titan X GPU上的性能均优于现有的SegNet模型。ENet在NVIDIA TX1上的推理速度能够达到21.1fps(640x360分辨率),显示出其在实时应用中的潜力:
image.png

2.精度:在Cityscapes数据集上,ENet在类IoU、类iIoU和类别IoU上均优于SegNet。在Cityscapes数据集上,ENet在类IoU上达到了58.3%,在iIoU上达到了34.4%,优于SegNet模型。
image.png

image.png

结论

ENet模型通过其创新的设计,在保持高精度的同时显著提高了语义分割的速度,使其适用于实时应用,尤其是在计算资源受限的移动设备上。尽管主要目标是在移动设备上运行网络,但在高端gpu(如NVIDIA Titan x)上也非常高效。这可能在需要处理大量高分辨率图像的数据中心应用程序中很有用。ENet允许以更快、更有效的方式执行大规模计算,这可能会大大节省成本。

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

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

相关文章

基于DGI框架的最佳实践

基于DGI框架的核心逻辑和搜索结果中的实践案例,以下是最精简的5步实施路径推荐: 1. 明确治理目标与范围(Why & What) 聚焦核心问题:优先选择1-2个业务痛点(如数据质量低下、主数据混乱、合规风险&…

使用Prometheus监控网站是否正常打开

要使用普罗米修斯监控你的网站主页 http://gyq.com/,可以通过以下步骤实现。普罗米修斯本身并不直接支持 HTTP 状态码的监控,但可以通过 Blackbox Exporter 来完成这项任务。 方案概述 Blackbox Exporter 是一个普罗米修斯官方提供的工具,用…

基于YOLOv8与LSKNet的遥感图像旋转目标检测新框架 —LSKblock注意力机制在小目标检测中的性能优化与SOTA探索

针对遥感图像中目标尺度差异大、方向任意性强、背景复杂度高等挑战,本文提出一种基于 YOLOv8 与 LSKNet 的新型旋转目标检测框架。通过引入 LSKblock 注意力机制 ,实现对多尺度特征的有效建模与动态感受野调整,显著提升了模型对小目标与旋转目标的识别能力。 1. 引言 随着遥…

JVM——JVM 是如何处理异常的?

JVM 是如何处理异常的? 在 Java 编程语言中,异常处理是一种强大的机制,用于应对程序运行时出现的错误和意外情况。而 Java 虚拟机(JVM)作为 Java 程序运行的核心环境,在异常处理过程中扮演着至关重要的角色…

MYSQL三大日志、隔离级别(MVCC+锁机制实现)

MySQL三大日志 ​Undo Log(回滚日志) 作用 事务回滚时恢复数据到修改前的状态。 支持 ​​MVCC​​,为读操作提供历史版本数据。 存储 存放在 undo tablespace 中,通过回滚段管理。 格式 undo log 格式都有一个 roll_point…

访问计划(C++)

题目描述 Farmer John 计划建造 N(1≤N≤10^5)个农场,用 N−1 条道路连接,构成一棵树(也就是说,所有农场之间都互相可以到达,并且没有环)。每个农场有一头奶牛,品种为更…

时间同步服务

时间同步:多主机协作工作时,各个主机的时间同步很重要,时间不一致会造成很多重要应用的故障,如:加密协议,日志,集群等,利用NTP(Network Time Protocol )协议使网络中的各个计算机 时间达到同步。目前NTP协议…

Cordova开发自定义插件的方法

Cordova开发自定义插件的方法 文章目录 Cordova开发自定义插件的方法[TOC](文章目录) 一、自定义插件二、android下的自定义插件开发(一)步骤1、建立cordova工程2、建立自定义插件(1) 安装plugman(2) 用plu…

【libm】2整数接口(int_traits.rs)

一、源码 int_traits.rs文件定义了两个核心 trait MinInt 和 Int,为整数类型提供统一的抽象接口,并通过宏为所有原生整数类型(i8 ~ i128/u8 ~ u128)实现这些 trait。 use core::{cmp, fmt, ops};/// Minimal integer implementa…

WebSocket实战经验

WebSocket实战经验详解 WebSocket基础概念 #mermaid-svg-sdkZP4UrWBpk2Hco {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-sdkZP4UrWBpk2Hco .error-icon{fill:#552222;}#mermaid-svg-sdkZP4UrWBpk2Hco .error-tex…

【C/C++】MQTT

文章目录 MQTT 协议1 基本概念2 核心特性3 核心组件4 C 简易实现(基于 Paho MQTT 库)环境准备示例代码 不同mqtt对比关键差异说明 MQTT 协议 1 基本概念 MQTT(Message Queuing Telemetry Transport)是一种轻量级的发布/订阅模式…

《Java 高并发程序设计》笔记

💡 根据 遗忘曲线:如果没有记录和回顾,6天后便会忘记75%的内容 读书笔记正是帮助你记录和回顾的工具,不必拘泥于形式,其核心是:记录、翻看、思考 ::: 书名Java 高并发程序设计作者葛一鸣、郭超状态已读完简…

Fine Structure-Aware Sampling(AAAI 2024)论文笔记和启发

文章目录 本文解决的问题本文提出的方法以及启发 本文解决的问题 传统的基于Pifu的人体三维重建一般通过采样来进行学习。一般选择的采样方法是空间采样,具体是在surface的表面随机位移进行样本的生成。这里的采样是同时要在XYZ三个方向上进行。所以这导致了一个问…

【AI面试准备】性能测试与AI模型结合应用指南

面试题: 性能测试:AI模型预测系统瓶颈(如LoadRunnerAI模块)。 性能测试与AI模型预测系统瓶颈的结合是当前软件工程和运维领域的重要趋势,能够显著提升系统优化效率和问题预测能力。以下从核心概念、技术实现、快速掌握…

Spring MVC 与 FreeMarker 整合

以下是 Spring MVC 与 FreeMarker 整合的详细步骤&#xff0c;包含配置和代码示例&#xff1a; 1. 添加依赖 在 pom.xml 中引入 Spring MVC 和 FreeMarker 的依赖&#xff08;以 Maven 为例&#xff09;&#xff1a; <!-- Spring Web MVC --> <dependency><gr…

Redis分布式锁使用以及对接支付宝,paypal,strip跨境支付

本章重点在于如何使用redis的分布式锁来锁定库存。减少超卖&#xff0c;同时也对接了支付宝&#xff0c;paypal&#xff0c;strip跨境支付 第一步先建立一个商品表 CREATE TABLE sys_product (id bigint(20) NOT NULL AUTO_INCREMENT COMMENT 主键,code varchar(60) DEFAUL…

使用frpc链接内网的mysql

以下是配置 frpc 连接内网 MySQL 服务的详细步骤&#xff1a; 1. 准备工作 frps 服务器&#xff1a;已部署在公网 IP 11.117.11.245&#xff0c;假设 frps 的默认端口为 7000。 内网 MySQL 服务&#xff1a;运行在内网机器的 3306 端口。 目标&#xff1a;通过公网 IP 11.117…

2025信息安全网络安全意识培训资料汇编(24份)

最新整理&#xff1a;2025信息安全网络安全意识培训资料汇编&#xff0c;共24份资料&#xff0c;供学习参考。 互联网信息安全意识培训.pptx100个网络安全风险防范知识.pptx亚信信息安全意识培训.pptx网络安全法规及意识培训.pptx网络安全意识与案例分析.pptx绿盟-安全意识培训…

JAVA:使用 XStream 实现对象与XML转换的技术指南

1、简述 XStream 是一个简单便捷的 Java 库,用于对象与 XML 的相互转换。其主要特点是: 易于使用:无需复杂的配置即可直接使用。支持自定义:可以灵活地定制对象的序列化和反序列化规则。强大的功能:支持注解、自定义转换器等。本文将详细介绍 XStream 的基本使用方法,并…

VITA STANDARDS LIST,VITA 标准清单下载

VITA STANDARDS LIST&#xff0c;VITA 标准清单下载 DesignationTitleAbstractStatusVMEbus Handbook, 4th EditionA users guide to the VME, VME64 and VME64x bus specifications - features over 70 product photos and over 160 circuit diagrams, tables and graphs. The…