EdgeNeXt: Efficiently Amalgamated CNN-Transformer Architecture for Mobile Vision Applications

本文主要是介绍EdgeNeXt: Efficiently Amalgamated CNN-Transformer Architecture for Mobile Vision Applications,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • 摘要
  • 介绍
    • CNN和Transformer的对比
    • 贡献
  • 相关工作
  • 总体架构
    • 总体架构
    • Convolution Encoder
    • SDTA Encoder
  • 代码解析
    • ConvEncoder
    • SDTA(Split Depth-wise Transpose Attention)
  • github地址

摘要

众所周知,模型的准确性很大程度上可以评判一个模型的优劣。为了提高模型的准确性,人们往往会设计复杂的神经网络来提高准确率。然而,模型越复杂,需要的计算资源就越大,这就导致了大模型无法部署在例如手机等边缘设备上。本文一方面是为了结合CNN和Transformer的优势,一方面是为了使得模型能在边缘设备上部署,提出了EdgeNext。

介绍

CNN和Transformer的对比

CNN具备局部感受野,无法对全局信息进行建模。
CNN学习到的权重在推理过程中是静态的,无法灵活的适应输入的内容。
Transformer可以缓解这个问题,但是计算的复杂度太高,对边缘设备不友好。

贡献

提出了SDTA(Split depth-wise transpose attention),可以有效的增加全局和局部表示。最主要的是不增加参数和乘法操作。

相关工作

