华为开源自研AI框架昇思MindSpore应用案例:梯度累加

news2024/11/19 2:32:31

目录

  • 一、环境准备
    • 1.进入ModelArts官网
    • 2.使用CodeLab体验Notebook实例
  • 二、案例实现

梯度累加的训练算法,目的是为了解决由于内存不足,导致Batch size过大神经网络无法训练,或者网络模型过大无法加载的OOM(Out Of Memory)问题。
在这里插入图片描述

如果你对MindSpore感兴趣,可以关注昇思MindSpore社区

在这里插入图片描述

在这里插入图片描述

一、环境准备

1.进入ModelArts官网

云平台帮助用户快速创建和部署模型,管理全周期AI工作流,选择下面的云平台以开始使用昇思MindSpore,获取安装命令,安装MindSpore2.0.0-alpha版本,可以在昇思教程中进入ModelArts官网

在这里插入图片描述

选择下方CodeLab立即体验

在这里插入图片描述

等待环境搭建完成

在这里插入图片描述

2.使用CodeLab体验Notebook实例

下载NoteBook样例代码,梯度累加.ipynb为样例代码

在这里插入图片描述

选择ModelArts Upload Files上传.ipynb文件

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

选择Kernel环境

在这里插入图片描述

切换至GPU环境,切换成第一个限时免费

在这里插入图片描述

进入昇思MindSpore官网,点击上方的安装

在这里插入图片描述

获取安装命令

在这里插入图片描述

回到Notebook中,在第一块代码前加入命令
在这里插入图片描述

conda update -n base -c defaults conda

在这里插入图片描述

安装MindSpore 2.0 GPU版本

conda install mindspore=2.0.0a0 -c mindspore -c conda-forge

在这里插入图片描述

安装mindvision

pip install mindvision

在这里插入图片描述

安装下载download

pip install download

在这里插入图片描述

二、案例实现

基于MindSpore的函数式自动微分机制,正向和反向执行完成后,函数将返回与训练参数相对应的梯度。因此我们需要设计一个梯度累加类Accumulator,对每一个Step产生的梯度值进行存储。下面是Accumulator的实现样例,我们需要维护两份与模型可训练参数的Shape相同的内部属性,分别为inner_grads和zeros。其中inner_grads用于存储累加的梯度值,zeros用于参数优化更新后的清零。同时,Accumulator内部维护了一个counter变量,在每一次正反向执行完成后,counter自增,通过对counter取模的方式来判断是否达到累加步数。

import mindspore as ms
from mindspore import Tensor, Parameter, ops

@ms.jit_class
class Accumulator():
    def __init__(self, optimizer, accumulate_step, clip_norm=1.0):
        self.optimizer = optimizer
        self.clip_norm = clip_norm
        self.inner_grads = optimizer.parameters.clone(prefix="accumulate_", init='zeros')
        self.zeros = optimizer.parameters.clone(prefix="zeros_", init='zeros')
        self.counter = Parameter(Tensor(1, ms.int32), 'counter_')
        assert accumulate_step > 0
        self.accumulate_step = accumulate_step
        self.map = ops.HyperMap()

    def __call__(self, grads):
        # 将单步获得的梯度累加至Accumulator的inner_grads
        self.map(ops.partial(ops.assign_add), self.inner_grads, grads)
        if self.counter % self.accumulate_step == 0:
            # 如果达到累加步数,进行参数优化更新
            self.optimizer(self.inner_grads)
            # 完成参数优化更新后,清零inner_grads
            self.map(ops.partial(ops.assign), self.inner_grads, self.zeros)
        # 计算步数加一
        ops.assign_add(self.counter, Tensor(1, ms.int32))

        return True

在这里插入图片描述

ms.jit_class为MindSpore即时编译修饰器,可以将普通的Python类作为可编译计算图使用。

接下来,我们使用快速入门中手写数字识别模型验证梯度累加的效果。

