Python从0到100(八十六):神经网络-ShuffleNet通道混合轻量级网络的深入介绍

news2025/2/1 17:24:54

在这里插入图片描述

前言: 零基础学Python:Python从0到100最新最全教程。 想做这件事情很久了,这次我更新了自己所写过的所有博客,汇集成了Python从0到100,共一百节课,帮助大家一个月时间里从零基础到学习Python基础语法、Python爬虫、Web开发、 计算机视觉、机器学习、神经网络以及人工智能相关知识,成为学习学习和学业的先行者!
欢迎大家订阅专栏:零基础学Python:Python从0到100最新最全教程!

本文目录:

  • 一、ShuffleNet架构详解
    • 1. 通道混合机制(Channel Shuffle)
    • 2. 深度可分离卷积(Depthwise Separable Convolution)
    • 3. 轻量化设计
    • 4. 自适应平均池化(Adaptive Average Pooling)
  • 二、ShuffleNet架构
    • 1.网络结构概述
    • 2.代码实现
      • 2.1 ChannelShuffleModule 详解
        • 初始化方法 `__init__`
        • 前向传播方法 `forward`
      • 2.2 ShuffleNet 网络结构详解
        • 初始化方法 `__init__`
        • 前向传播方法 `forward`
        • 完整代码
  • 三、网络结构特点
    • 1. 深度可分离卷积:高效计算的核心
    • 2. 通道数的变化:动态调整通道数以优化性能
    • 3. 批量归一化和 ReLU:提升训练效率和稳定性
    • 4. 通道混合:增强通道间的信息流动
    • 5. 自适应平均池化:适应不同输入尺寸
  • 四、ShuffleNet 的优势总结

ShuffleNet是一种轻量级的深度学习模型,它在保持MobileNet的Depthwise Separable Convolution(深度可分离卷积)的基础上,引入了通道混合(Channel Shuffle)机制,以进一步提升模型的性能和效率。

image.png

一、ShuffleNet架构详解

1. 通道混合机制(Channel Shuffle)

通道混合是 ShuffleNet 的核心创新之一。在传统的深度学习模型中,卷积层的输出通道通常在空间上是高度相关的,这种相关性限制了模型的表示能力。ShuffleNet 通过通道混合机制打破了这种限制。具体来说,通道混合通过在组间重新排列通道,增强了通道间的信息流动,从而提高了模型的性能。
在实际应用中,通道混合模块的工作原理如下:假设输入张量的通道数为 C,我们将这些通道分成 G 个组,每个组包含 C/G 个通道。然后,我们在每个组内对通道进行重新排列,使得不同组的通道能够相互“交流”。这种重新排列的操作类似于洗牌,因此得名“通道混合”。

2. 深度可分离卷积(Depthwise Separable Convolution)

ShuffleNet 继承了 MobileNet 的深度可分离卷积技术。深度可分离卷积将标准的卷积操作分解为两个步骤:深度卷积(Depthwise Convolution)和逐点卷积(Pointwise Convolution)。深度卷积为每个输入通道单独应用一个卷积核,而逐点卷积则通过 1×1 卷积核将深度卷积的输出通道进行组合。这种分解方式显著减少了模型的参数数量和计算量,使得 ShuffleNet 能够在计算资源受限的设备上高效运行。

3. 轻量化设计

ShuffleNet 的设计目标是实现轻量化,以便在移动和嵌入式设备上高效运行。为了达到这一目标,ShuffleNet 在多个方面进行了优化。首先,它通过深度可分离卷积减少了参数数量和计算量。其次,ShuffleNet 采用了通道混合机制,进一步提高了模型的效率。此外,ShuffleNet 还引入了自适应平均池化(Adaptive Average Pooling),允许模型接受任意尺寸的输入,并将其转换为固定尺寸的输出,为后续的全连接层提供了便利。

4. 自适应平均池化(Adaptive Average Pooling)

自适应平均池化是 ShuffleNet 的一个重要组成部分。它允许模型接受任意尺寸的输入,并将其转换为固定尺寸的输出。这种灵活性使得 ShuffleNet 能够适应不同的输入尺寸,而无需对模型结构进行调整。在实际应用中,自适应平均池化通常用于将特征图的尺寸调整为 1×1,以便为全连接层提供输入。

