自学内容网 自学内容网

昇思MindSpore 基础入门学习-保存与加载代码学习-CSDN

日期

心得

昇思MindSpore 基础入门学习 保存与加载 (AI 代码解析)

保存与加载

上一章节主要介绍了如何调整超参数,并进行网络模型训练。在训练网络模型的过程中,实际上我们希望保存中间和最后的结果,用于微调(fine-tune)和后续的模型推理与部署,本章节我们将介绍如何保存与加载模型。

import numpy as np                 # 导入numpy库,并简写为np,numpy是Python的一个科学计算库。
import mindspore                   # 导入mindspore库,mindspore是一个深度学习框架。
from mindspore import nn           # 从mindspore库中导入nn模块,nn是神经网络的缩写,用于构建网络层。
from mindspore import Tensor       # 从mindspore库中导入Tensor类,用于创建和操作mindspore张量。

解析:

  1. numpy 是一个开源的Python数值计算扩展库,用于数据操作、数学计算等操作。它提供了一个强大的N维数组对象ndarray,还包含了用于对这些数组执行操作的函数和方法。
  2. mindspore 是一个由华为开发的开源深度学习框架,用于构建和训练机器学习模型,特别是用于大规模和高性能的场景。
  3. nn 模块包含了构建深度学习网络所需要的各种层和函数,例如卷积层(Conv2d)、池化层(MaxPool2d)、全连接层(Dense)等。
  4. Tensor 类是mindspore中的一个关键概念,与numpyndarray类似,它代表了一个多维数组,可以用于存储和转换数据,是构建和训练网络时的基本数据结构。

这段代码是在准备使用MindSpore框架进行深度学习模型开发的前期准备代码,通过导入必要的模块和类以便后续进行模型设计和数据操作。

def network():
    model = nn.SequentialCell(       # 使用SequentialCell创建一个顺序模型
                nn.Flatten(),        # 添加一个Flatten层,用于将输入数据展平,通常用于从卷积层到全连接层的过渡
                nn.Dense(28*28, 512),# 添加第一个全连接(Dense)层,输入尺寸为28*28,输出尺寸为512
                nn.ReLU(),           # 添加一个ReLU激活层
                nn.Dense(512, 512),  # 添加第二个全连接(Dense)层,输入输出尺寸均为512
                nn.ReLU(),           # 添加另一个ReLU激活层
                nn.Dense(512, 10))   # 添加第三个全连接(Dense)层,输入尺寸为512,输出尺寸为10(假设是10分类问题)
    return model                      # 返回构建的模型

这段代码定义了一个函数network,其目的是构建一个简单的神经网络模型。这个模型使用了MindSpore的nn.SequentialCell来顺序地堆叠不同的层,创建一个顺序模型。

  1. nn.SequentialCell: 它是一个容器,用于依次添加不同的层。每一层的输出自动成为下一层的输入。这样可以非常方便地构建一个顺序执行的模型。
  2. nn.Flatten: 这是模型的第一层,作用是将输入数据展平。例如,如果输入数据是一个图像的二维数组(如MNIST数据集中的28x28像素图像),Flatten层会将其转换成一个一维数组,长度为784 (28*28)。这一步是必须的,因为接下来的全连接层需要一维的输入。
  3. nn.Dense: 这是全连接层,也称为线性层。它的工作原理是对输入进行线性变换(y = Ax + b),其中A是权重矩阵,b是偏置,x是输入。在这个模型中,第一个全连接层将输入的784个特征转换为512个特征,接着是另一个全连接层保持512个特征不变,最后一个全连接层将特征数量降低到10,通常这对应于分类任务中的类别数量。
  4. nn.ReLU: 这是一个非线性激活函数层,用ReLU(Rectified Linear Unit)激活函数。它的作用是增加模型的非线性,没有它模型只能学习输入和输出之间的线性关系。ReLU函数定义为f(x) = max(0, x),意味着如果输入是正数,就原样输出,如果是负数,则输出0。这有助于解决梯度消失问题并加速训练。

这段代码展示了使用MindSpore框架构建一个简单的全连接神经网络模型的过程,适用于诸如图像分类等简单任务。

保存和加载模型权重

保存模型使用save_checkpoint接口,传入网络和指定的保存路径:
要加载模型权重,需要先创建相同模型的实例,然后使用load_checkpointload_param_into_net方法加载参数。