from mindspore import nn
from mindspore import value_and_grad
from mindspore.dataset import vision, transforms
from mindspore.dataset import MnistDataset

from download import download

url = "https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/" \
      "notebook/datasets/MNIST_Data.zip"
path = download(url, "./", kind="zip", replace=True)


def datapipe(path, batch_size):
    image_transforms = [
        vision.Rescale(1.0 / 255.0, 0),
        vision.Normalize(mean=(0.1307,), std=(0.3081,)),
        vision.HWC2CHW()
    ]
    label_transform = transforms.TypeCast(ms.int32)

    dataset = MnistDataset(path)
    dataset = dataset.map(image_transforms, 'image')
    dataset = dataset.map(label_transform, 'label')
    dataset = dataset.batch(batch_size)
    return dataset

class Network(nn.Cell):
    def __init__(self):
        super().__init__()
        self.flatten = nn.Flatten()
        self.dense_relu_sequential = nn.SequentialCell(
            nn.Dense(28*28, 512),
            nn.ReLU(),
            nn.Dense(512, 512),
            nn.ReLU(),
            nn.Dense(512, 10)
        )

    def construct(self, x):
        x = self.flatten(x)
        logits = self.dense_relu_sequential(x)
        return logits

model = Network()

在这里插入图片描述

假设我们在使用快速入门中配置的batch_size=64会导致显存不足,此时我们设置累加步数为2,通过执行两次batch_size=32进行梯度累加。

首先,我们使用Accumulator,传入实例化的optimizer,并配置累加步数。然后定义正向计算函数forward_fn,此时,由于梯度累加的需要,loss值需要进行相应的缩放。

accumulate_step = 2

loss_fn = nn.CrossEntropyLoss()
optimizer = nn.SGD(model.trainable_params(), 1e-2)
accumulator = Accumulator(optimizer, accumulate_step)

def forward_fn(data, label):
    logits = model(data)
    loss = loss_fn(logits, label)
    # loss除以累加步数accumulate_step
    return loss / accumulate_step

在这里插入图片描述

接下来继续使用value_and_grad函数进行函数变换,并构造单步训练函数train_step。此时我们使用实例化好的accumulator进行梯度累加,由于optimizer作为accumulator的内部属性,不需要单独执行。

grad_fn = value_and_grad(forward_fn, None, model.trainable_params())

@ms.jit
def train_step(data, label):
    loss, grads = grad_fn(data, label)
    accumulator(grads)
    return loss

在这里插入图片描述

接下来,我们定义训练和评估逻辑,进行训练验证。

def train_loop(model, dataset, loss_fn, optimizer):
    size = dataset.get_dataset_size()
    model.set_train()
    for batch, (data, label) in enumerate(dataset.create_tuple_iterator()):
        loss = train_step(data, label)

        if batch % 100 == 0:
            loss, current = loss.asnumpy(), batch
            print(f"loss: {loss:>7f}  [{current:>3d}/{size:>3d}]")

def test_loop(model, dataset, loss_fn):
    num_batches = dataset.get_dataset_size()
    model.set_train(False)
    total, test_loss, correct = 0, 0, 0
    for data, label in dataset.create_tuple_iterator():
        pred = model(data)
        total += len(data)
        test_loss += loss_fn(pred, label).asnumpy()
        correct += (pred.argmax(1) == label).asnumpy().sum()
    test_loss /= num_batches
    correct /= total
    print(f"Test: \n Accuracy: {(100*correct):>0.1f}%, Avg loss: {test_loss:>8f} \n")

在这里插入图片描述

接下来同样进行3个epoch的训练,注意此时根据我们的假设,数据集需要设置batch_size=32,每两步进行累加。

train_dataset = datapipe('MNIST_Data/train', 32)
test_dataset = datapipe('MNIST_Data/test', 32)

在这里插入图片描述