二、ShuffleNet架构

1.网络结构概述

ShuffleNet主要由以下几个部分组成:

  1. 输入层:接收输入数据。
  2. 深度可分离卷积层:减少参数数量和计算量。
  3. 批量归一化层:提高训练效率和稳定性。
  4. ReLU激活函数:引入非线性。
  5. 通道混合模块:增强通道间的信息流动。
  6. 自适应平均池化层:适应不同尺寸的输入。
  7. 全连接层:输出分类结果。

这种结构设计使得 ShuffleNet 在保持高效性的同时,也具备了较强的特征提取能力。

2.代码实现

2.1 ChannelShuffleModule 详解

ChannelShuffleModule 是 ShuffleNet 中用于增强通道间信息流动的关键组件。它通过将输入张量的通道分成多个组,并在组内进行洗牌,从而实现通道间的信息重组。

初始化方法 __init__

在初始化方法中,我们接收两个参数:channelsgroupschannels 是输入张量的通道数,而 groups 是我们想要将这些通道分成的组数。我们通过一个断言来确保 channels 可以被 groups 整除,以保证每个组内的通道数是均匀的。

assert channels % groups == 0

接着,我们存储这些值,并计算每个组应有的通道数。

self.channel_per_group = self.channels // self.groups
前向传播方法 forward

在前向传播方法中,我们首先获取输入张量的尺寸,这包括批量大小 batch、通道数 _、序列长度 series 和模态数 modal

batch, _, series, modal = x.size()

然后,我们将输入张量重新排列成 groups 个组,每组包含 self.channel_per_group 个通道。这一步通过 reshape 方法实现。

x = x.reshape(batch, self.groups, self.channel_per_group, series, modal)

接下来是洗牌操作,这是通过 permute 方法实现的。我们交换 permute 方法中指定维度的顺序,从而在组内打乱通道的顺序。

x = x.permute(0, 2, 1, 3, 4)

最后,我们再次使用 reshape 方法将张量恢复到原始的形状,并将其返回。

x = x.reshape(batch, self.channels, series, modal)
return x

2.2 ShuffleNet 网络结构详解

ShuffleNet 类定义了整个网络的结构,它由多个组件组成,包括卷积层、批量归一化层、ReLU 激活函数、通道混合模块、自适应平均池化层和全连接层。

初始化方法 __init__

在初始化方法中,我们接收三个参数:train_shape 表示训练样本的形状,category 表示类别的数量,kernel_size 表示卷积核的尺寸。

def __init__(self, train_shape, category, kernel_size=3):

我们使用 nn.Sequential 来组织网络中的多个层,包括卷积层、批量归一化层、ReLU 激活函数和通道混合模块。