model = network()  # 调用之前定义的network函数创建一个神经网络模型
mindspore.save_checkpoint(model, "model.ckpt")  # 将模型的参数保存到文件"model.ckpt"中
model = network()  # 再次调用network函数创建一个新的神经网络模型
param_dict = mindspore.load_checkpoint("model.ckpt")  # 从文件"model.ckpt"中加载模型的参数到一个字典中
param_not_load, _ = mindspore.load_param_into_net(model, param_dict)  # 将加载的参数字典应用到新的模型中,并返回未成功加载的参数列表
print(param_not_load)  # 打印未成功加载的参数列表

这段代码展示了如何使用MindSpore框架保存和加载神经网络模型的参数。

  1. mindspore.save_checkpoint: 这个函数用于将模型的参数保存到一个文件中。在这个例子中,它将model的参数保存到名为"model.ckpt"的文件中。
  2. mindspore.load_checkpoint: 这个函数用于从文件中加载模型的参数。它返回一个参数字典,包含了模型的所有参数。
  3. mindspore.load_param_into_net: 这个函数用于将加载的参数字典应用到一个新的模型实例中。它返回两个值,第一个是未成功加载的参数列表,第二个是成功加载的参数列表。在这个例子中,我们只关心未成功加载的参数列表。
  4. print(param_not_load): 打印未成功加载的参数列表。如果所有参数都成功加载,这个列表应该是空的。如果有参数未成功加载,这可能是因为新模型的结构与保存的模型结构不匹配,或者是因为某些参数名称在新的模型中不存在。

这段代码的主要目的是展示如何保存和恢复模型的状态,这在实际应用中非常有用,例如在训练过程中定期保存模型状态以防止数据丢失,或者在部署模型时加载预训练的参数。

保存和加载MindIR

除Checkpoint外,MindSpore提供了云侧(训练)和端侧(推理)统一的中间表示(Intermediate Representation,IR)。可使用export接口直接将模型保存为MindIR。

model = network()  # 调用之前定义的network函数创建一个神经网络模型
inputs = Tensor(np.ones([1, 1, 28, 28]).astype(np.float32))  # 创建一个大小为(1, 1, 28, 28)的张量,所有元素均为1,数据类型为float32
mindspore.export(model, inputs, file_name="model", file_format="MINDIR")  # 导出模型,指定输入张量、文件名和格式

解析:
这段代码展示了如何使用MindSpore将训练好的模型导出为指定的格式,以便在推理或部署时使用。

  1. Tensor(np.ones([1, 1, 28, 28]).astype(np.float32)):
    • np.ones([1, 1, 28, 28]):使用NumPy创建一个全为1的数组,形状为(1, 1, 28, 28)。这代表一个包含1个样本的批次,每个样本是1个通道的28x28像素的图像。
    • .astype(np.float32):将数组的数据类型转换为float32,因为深度学习模型通常要求输入数据为浮点型。
    • Tensor(...):将NumPy数组转换为MindSpore中的Tensor对象,这是MindSpore处理数据的基本数据结构。
  2. mindspore.export:
    • model:要导出的神经网络模型。
    • inputs:模型的输入张量,用于指定模型的输入形状和数据类型。
    • file_name="model":指定导出文件的名称为"model"。
    • file_format="MINDIR":指定导出文件的格式为MINDIR(MindSpore Intermediate Representation),这是MindSpore使用的一种中间表示格式,用于模型保存和部署。

通过这段代码,可以将一个训练好的模型导出为MINDIR格式文件。这种格式文件可以用于后续的模型推理或部署,方便将模型应用到生产环境中。

MindIR同时保存了Checkpoint和模型结构,因此需要定义输入Tensor来获取输入shape。
已有的MindIR模型可以方便地通过load接口加载,传入nn.GraphCell即可进行推理。
nn.GraphCell仅支持图模式。

mindspore.set_context(mode=mindspore.GRAPH_MODE)  # 将MindSpore的执行模式设置为图模式(GRAPH_MODE)

graph = mindspore.load("model.mindir")  # 从文件"model.mindir"中加载保存的模型图
model = nn.GraphCell(graph)  # 使用加载的模型图创建一个GraphCell实例
outputs = model(inputs)  # 通过传入输入张量inputs执行模型推理,获取输出
print(outputs.shape)  # 打印输出张量的形状

