今天学习-入门教程【保存和加载模型】以及【静态图加速】
capture captured_output
实验环境已经预装了mindspore==2.2.14,如需更换mindspore版本,可更改下面mindspore的版本号
!pip uninstall mindspore -y
!pip install -i https://pypi.mirrors.ustc.edu.cn/simple mindspore==2.2.14
三个全连接层,每层之后跟着一个ReLU激活函数。
nn.Flatten():这是一个层,用于将输入数据的形状从高维张量(例如图片的形状通常是(batch_size, height, width, channels))转换成二维张量(batch_size, features)。
nn.Dense(28*28, 512):这是一个全连接层,它接受28*28个输入(即MNIST图像的大小),并输出到512个神经元。
nn.ReLU():这是一个激活函数层,ReLU激活函数定义为f(x) = max(0, x),即负值输入会被转化为零。
第二个nn.Dense(512, 512)和nn.ReLU():这是第二个全连接层和其后的ReLU激活函数,它们进一步处理数据。
nn.Dense(512, 10):这是最后一个全连接层,它接受来自前一个层的512个输入,并输出10个值,这通常代表10个类别的概率分布(在MNIST数据集中,就是0到9的数字)。
import numpy as np
import mindspore
from mindspore import nn
from mindspore import Tensor
def network():
model = nn.SequentialCell(
nn.Flatten(),
nn.Dense(28*28, 512),
nn.ReLU(),
nn.Dense(512, 512),
nn.ReLU(),
nn.Dense(512, 10))
return model
保存和加载模型权重
model = network()
mindspore.save_checkpoint(model, "model.ckpt")
要加载模型权重,需要先创建相同模型的实例,然后使用load_checkpoint和load_param_into_net方法加载参数。
model = network()
param_dict = mindspore.load_checkpoint("model.ckpt")
param_not_load, _ = mindspore.load_param_into_net(model, param_dict)
print(param_not_load)
[]
保存和加载MindIR
model = network()
inputs = Tensor(np.ones([1, 1, 28, 28]).astype(np.float32))
mindspore.export(model, inputs, file_name="model", file_format="MINDIR")
mindspore.set_context(mode=mindspore.GRAPH_MODE)
graph = mindspore.load("model.mindir")
model = nn.GraphCell(graph)
outputs = model(inputs)
print(outputs.shape)
(1, 10)
静态图加速
%%capture captured_output
实验环境已经预装了mindspore==2.2.14,如需更换mindspore版本,可更改下面mindspore的版本号
!pip uninstall mindspore -y
!pip install -i https://pypi.mirrors.ustc.edu.cn/simple mindspore==2.2.14
import numpy as np
import mindspore as ms
from mindspore import nn, Tensor
ms.set_context(mode=ms.PYNATIVE_MODE) 使用set_context进行动态图模式的配置
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()
input = Tensor(np.ones([64, 1, 28, 28]).astype(np.float32))
output = model(input)
print(output)
静态图模式
静态图的特点是将计算图的构建和实际计算分开
手动控制框架采用静态图模式,可以通过以下代码进行网络构建:
import numpy as np
import mindspore as ms
from mindspore import nn, Tensor
ms.set_context(mode=ms.GRAPH_MODE) 使用set_context进行运行静态图模式的配置
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()
input = Tensor(np.ones([64, 1, 28, 28]).astype(np.float32))
output = model(input)
print(output)
jit的使用示例:需要对Tensor的某些运算进行编译加速时,可以在其定义的函数上使用jit修饰器,在调用该函数时,该模块自动被编译为静态图
import numpy as np
import mindspore as ms
from mindspore import nn, Tensor
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
input = Tensor(np.ones([64, 1, 28, 28]).astype(np.float32))
使用ms.jit装饰器,使被装饰的函数以静态图模式运行
def run(x):
model = Network()
return model(x)
output = run(input)
print(output)
也可以用函数变换方式调用jit
import numpy as np
import mindspore as ms
from mindspore import nn, Tensor
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
input = Tensor(np.ones([64, 1, 28, 28]).astype(np.float32))
def run(x):
model = Network()
return model(x)
run_with_jit = ms.jit(run) 通过调用jit将函数转换为以静态图方式执行
output = run(input)
print(output)
需要对神经网络的某部分进行加速时,可以直接在construct方法上使用jit修饰器,在调用实例化对象时,该模块自动被编译为静态图
import numpy as np
import mindspore as ms
from mindspore import nn, Tensor
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)
)
@ms.jit 使用ms.jit装饰器,使被装饰的函数以静态图模式运行
def construct(self, x):
x = self.flatten(x)
logits = self.dense_relu_sequential(x)
return logits
input = Tensor(np.ones([64, 1, 28, 28]).astype(np.float32))
model = Network()
output = model(input)
print(output)
[[-0.04049895 0.11536377 0.08095516 0.00391916 0.01643538 0.16893423
-0.09891538 -0.06973983 0.05562657 -0.1653231 ]
基于contex的开启方式
import numpy as np
import mindspore as ms
from mindspore import nn, Tensor
ms.set_context(mode=ms.GRAPH_MODE)
使用set_context进行运行静态图模式的配置
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()
input = Tensor(np.ones([64, 1, 28, 28]).astype(np.float32))
output = model(input)
print(output)
[[-0.17163241 0.06061254 -0.06128727 0.13402852 -0.05499288 -0.04404625
0.05912814 -0.05384313 0.03543703 -0.06354527]
[-0.17163241 0.06061254 -0.06128727 0.13402852 -0.05499288 -0.04404625
0.05912814 -0.05384313 0.03543703 -0.06354527]
import datetime
current_time = datetime.datetime.now()
print("Current time:", current_time)
print("littlesujin")
Current time: 2024-06-27 00:22:37.645485
littlesujin
总结
学习了使用MindSpore框架进行神经网络构建、保存和加载模型权重、MindIR的导出和加载、动态图与静态图模式的配置、以及使用JIT编译加速Tensor操作的方法,包括:
神经网络构建
- 使用了三个全连接层(
nn.Dense
),每层后接一个ReLU激活函数(nn.ReLU
)。 - 输入数据通过
nn.Flatten
层从四维张量转换成二维张量。 - 第一个全连接层将MNIST图像的28*28个输入神经元连接到512个输出神经元。
- 第二个全连接层也是将512个输入神经元连接到512个输出神经元。
- 最后一个全连接层将512个输入神经元转换为10个输出值,代表10个类别的概率分布。
模型保存和加载
- 定义了一个
network
函数,返回一个Sequential模型。 - 使用
mindspore.save_checkpoint
保存模型权重。 - 使用
mindspore.load_checkpoint
和mindspore.load_param_into_net
加载模型权重。
MindIR导出和加载
- 使用
mindspore.export
导出模型为MindIR格式。 - 加载MindIR模型,并使用
nn.GraphCell
包装加载的图执行推理。
实验环境配置
- 提供了更换MindSpore版本的pip命令。
- 使用
mindspore.set_context
配置为动态图模式(ms.PYNATIVE_MODE
)或静态图模式(ms.GRAPH_MODE
)。
动态图和静态图模式
- 展示了如何在动态图和静态图模式下构建和执行神经网络。
- 静态图模式下,计算图的构建和执行是分开的。
JIT编译
- 使用
ms.jit
装饰器将函数转换为静态图执行,以加速Tensor的某些操作。
网络部分加速
- 可以在
construct
方法上使用ms.jit
装饰器,加速神经网络的某部分。
基于Context的开启方式
- 展示了如何使用
set_context
配置MindSpore运行在静态图模式下。
几个概念的理解
- 动态图:边想边做的烹饪方式,灵活但可能不够高效。
- 静态图:按照食谱做菜,事先规划好步骤,执行更高效但缺乏灵活性
- JIT编译:在深度学习框架中,使用JIT编译可以加速模型的执行,特别是在使用静态图模式时,JIT编译可以在执行前对计算图进行进一步的优化,从而提高模型运行的效率。这就像是在一场精心准备的演出中,演员们还保留了一些即兴的空间,以确保表演的最佳效果。
- Context开启:就像戏剧开幕前的最后准备,确保所有元素都已就绪,为即将开始的表演创造最佳条件。