self.layer = nn.Sequential(
    # 第一个卷积层,用于减少输入通道并进行空间维度的下采样
    nn.Conv2d(1, 1, (kernel_size, 1), (2, 1), (kernel_size // 2, 0), groups=1),
    # ...
)

这里,我们首先使用一个深度可分离卷积来减少输入通道,并进行空间维度的下采样。然后,我们添加一个1x1的卷积层来扩展通道数,接着是批量归一化层、ReLU 激活函数和通道混合模块。

我们还添加了一个自适应平均池化层,它可以根据输入特征图的实际尺寸动态调整池化尺寸,以确保输出尺寸的一致性。

self.ada_pool = nn.AdaptiveAvgPool2d((1, train_shape[-1]))

最后,我们添加一个全连接层,它将展平的特征图映射到最终的分类结果。

self.fc = nn.Linear(512*train_shape[-1], category)
前向传播方法 forward

在前向传播方法中,我们首先将输入数据 x 通过 self.layer 中定义的卷积层和通道混合模块。

x = self.layer(x)

然后,我们将结果通过自适应平均池化层,以获得固定尺寸的特征图。

x = self.ada_pool(x)

接下来,我们将特征图展平,以适配全连接层。

x = x.view(x.size(0), -1)

最后,我们通过全连接层 self.fc 得到最终的分类结果,并将其返回。

x = self.fc(x)
return x
完整代码
import torch.nn as nn
class ChannelShuffleModule(nn.Module):
    def __init__(self, channels, groups):
        super().__init__()
        assert channels % groups == 0
        self.channels = channels
        self.groups = groups
        self.channel_per_group = self.channels // self.groups

    def forward(self, x):
        '''
            x.shape: [b, c, series, modal]
        '''
        batch, _, series, modal = x.size()
        x = x.reshape(batch, self.groups, self.channel_per_group, series, modal)
        x = x.permute(0, 2, 1, 3, 4)
        x = x.reshape(batch, self.channels, series, modal)
        return x

class ShuffleNet(nn.Module):
    def __init__(self, train_shape, category, kernel_size=3):
        super(ShuffleNet, self).__init__()
        self.layer = nn.Sequential(
            nn.Conv2d(1, 1, (kernel_size, 1), (2, 1), (kernel_size // 2, 0), groups=1),
            nn.Conv2d(1, 64, 1, 1, 0),
            nn.BatchNorm2d(64),
            nn.ReLU(),
            ChannelShuffleModule(channels=64, groups=8),

            nn.Conv2d(64, 64, (kernel_size, 1), (2, 1), (kernel_size // 2, 0), groups=64),
            nn.Conv2d(64, 128, 1, 1, 0),
            nn.BatchNorm2d(128),
            nn.ReLU(),
            ChannelShuffleModule(channels=128, groups=8),

            nn.Conv2d(128, 128, (kernel_size, 1), (2, 1), (kernel_size // 2, 0), groups=128),
            nn.Conv2d(128, 256, 1, 1, 0),
            nn.BatchNorm2d(256),
            nn.ReLU(),
            ChannelShuffleModule(channels=256, groups=16),

            nn.Conv2d(256, 256, (kernel_size, 1), (2, 1), (kernel_size // 2, 0), groups=256),
            nn.Conv2d(256, 512, 1, 1, 0),
            nn.BatchNorm2d(512),
            nn.ReLU(),
            ChannelShuffleModule(channels=512, groups=16)
        )
        self.ada_pool = nn.AdaptiveAvgPool2d((1, train_shape[-1]))
        self.fc = nn.Linear(512*train_shape[-1], category)

    def forward(self, x):
        x = self.layer(x)
        x = self.ada_pool(x)
        x = x.view(x.size(0), -1)
        x = self.fc(x)
        return x

ShuffleNet 的初始化方法中,我们定义了一个包含多个卷积层、批量归一化层、ReLU 激活函数和通道混合模块的序列。每个卷积层都使用了深度可分离卷积技术,以减少参数数量和计算量。自适应平均池化层用于将不同尺寸的特征图转换为固定尺寸的输出,最后通过全连接层输出分类结果。

三、网络结构特点

1. 深度可分离卷积:高效计算的核心

深度可分离卷积 是 ShuffleNet 的关键特性之一,它将传统的卷积操作分解为两个独立的步骤:深度卷积(Depthwise Convolution)逐点卷积(Pointwise Convolution) 。这种分解方式极大地减少了模型的参数数量和计算量。

  • 深度卷积:深度卷积为每个输入通道单独应用一个卷积核,而不涉及通道间的交互。这种方式显著减少了卷积操作的计算复杂度。
  • 逐点卷积:逐点卷积使用 1×1 的卷积核对深度卷积的输出进行组合,增加了通道间的交互。这种组合方式不仅减少了参数数量,还保留了模型的表达能力。

在 ShuffleNet 中,深度可分离卷积被广泛应用于多个卷积层中。例如,在第一个卷积层中,深度可分离卷积将输入通道数减少到 1,然后通过 1×1 卷积将通道数扩展到 64。这种设计不仅减少了参数数量,还为后续的卷积层提供了足够的通道数。

2. 通道数的变化:动态调整通道数以优化性能

ShuffleNet 在网络的不同阶段动态调整通道数,以优化性能和计算效率。通过 1×1 卷积层,模型能够灵活地增加或减少通道数。例如,在第一个卷积层中,输入通道数被扩展到 64,为后续的深度可分离卷积提供了足够的输入通道。这种动态调整通道数的设计不仅提高了模型的灵活性,还减少了计算量。

此外,ShuffleNet 在后续的卷积层中逐步增加通道数,以适应更复杂的特征提取需求。例如,在第二个卷积层中,通道数从 64 增加到 128;在第三个卷积层中,通道数进一步增加到 256。这种逐步增加通道数的设计使得模型能够在不同阶段提取不同层次的特征,从而提高了模型的性能。

3. 批量归一化和 ReLU:提升训练效率和稳定性

在深度学习模型中,批量归一化(Batch Normalization)ReLU 激活函数 是两个重要的组件,它们能够显著提高模型的训练效率和稳定性。

  • 批量归一化:批量归一化通过归一化每个特征的输入,减少了内部协变量偏移(Internal Covariate Shift),从而加快了模型的收敛速度。在 ShuffleNet 中,每个卷积层后都添加了批量归一化层,以提高训练效率和模型的稳定性。
  • ReLU 激活函数:ReLU 激活函数通过引入非线性,使得模型能够学习复杂的特征表示。在 ShuffleNet 中,ReLU 激活函数被广泛应用于每个卷积层后,以提高模型的非线性表达能力。

4. 通道混合:增强通道间的信息流动

通道混合(Channel Shuffle) 是 ShuffleNet 的核心创新之一。在传统的卷积神经网络中,卷积层的输出通道通常在空间上是高度相关的,这种相关性限制了模型的表示能力。ShuffleNet 通过通道混合机制打破了这种限制。

通道混合模块的工作原理如下:假设输入张量的通道数为 C,我们将这些通道分成 G 个组,每个组包含 C/G 个通道。然后,我们在每个组内对通道进行重新排列,使得不同组的通道能够相互“交流”。这种重新排列的操作类似于洗牌,因此得名“通道混合”。

通道混合机制不仅增强了通道间的信息流动,还提高了模型的特征提取能力。在 ShuffleNet 中,通道混合模块被广泛应用于每个深度可分离卷积块后,以增强通道间的信息交互。

5. 自适应平均池化:适应不同输入尺寸

自适应平均池化(Adaptive Average Pooling) 是 ShuffleNet 的一个重要组成部分。它允许模型接受任意尺寸的输入,并将其转换为固定尺寸的输出。这种灵活性使得 ShuffleNet 能够适应不同的输入尺寸,而无需对模型结构进行调整。

在实际应用中,自适应平均池化通常用于将特征图的尺寸调整为 1×1,以便为全连接层提供输入。在 ShuffleNet 中,自适应平均池化层被放置在卷积层之后,以确保模型能够处理不同尺寸的输入数据。


ShuffleNet 的设计哲学在于通过 轻量化的设计 实现高效的特征提取。它通过 深度可分离卷积通道混合技术 减少了模型的参数数量和计算量,同时保持了较高的性能。这种设计使得 ShuffleNet 非常适合在计算资源受限的移动和嵌入式设备上部署,用于图像识别和处理任务。

具体来说,ShuffleNet 的轻量化设计主要体现在以下几个方面:

  • 深度可分离卷积:通过将卷积操作分解为深度卷积和逐点卷积,显著减少了参数数量和计算量。
  • 通道混合:通过在组内重新排列通道,增强了通道间的信息流动,提高了模型的特征提取能力。
  • 自适应平均池化:通过将特征图的尺寸调整为固定尺寸,使得模型能够适应不同尺寸的输入数据。
  • 动态调整通道数:通过 1×1 卷积层动态调整通道数,优化了模型的性能和计算效率。

这种轻量化设计不仅提高了 ShuffleNet 的计算效率,还使得它能够在移动和嵌入式设备上高效运行。ShuffleNet 的高效性和灵活性使其成为一种理想的轻量级深度学习模型,适用于各种资源受限的场景。

四、ShuffleNet 的优势总结

ShuffleNet 的设计哲学和轻量化设计使其具有以下优势:

  • 高效性:通过 深度可分离卷积通道混合技术,ShuffleNet 显著减少了参数数量和计算量,提高了模型的计算效率。
  • 灵活性:通过 自适应平均池化 和动态调整通道数,ShuffleNet 能够适应不同尺寸的输入数据,具有很强的灵活性。
  • 高性能:尽管参数数量和计算量减少,但 ShuffleNet 通过通道混合机制增强了通道间的信息流动,保持了较高的性能。
  • 适用性:ShuffleNet 的轻量化设计使其能够在移动和嵌入式设备上高效运行,适用于各种资源受限的场景。

尽管 ShuffleNet 在轻量级深度学习模型中已经取得了显著的成果,但仍有进一步优化的空间。未来,随着技术的不断发展,ShuffleNet 可以在更多领域进行应用,如 自动驾驶医疗影像分析自然语言处理 等。

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

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

相关文章

大模型本地化部署(Ollama + Open-WebUI)

文章目录 环境准备下载Ollama模型下载下载Open-WebUI 本地化部署的Web图形化界面本地模型联网查询安装 Docker安装 SearXNG本地模型联网查询 环境准备 下载Ollama 下载地址:Ollama网址 安装完成后,命令行里执行命令 ollama -v查看是否安装成功。安装成…

【Linux系统】进程间通信:共享内存

认识共享内存 通过 一些系统调用,在物理内存中开辟一块空间,然后将该空间的起始地址,通过页表映射到两个进程的虚拟地址空间的共享区中,这样不就共享了一块空间吗!!! 这种技术就是共享内存&am…

渗透测试之WAF组合条件绕过方式手法详解以及SQL注入参数污染绕过

目录 组合绕过waf ​先看一些语句 绕过方式 我给出的注入语句是: 这里要注意的几点是: 组合绕过方式 完整过狗注入语句集合 http请求分块传输方法 其它方式绕过 http参数污染绕过waf 面试题:如何参数污染绕过waf 可以通过http参数污染绕过wa…

oracl:多表查询>>表连接[内连接,外连接,交叉连接,自连接,自然连接,等值连接和不等值连接]

SQL(Structured Query Language,结构化查询语言)是一种用于管理和操作关系数据库的标准编程语言。 sql分类: 数据查询语言(DQL - Data Query Language) 查询的关键词 select 多表查询>>表连接 表连接: 把2个…

ARIMA详细介绍

ARIMA(AutoRegressive Integrated Moving Average,自回归积分滑动平均模型)是一种用于时间序列分析和预测的统计模型。它结合了自回归(AR)、差分(I)和移动平均(MA)三种方…

飞致云开源社区月度动态报告(2025年1月)

自2023年6月起,中国领先的开源软件公司飞致云以月度为单位发布《飞致云开源社区月度动态报告》,旨在向广大社区用户同步飞致云旗下系列开源软件的发展情况,以及当月主要的产品新版本发布、社区运营成果等相关信息。 飞致云开源运营数据概览&…

【搜索回溯算法篇】:拓宽算法视野--BFS如何解决拓扑排序问题

✨感谢您阅读本篇文章,文章内容是个人学习笔记的整理,如果哪里有误的话还请您指正噢✨ ✨ 个人主页:余辉zmh–CSDN博客 ✨ 文章所属专栏:搜索回溯算法篇–CSDN博客 文章目录 一.广度优先搜索(BFS)解决拓扑排…

WPS怎么使用latex公式?

1、下载并安装mathtype https://blog.csdn.net/weixin_43135178/article/details/125143654?sharetypeblogdetail&sharerId125143654&sharereferPC&sharesourceweixin_43135178&spm1011.2480.3001.8118 2、将mathtype嵌入在WPS MathType面板嵌入器,免费工具…

简单的爱心跳动表白网页(附源码)

一:准备工作 在开始之前,确保已经具备基础的 HTML、CSS 和 JavaScript 知识。同时,也要准备好一个代码编辑器,比如 VS Code 或 Sublime Text。接下来,我们需要创建三个文件:index.html、styles.css 和 scr…

【AI】DeepSeek 概念/影响/使用/部署

在大年三十那天,不知道你是否留意到,“deepseek”这个词出现在了各大热搜榜单上。这引起了我的关注,出于学习的兴趣,我深入研究了一番,才有了这篇文章的诞生。 概念 那么,什么是DeepSeek?首先百…

【4Day创客实践入门教程】Day3 实战演练——桌面迷你番茄钟

Day3 实战演练——桌面迷你番茄钟 目录 Day3 实战演练——桌面迷你番茄钟1. 选择、准备元件、收集资料2. 硬件搭建3.编写代码 Day0 创想启程——课程与项目预览Day1 工具箱构建——开发环境的构建Day2 探秘微控制器——单片机与MicroPython初步Day3 实战演练——桌面迷你番茄钟…

AndroidCompose Navigation导航精通1-基本页面导航与ViewPager

文章目录 前言基本页面导航库依赖导航核心部件简单NavHost实现ViewPagerPager切换逻辑图阐述Pager导航实战前言 在当今的移动应用开发中,导航是用户与应用交互的核心环节。随着 Android Compose 的兴起,它为开发者提供了一种全新的、声明式的方式来构建用户界面,同时也带来…

Node.js——body-parser、防盗链、路由模块化、express-generator应用生成器

个人简介 👀个人主页: 前端杂货铺 🙋‍♂️学习方向: 主攻前端方向,正逐渐往全干发展 📃个人状态: 研发工程师,现效力于中国工业软件事业 🚀人生格言: 积跬步…

C语言指针专题四 -- 多级指针

目录 1. 多级指针的核心原理 1. 多级指针的定义 2. 内存结构示意图 3. 多级指针的用途 2. 编程实例 实例1:二级指针操作(修改一级指针的值) 实例2:动态二维数组(二级指针) 实例3:三级指…

深度学习的应用

目录 一、机器视觉 1.1 应用场景 1.2 常见的计算机视觉任务 1.2.1 图像分类 1.2.2 目标检测 1.2.3 图像分割 二、自然语言处理 三、推荐系统 3.1 常用的推荐系统算法实现方案 四、图像分类实验补充 4.1 CIFAR-100 数据集实验 实验代码 4.2 CIFAR-10 实验代码 深…

RabbitMQ 多种安装模式

文章目录 前言一、Windows 安装 RabbitMq1、版本关系2、Erlang2.1、下载安装 Erlang 23.12.2、配置 Erlang 环境变量 3、RabbitMQ3.1、下载安装 RabbitMQ 3.8.93.2、环境变量3.3、启动RabbitMQ 管理插件3.3、RabbitMQ3.4、注意事项 二、安装docker1、更新系统包:2、…

吴恩达深度学习——有效运作神经网络

内容来自https://www.bilibili.com/video/BV1FT4y1E74V,仅为本人学习所用。 文章目录 训练集、验证集、测试集偏差、方差正则化正则化参数为什么正则化可以减少过拟合Dropout正则化Inverted Dropout其他的正则化方法数据增广Early stopping 归一化梯度消失与梯度爆…

DDD - 微服务架构模型_领域驱动设计(DDD)分层架构 vs 整洁架构(洋葱架构) vs 六边形架构(端口-适配器架构)

文章目录 引言1. 概述2. 领域驱动设计(DDD)分层架构模型2.1 DDD的核心概念2.2 DDD架构分层解析 3. 整洁架构:洋葱架构与依赖倒置3.1 整洁架构的核心思想3.2 整洁架构的层次结构 4. 六边形架构:解耦核心业务与外部系统4.1 六边形架…

数据结构与算法之二叉树: LeetCode LCP 10. 二叉树任务调度 (Ts版)

二叉树任务调度 https://leetcode.cn/problems/er-cha-shu-ren-wu-diao-du/description/ 描述 任务调度优化是计算机性能优化的关键任务之一。在任务众多时,不同的调度策略可能会得到不同的总体执行时间,因此寻求一个最优的调度方案是非常有必要的 通…

玩转大语言模型——配置图数据库Neo4j(含apoc插件)并导入GraphRAG生成的知识图谱

系列文章目录 玩转大语言模型——使用langchain和Ollama本地部署大语言模型 玩转大语言模型——ollama导入huggingface下载的模型 玩转大语言模型——langchain调用ollama视觉多模态语言模型 玩转大语言模型——使用GraphRAGOllama构建知识图谱 玩转大语言模型——完美解决Gra…