解析:
这段代码展示了如何在MindSpore中加载一个已保存的MINDIR格式模型,并使用它进行推理。

  1. mindspore.set_context(mode=mindspore.GRAPH_MODE):
    • 将MindSpore的执行模式设置为图模式(GRAPH_MODE)。MindSpore支持两种执行模式:图模式(GRAPH_MODE)和命令模式(PYNATIVE_MODE)。图模式会将整个计算图编译成一个静态图,从而优化执行速度和性能,适合于训练和推理。命令模式适合于调试和原型开发。
  2. mindspore.load(“model.mindir”):
    • 从文件"model.mindir"中加载之前导出的模型。mindspore.load函数会解析MINDIR文件并返回一个表示模型结构的图对象。
  3. nn.GraphCell(graph):
    • 使用加载的模型图创建一个GraphCell实例。GraphCell是MindSpore中的一种特殊的细胞类型,用于封装执行图,使其可以像普通的神经网络模型一样被调用。
  4. model(inputs):
    • 传入输入张量inputs进行模型推理,获取输出张量outputs。这一步实际执行了加载模型的前向计算。
  5. print(outputs.shape):
    • 打印输出张量的形状。这有助于确认模型的输出是否符合预期。

通过这段代码,可以将一个保存的MINDIR模型加载回来,并使用它进行推理,验证其输出。这在模型部署和推理阶段非常有用。

整体代码

#!/usr/bin/env python
# coding: utf-8

# In[1]:
import numpy as np  # 导入NumPy库,用于数值计算
import mindspore  # 导入MindSpore框架
from mindspore import nn  # 从MindSpore导入神经网络模块
from mindspore import Tensor  # 从MindSpore导入Tensor类

# In[2]:
def network():
    # 定义一个简单的神经网络模型
    model = nn.SequentialCell(
                nn.Flatten(),  # 将输入张量展平
                nn.Dense(28*28, 512),  # 全连接层,将展平后的输入映射到512维
                nn.ReLU(),  # ReLU激活函数
                nn.Dense(512, 512),  # 另一个全连接层
                nn.ReLU(),  # ReLU激活函数
                nn.Dense(512, 10))  # 最后一层全连接层,将输出映射到10维
    return model  # 返回定义的模型

# ## 保存和加载模型权重

# In[3]:
model = network()  # 创建神经网络模型
mindspore.save_checkpoint(model, "model.ckpt")  # 保存模型的权重到文件"model.ckpt"

# ## 加载模型权重

# In[4]:
model = network()  # 再次创建相同的神经网络模型
param_dict = mindspore.load_checkpoint("model.ckpt")  # 从文件"model.ckpt"加载模型权重
param_not_load, _ = mindspore.load_param_into_net(model, param_dict)  # 将加载的权重应用到模型中
print(param_not_load)  # 打印未被加载的参数列表

# ## 保存和加载MindIR

# In[5]:
model = network()  # 创建神经网络模型
inputs = Tensor(np.ones([1, 1, 28, 28]).astype(np.float32))  # 创建输入张量,形状为(1, 1, 28, 28),数据类型为float32
mindspore.export(model, inputs, file_name="model", file_format="MINDIR")  # 导出模型为MindIR格式文件

# In[6]:
mindspore.set_context(mode=mindspore.GRAPH_MODE)  # 设置MindSpore的执行模式为图模式

graph = mindspore.load("model.mindir")  # 加载MindIR格式的模型文件
model = nn.GraphCell(graph)  # 使用加载的模型图创建GraphCell实例
outputs = model(inputs)  # 传入输入张量进行推理,获取输出
print(outputs.shape)  # 打印输出张量的形状

解析:

  1. 导入必要的库
    • numpy 用于数值计算。
    • mindspore 框架及其相关模块用于神经网络的创建、训练和保存。
  2. 定义神经网络模型
    • 使用 nn.SequentialCell 创建一个简单的前馈神经网络,包含展平层、全连接层和ReLU激活函数。
  3. 保存和加载模型权重
    • mindspore.save_checkpoint:将模型的参数保存到一个Checkpoint文件中。
    • mindspore.load_checkpoint:从Checkpoint文件中加载模型的参数。
    • mindspore.load_param_into_net:将加载的参数应用到模型中,并返回未成功加载的参数列表。
  4. 保存和加载MindIR
    • mindspore.export:将模型及其结构导出为MindIR格式文件。这种格式同时保存模型结构和参数,以便在推理或部署时使用。
    • mindspore.load:加载MindIR格式的模型文件。
    • nn.GraphCell:创建一个GraphCell实例用于封装执行图,使其可以像普通的神经网络模型一样被调用进行推理。
  5. 推理执行
    • 设置MindSpore的执行模式为图模式(GRAPH_MODE),加载MindIR模型,并进行推理,最终打印输出张量的形状以验证模型的输出。

原文地址:https://blog.csdn.net/qq_43638033/article/details/140532520

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!