昇思25天学习打卡营第8天 |昇思MindSpore ShuffleNet 图像分类学习笔记

embedded/2024/9/24 14:21:30/
1. ShuffleNet 网络简介

ShuffleNet 是旷视科技提出的一种高效卷积神经网络模型,旨在使用有限的计算资源实现高模型精度。其核心思想包括:

  • Pointwise Group Convolution(逐点分组卷积):通过对通道进行分组,每组卷积核仅处理输入特征图的一部分通道,从而降低计算量。
  • Channel Shuffle(通道重排):解决 Group Convolution 导致的信息交流不足的问题,通过通道重排增强信息交互。
2. 网络架构
2.1 Pointwise Group Convolution
  • 分组卷积(Group Convolution):将卷积核分组,每组处理输入特征图的部分通道。相比于标准卷积,分组卷积的参数量减少,计算效率提高。

  • 深度可分离卷积(Depthwise Convolution):每个卷积核只处理一个输入通道,计算量大幅降低。

  • 逐点分组卷积(Pointwise Group Convolution):每组的卷积核为1×1卷积,进一步减少计算量。

    from mindspore import nn
    import mindspore.ops as ops
    from mindspore import Tensorclass GroupConv(nn.Cell):def __init__(self, in_channels, out_channels, kernel_size,stride, pad_mode="pad", pad=0, groups=1, has_bias=False):super(GroupConv, self).__init__()self.groups = groupsself.convs = nn.CellList()for _ in range(groups):self.convs.append(nn.Conv2d(in_channels // groups, out_channels // groups,kernel_size=kernel_size, stride=stride, has_bias=has_bias,padding=pad, pad_mode=pad_mode, group=1, weight_init='xavier_uniform'))def construct(self, x):features = ops.split(x, split_size_or_sections=int(len(x[0]) // self.groups), axis=1)outputs = ()for i in range(self.groups):outputs = outputs + (self.convs[i](features[i].astype("float32")),)out = ops.cat(outputs, axis=1)return out
    
2.2 Channel Shuffle
  • Channel Shuffle:将不同组别通道均匀分散重组,使得下一层能处理不同组别通道的信息,从而提高网络的特征提取能力。

    class ShuffleV1Block(nn.Cell):def __init__(self, inp, oup, group, first_group, mid_channels, ksize, stride):super(ShuffleV1Block, self).__init__()self.stride = stridepad = ksize // 2self.group = groupif stride == 2:outputs = oup - inpelse:outputs = oupself.relu = nn.ReLU()branch_main_1 = [GroupConv(in_channels=inp, out_channels=mid_channels,kernel_size=1, stride=1, pad_mode="pad", pad=0,groups=1 if first_group else group),nn.BatchNorm2d(mid_channels),nn.ReLU(),]branch_main_2 = [nn.Conv2d(mid_channels, mid_channels, kernel_size=ksize, stride=stride,pad_mode='pad', padding=pad, group=mid_channels,weight_init='xavier_uniform', has_bias=False),nn.BatchNorm2d(mid_channels),GroupConv(in_channels=mid_channels, out_channels=outputs,kernel_size=1, stride=1, pad_mode="pad", pad=0,groups=group),nn.BatchNorm2d(outputs),]self.branch_main_1 = nn.SequentialCell(branch_main_1)self.branch_main_2 = nn.SequentialCell(branch_main_2)if stride == 2:self.branch_proj = nn.AvgPool2d(kernel_size=3, stride=2, pad_mode='same')def construct(self, old_x):left = old_xright = old_xout = old_xright = self.branch_main_1(right)if self.group > 1:right = self.channel_shuffle(right)right = self.branch_main_2(right)if self.stride == 1:out = self.relu(left + right)elif self.stride == 2:left = self.branch_proj(left)out = ops.cat((left, right), 1)out = self.relu(out)return outdef channel_shuffle(self, x):batchsize, num_channels, height, width = ops.shape(x)group_channels = num_channels // self.groupx = ops.reshape(x, (batchsize, group_channels, self.group, height, width))x = ops.transpose(x, (0, 2, 1, 3, 4))x = ops.reshape(x, (batchsize, num_channels, height, width))return x
    
2.3 ShuffleNetV1 架构
  • ShuffleNetV1:包括输入卷积层、多个 ShuffleNet 模块、全局平均池化层、全连接层。

    class ShuffleNetV1(nn.Cell):def __init__(self, n_class=1000, model_size='2.0x', group=3):super(ShuffleNetV1, self).__init__()self.stage_repeats = [4, 8, 4]self.model_size = model_sizeif group == 3:if model_size == '0.5x':self.stage_out_channels = [-1, 12, 120, 240, 480]elif model_size == '1.0x':self.stage_out_channels = [-1, 24, 240, 480, 960]elif model_size == '1.5x':self.stage_out_channels = [-1, 24, 360, 720, 1440]elif model_size == '2.0x':self.stage_out_channels = [-1, 48, 480, 960, 1920]else:raise NotImplementedErrorelif group == 8:if model_size == '0.5x':self.stage_out_channels = [-1, 16, 192, 384, 768]elif model_size == '1.0x':self.stage_out_channels = [-1, 24, 384, 768, 1536]elif model_size == '1.5x':self.stage_out_channels = [-1, 24, 576, 1152, 2304]elif model_size == '2.0x':self.stage_out_channels = [-1, 48, 768, 1536, 3072]else:raise NotImplementedErrorinput_channel = self.stage_out_channels[1]self.first_conv = nn.SequentialCell(nn.Conv2d(3, input_channel, 3, 2, 'pad', 1, weight_init='xavier_uniform', has_bias=False),nn.BatchNorm2d(input_channel),nn.ReLU(),)self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, pad_mode='same')features = []for idxstage in range(len(self.stage_repeats)):numrepeat = self.stage_repeats[idxstage]output_channel = self.stage_out_channels[idxstage + 2]for i in range(numrepeat):stride = 2 if i == 0 else 1first_group = idxstage == 0 and i == 0features.append(ShuffleV1Block(input_channel, output_channel,group=group, first_group=first_group,mid_channels=output_channel // 4, ksize=3, stride=stride))input_channel = output_channelself.features = nn.SequentialCell(features)self.globalpool = nn.AvgPool2d(7)self.classifier = nn.Dense(self.stage_out_channels[-1], n_class)def construct(self, x):x = self.first_conv(x)x = self.maxpool(x)x = self.features(x)x = self.globalpool(x)x = ops.reshape(x, (-1, self.stage_out_channels[-1]))x = self.classifier(x)return x
    
3. 模型训练与评估
3.1 数据集准备
  • CIFAR-10 数据集:包含 60000 张 32×32 彩色图像,分为 10 类。训练集 50000 张,测试集 10000 张。

    from download import downloadurl = "https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/datasets/cifar-10-binary.tar.gz"
    download(url, cache_dir='./datasets')
    
3.2 训练配置
  • 训练超参数

    • 学习:0.1
    • 批量大小:128
    • 优化器:SGD
    from mindspore import context
    from mindspore.train import Model
    from mindspore.nn import SGD, SoftmaxCrossEntropyWithLogits, Accuracy
    from mindspore.dataset import Cifar10Dataset
    from mindspore import nncontext.set_context(mode=context.GRAPH_MODE, device_target="CPU")net = ShuffleNetV1()
    loss = SoftmaxCrossEntropyWithLogits(sparse=True, reduction='mean')
    optimizer = SGD(params=net.trainable_params(), learning_rate=0.1, momentum=0.9)
    metrics = {"accuracy": Accuracy()}model = Model(net, loss_fn=loss, optimizer=optimizer, metrics=metrics)train_dataset = Cifar10Dataset(dataset_dir='./datasets/cifar-10-binary/', usage='train')
    test_dataset = Cifar10Dataset(dataset_dir='./datasets/cifar-10-binary/', usage='test')model.train(10, train_dataset)
    eval_result = model.eval(test_dataset)
    print("Evaluation result:", eval_result)
    
4. 总结
  • ShuffleNet 的优势:通过分组卷积和通道重排显著减少计算量,提高效率。
  • 模型应用:适用于资源受限的设备,如移动端和嵌入式系统。

学习 ShuffleNet 时,可以通过代码实践来深入理解其优化原理和应用场景,并通过比较不同网络模型的性能来评估 ShuffleNet 的实际效果。


http://www.ppmy.cn/embedded/87511.html

相关文章

2024-07-24 Linux C語言使用inotify进行文件变化检测

一、在Linux中,用C语言检测文件内容变化的方法有几种,最常用的包括以下几种: 轮询(Polling):周期性地读取文件并检查内容是否变化。inotify:使用Linux内核提供的inotify接口,这是一…

Python爬虫技术 第23节 数据清洗和预处理

在使用Python进行网络爬虫项目时,数据清洗和预处理是非常重要的步骤。这些步骤有助于确保从网页上抓取的数据准确、一致,并且适合后续的分析或机器学习任务。下面我将详细介绍如何使用Python来进行数据清洗和预处理。 1. 数据获取 首先,你需…

go程序在windows服务中优雅开启和关闭

本篇主要是讲述一个go程序,如何在windows服务中优雅开启和关闭,废话不多说,开搞!!!   使用方式:go程序 net服务启动 Ⅰ 开篇不利 Windows go进程编译后,为一个.exe文件,直接执行即…

本地化部署Chatglm和防踩坑攻略

最近想搞点什么东西练练手,传统crud又没有意义,于是就看到了给介绍AI的文章,然后就慢慢自己摸索,从0到1,独自部署应用。 项目简介 ChatGLM3 是智谱AI和清华大学 KEG 实验室联合发布的对话预训练模型。ChatGLM3-6B 是…

pandas安装以及导入CSV

安装pandas pip install pandas速度慢可以切换国内镜像源 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pandas执行导入csv操作 import pandas as pd# 读取csv文件 data pd.read_csv(yourPath)输入data查看数据 导入成功!

写代码对人的影响

1 代码是需要跑起来的,不能你写了一段代码运行不了 2 代码过程中有大量的bug,经常异常报错,你需要花费时间去解决 对人的影响就是解决问题的态度得到强化,解决问题要比坚持正确困难,坚持正确只是需要自然而然的努力&…

PHP命名空间

PHP 命名空间是 PHP 5.3.0 版本之后引入的一个重要特性,它提供了一种将相关的类、接口、函数和常量组合在一起的方式,以避免命名冲突,并更好地组织代码。以下是对 PHP 命名空间的详细教程: 一、命名空间的定义 使用 namespace 关…

第六章 面向对象 复习

面向对象基本概念 面向对象设计原则 面向对象真题 UML UML关系 UML类图 设计模式 设计模式真题