模型介绍
MobileNet使用深度可分离卷积构建轻量型深度神经网络。(深度卷积(过滤特征)和点卷积(组合特征))
ShuffleNet使用通道混洗操作和低成本组卷积。(逐点组卷积(降低计算成本)和通道混洗(不同组之间交换信息)
MobileFormerMobileNet+Transformer的并行设计,从而实现局部特征和全局特征的融合。(mobileNet+Vision Transformer)
MobileViT使用transformer作为卷积来学习全局表示,传统卷积可以分为展开、矩阵乘法(局部表示)、折叠三部分。
ConvNeXt对ResNet进行改造,达到了Swin Transformer的效果

总体架构

总体架构

在这里插入图片描述

Convolution Encoder

类似于深度可分离卷积,使用每个阶段大小可变的深度卷积来丰富局部表示。
然后使用1*1的卷积进行特征组合,进行不同通道上特征信息的交互。
空间混合(深度卷积)和通道混合(点卷积)

卷积编码器

SDTA Encoder

split通过编码输入图像中的各种空间级别来学习自适应多尺度特征表示。
自注意力的计算在通道维度上进行,大大减少了计算的复杂度。
SDTA

代码解析

EdgeNeXt有两种实现。一种是LayerNorm和GELU的,一种为Hard-Swish和BatchNorm。主要以介绍LayerNorm和GELU的ConvEncoder和SDTA。

ConvEncoder

class ConvEncoder(nn.Module):def __init__(self, dim, drop_path=0., layer_scale_init_value=1e-6, expan_ratio=4, kernel_size=7):super().__init__()# 空间混合self.dwconv = nn.Conv2d(dim, dim, kernel_size=kernel_size, padding=kernel_size // 2, groups=dim)self.norm = LayerNorm(dim, eps=1e-6)# 通道混合self.pwconv1 = nn.Linear(dim, expan_ratio * dim)self.act = nn.GELU()self.pwconv2 = nn.Linear(expan_ratio * dim, dim)self.gamma = nn.Parameter(layer_scale_init_value * torch.ones(dim),requires_grad=True) if layer_scale_init_value > 0 else Noneself.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()def forward(self, x):input = xx = self.dwconv(x)x = x.permute(0, 2, 3, 1)  # (N, C, H, W) -> (N, H, W, C)x = self.norm(x)x = self.pwconv1(x)x = self.act(x)x = self.pwconv2(x)if self.gamma is not None:x = self.gamma * xx = x.permute(0, 3, 1, 2)  # (N, H, W, C) -> (N, C, H, W)x = input + self.drop_path(x)return x

SDTA(Split Depth-wise Transpose Attention)

class SDTAEncoder(nn.Module):def __init__(self, dim, drop_path=0., layer_scale_init_value=1e-6, expan_ratio=4,use_pos_emb=True, num_heads=8, qkv_bias=True, attn_drop=0., drop=0., scales=1):super().__init__()width = max(int(math.ceil(dim / scales)), int(math.floor(dim // scales)))self.width = widthif scales == 1:self.nums = 1else:self.nums = scales - 1convs = []for i in range(self.nums):convs.append(nn.Conv2d(width, width, kernel_size=3, padding=1, groups=width))self.convs = nn.ModuleList(convs)self.pos_embd = Noneif use_pos_emb:self.pos_embd = PositionalEncodingFourier(dim=dim)self.norm_xca = LayerNorm(dim, eps=1e-6)self.gamma_xca = nn.Parameter(layer_scale_init_value * torch.ones(dim),requires_grad=True) if layer_scale_init_value > 0 else Noneself.xca = XCA(dim, num_heads=num_heads, qkv_bias=qkv_bias, attn_drop=attn_drop, proj_drop=drop)self.norm = LayerNorm(dim, eps=1e-6)self.pwconv1 = nn.Linear(dim, expan_ratio * dim)  # pointwise/1x1 convs, implemented with linear layersself.act = nn.GELU()  # TODO: MobileViT is using 'swish'self.pwconv2 = nn.Linear(expan_ratio * dim, dim)self.gamma = nn.Parameter(layer_scale_init_value * torch.ones((dim)),requires_grad=True) if layer_scale_init_value > 0 else Noneself.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()def forward(self, x):input = x# 切分通道,加入深度卷积来增加多尺度表示spx = torch.split(x, self.width, 1)for i in range(self.nums):if i == 0:sp = spx[i]else:sp = sp + spx[i]sp = self.convs[i](sp)if i == 0:out = spelse:out = torch.cat((out, sp), 1)x = torch.cat((out, spx[self.nums]), 1)# XCA,在通道上计算注意力B, C, H, W = x.shapex = x.reshape(B, C, H * W).permute(0, 2, 1)if self.pos_embd:# 加入位置坐标pos_encoding = self.pos_embd(B, H, W).reshape(B, -1, x.shape[1]).permute(0, 2, 1)x = x + pos_encodingx = x + self.drop_path(self.gamma_xca * self.xca(self.norm_xca(x)))x = x.reshape(B, H, W, C)# Inverted Bottleneck,倒残差结构。# 倒残差结构的特点是:先对输入特征通道扩张,再提取特征,最后输出相应的特征通道,对于通道数来说有点中间大两头小类似于梭子的形状,所以称这样的结构为 Inverted residuals(倒残差结构)。x = self.norm(x)x = self.pwconv1(x)x = self.act(x)x = self.pwconv2(x)if self.gamma is not None:x = self.gamma * xx = x.permute(0, 3, 1, 2)  # (N, H, W, C) -> (N, C, H, W)x = input + self.drop_path(x)return x

github地址

edgeNext

这篇关于EdgeNeXt: Efficiently Amalgamated CNN-Transformer Architecture for Mobile Vision Applications的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/226976

相关文章

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

深度学习实战:如何利用CNN实现人脸识别考勤系统

1. 何为CNN及其在人脸识别中的应用 卷积神经网络(CNN)是深度学习中的核心技术之一,擅长处理图像数据。CNN通过卷积层提取图像的局部特征,在人脸识别领域尤其适用。CNN的多个层次可以逐步提取面部的特征,最终实现精确的身份识别。对于考勤系统而言,CNN可以自动从摄像头捕捉的视频流中检测并识别出员工的面部。 我们在该项目中采用了 RetinaFace 模型,它基于CNN的结构实现高效、精准的

如何将卷积神经网络(CNN)应用于医学图像分析:从分类到分割和检测的实用指南

引言 在现代医疗领域,医学图像已经成为疾病诊断和治疗规划的重要工具。医学图像的类型繁多,包括但不限于X射线、CT(计算机断层扫描)、MRI(磁共振成像)和超声图像。这些图像提供了对身体内部结构的详细视图,有助于医生在进行准确诊断和制定个性化治疗方案时获取关键的信息。 1. 医学图像分析的挑战 医学图像分析面临诸多挑战,其中包括: 图像数据的复杂性:医学图像通常具有高维度和复杂的结构

Transformer从零详细解读

Transformer从零详细解读 一、从全局角度概况Transformer ​ 我们把TRM想象为一个黑盒,我们的任务是一个翻译任务,那么我们的输入是中文的“我爱你”,输入经过TRM得到的结果为英文的“I LOVE YOU” ​ 接下来我们对TRM进行细化,我们将TRM分为两个部分,分别为Encoders(编码器)和Decoders(解码器) ​ 在此基础上我们再进一步细化TRM的

PC/MCU/SoC使用的计算机架构(Architecture)

1. 冯·诺依曼结构 冯·诺依曼结构(Von Neumann Architecture)是计算机系统的经典架构,由数学家约翰·冯·诺依曼在1945年提出。它的核心思想是程序存储器和数据存储器共享同一存储设备,程序和数据以相同的方式存储和访问。冯·诺依曼架构的主要特点包括: 单一存储器:存储程序指令和数据在同一个存储器中。控制单元:通过程序计数器顺序执行指令。数据路径:通过一个共享的总线,将数据

LLM模型:代码讲解Transformer运行原理

视频讲解、获取源码:LLM模型:代码讲解Transformer运行原理(1)_哔哩哔哩_bilibili 1 训练保存模型文件 2 模型推理 3 推理代码 import torchimport tiktokenfrom wutenglan_model import WutenglanModelimport pyttsx3# 设置设备为CUDA(如果可用),否则使用CPU#

CNN-LSTM模型中应用贝叶斯推断进行时间序列预测

这篇论文的标题是《在混合CNN-LSTM模型中应用贝叶斯推断进行时间序列预测》,作者是Thi-Lich Nghiem, Viet-Duc Le, Thi-Lan Le, Pierre Maréchal, Daniel Delahaye, Andrija Vidosavljevic。论文发表在2022年10月于越南富国岛举行的国际多媒体分析与模式识别会议(MAPR)上。 摘要部分提到,卷积

逐行讲解Transformer的代码实现和原理讲解:计算交叉熵损失

LLM模型:Transformer代码实现和原理讲解:前馈神经网络_哔哩哔哩_bilibili 1 计算交叉熵目的 计算 loss = F.cross_entropy(input=linear_predictions_reshaped, target=targets_reshaped) 的目的是为了评估模型预测结果与实际标签之间的差距,并提供一个量化指标,用于指导模型的训练过程。具体来说,交叉

复盘高质量Vision Pro沉浸式视频的制作流程与工具

在探索虚拟现实(VR)和增强现实(AR)技术的过程中,高质量的沉浸式体验是至关重要的。最近,国外开发者Dreamwieber在其作品中展示了如何使用一系列工具和技术,创造出令人震撼的Vision Pro沉浸式视频。本文将详细复盘Dreamwieber的工作流,希望能为从事相关领域的开发者们提供有价值的参考。 一、步骤和工作流 构建基础原型 目的:快速搭建起一个基本的模型,以便在设备

深度学习每周学习总结N9:transformer复现

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 | 接辅导、项目定制 目录 多头注意力机制前馈传播位置编码编码层解码层Transformer模型构建使用示例 本文为TR3学习打卡,为了保证记录顺序我这里写为N9 总结: 之前有学习过文本预处理的环节,对文本处理的主要方式有以下三种: 1:词袋模型(one-hot编码) 2:TF-I