开始训练验证,此时由于batch_size调小需要训练的step数增加至2倍。最终Accuracy验证结果与快速入门结果一致,均为93.0%左右。

epochs = 3
for t in range(epochs):
    print(f"Epoch {t+1}\n-------------------------------")
    train_loop(model, train_dataset, loss_fn, optimizer)
    test_loop(model, test_dataset, loss_fn)
print("Done!")

在这里插入图片描述

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

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

相关文章

EdgeGallery开发指南

API接口 简介 EdgeGallery支持第三方业务系统通过北向接口网关调用EdgeGallery的业务接口。调用流程如下图所示(融合前端edgegallery-fe包含融合前端界面以及北向接口网关功能,通过浏览器访问时打开的是融合前端的界面,通过IP:Port/urlPref…

Tensorflow CUPTI could not be loaded 解决

使用conda在指定环境安装cudatoolkit和cudnn后出现 CUPTI could not be loaded问题 conda install cudatoolkit11.0.3 conda install cudnn8.0.5.39 将本机C:\Program Files\NVIDIA Corporation\Nsight Systems xxxx\target-windows-x64 包含cupti的文件均复制到 D:\xxx\cond…

vue + LogicFlow 实现流程图展示

vue LogicFlow 实现流程图展示 1.背景 部门主要负责低代码平台,配置端负责配置流程图,引擎端负责流程执行,原引擎端只负责流程执行控制以及流程历史列表展示。现在提出个新的要求,认为仅历史记录不直观,需要在展示完…

分享多种mfc100u.dll丢失的解决方法(一键修复DLL丢失的方法)

在使用电脑过程中,我们经常会遇到一些陌生的DLL文件,例如mfc100u.dll。这些DLL文件是动态链接库(Dynamic Link Libraries)的缩写,它们包含了可以被多个程序共享的代码和数据。今天,我们将深入探讨mfc100u.d…

【研发日记】Matlab/Simulink开箱报告(十)——Signal Routing模块模块

文章目录 前言 Signal Routing模块 虚拟模块和虚拟信号 Mux和Demux Vector Concatenate和Selector Bus Creator和Bus Selector 分析和应用 总结 前言 见《开箱报告,Simulink Toolbox库模块使用指南(五)——S-Fuction模块(C MEX S-Fun…

elasticsearch基础应用

1._cat接口 | _cat接口 | 说明 | | GET /_cat/nodes | 查看所有节点 | | GET /_cat/health | 查看ES健康状况 | | GET /_cat/master | 查看主节点 | | GET /_cat/indices | 查看所有索引信息 | es 中会默认提供上面的几个索引,表头…

【Redis】快速入门 数据类型 常用指令 在Java中操作Redis

文章目录 一、简介二、特点三、下载与安装四、使用4.1 服务器启动4.2 客户端连接命令4.3 修改Redis配置文件4.4 客户端图形化界面 五、数据类型5.1 五种常用数据类型介绍5.2 各种数据类型特点 六、常用命令6.1 字符串操作命令6.2 哈希操作命令6.3 列表操作命令6.4 集合操作命令…

ChatGPT赋能大气科学:GPT与Python结合应用遥感降水数据处理、ERA5大气再分析数据的统计分析、干旱监测及风能和太阳能资源评估等

目录 专题一 AI领域常见工具讲解 专题二 POE平台及ChatGPT使用方法 专题三 提示词工程 专题四 科研常见应用场景 专题五 Python简明教程 专题六 GPT科研绘图 专题七 GPT辅助下载数据 专题八 遥感降水数据 专题九 数据产品评估 专题十 ERA5全球大气再分析数据 专题十…

R语言 | 上下双向柱状图

1. 效果图 2. 代码 # 生成测试数据 difdata.frame(labelspaste0("pathway", 1:3),upc(30,15,1),downc(10,20,40) ) rownames(dif)dif$labels dif#变形 difreshape2::melt(dif) dif# 绘图 ggplot(dif, aes(xlabels, yifelse(variable"up", value, -value), …

大语言模型(LLM)token解读

1. 什么是token? 人们经常在谈论大模型时候,经常会谈到模型很大,我们也常常会看到一种说法: 参数会让我们了解神经网络的结构有多复杂,而token的大小会让我们知道有多少数据用于训练参数。 什么是token?比…

对比HTTP与WebSocket

目录 对比HTTP与WebSocket1. HTTP协议概述2. WebSocket协议概述3. HTTP与WebSocket的区别4. 使用场景比较5. 性能比较6. 安全性比较7. 应用案例分析8. 总结与展望 对比HTTP与WebSocket 1. HTTP协议概述 1.1 HTTP的基本概念 HTTP(Hypertext Transfer Protocol&…

【Leetcode每日一题】 递归 - 计算布尔二叉树的值(难度⭐⭐)(44)

1. 题目解析 题目链接:2331. 计算布尔二叉树的值 这个问题的理解其实相当简单,只需看一下示例,基本就能明白其含义了。 2.算法原理 算法思路概述: 问题解释:我们面对的是一个节点可能含有逻辑运算符(AN…

比例尺、等高距和DEM分辨率关系

地球表面的形态是很复杂的,不同地貌类型的形态是由它的相对高度、地面坡度以及所处的地势所决定的,它们是影响等高距的主要因素。从等高距计算公式可以看出,当地图比例尺和图上等高线间的最小距离简称等高线间距确定之后,地面坡度…

前端框架的简单介绍

html html-结构 盖房子之前先划三室二厅 (超文本标记语言)(可以实现一切的文本) css css-样式 在房里添家具 (层叠样式单)(化妆在脸上叠加) javascript(js) javascript(js)-交互(行为) 我点击你打开 供显示信息的元…

多维数组和交错数组笔记

1.) 关于数据的几个概念: Rank,即数组的维数,其值是数组类型的方括号之间逗号个数加上1。 Demo:利用一维数组显示斐波那契数列F(n) F(n-1) F(n-2) (n >2 ),每行显示5项,20项. static void Main(string[] args){int[] F n…

线程局部存储(TLS)

线程局部存储(Thread Local Storage,TLS),是一种变量的存储方法,这个变量在它所在的线程内是全局可访问的,但是不能被其他线程访问到,这样就保持了数据的线程独立性。而熟知的全局变量&#xff…

2014年认证杯SPSSPRO杯数学建模C题(第一阶段)土地储备方案的风险评估全过程文档及程序

2014年认证杯SPSSPRO杯数学建模 C题 土地储备方案的风险评估 原题再现: 土地储备,是指市、县人民政府国土资源管理部门为实现调控土地市场、促进土地资源合理利用目标,依法取得土地,进行前期开发、储存以备供应土地的行为。土地…

⼗多种免费Unity VR资源⼯具

1、VRTK是⼀种⾼效的VR⼯具包,⽤于在Unity3d中快速构建VR解决⽅案VRTK - Virtual Reality Toolkit - [ VR Toolkit ] | Integration | Unity Asset StoreUse the VRTK - Virtual Reality Toolkit - [ VR Toolkit ] from Sysdia Solutions Ltd on your next project.…

PyTorch-----torch.nn.Softmax()函数

Softmax原理 Softmax 函数是一种常用的激活函数,通常用于多分类问题中。它将一个含有多个实数值的向量(通常称为 logits)转换成一个概率分布,使得每个元素都在 (0, 1) 区间内,并且所有元素的和为 1。 假设我们有一个实…

YOLOv5实战记录02 模型检测

本人记录打卡,不够自习,慎看。 今天主要学了计组和计网,YOLO简单打个卡。 指路大佬:【手把手带你实战YOLOv5-入门篇】YOLOv5 模型检测_哔哩哔哩_bilibili 1. 主要讲了几个关键参数: 图源你可是处女座 运行示例&#…