此处,以线性函数拟合为例,演示如何搭建和训练网络。 因涉及到自定义数据集、网络搭建与训练,本文档可为用 MindSpore 搭建机器学习算法做简单入门指导。更多内容请参考MindSpore官方教程:简单线性函数拟合。
待拟合的目标函数为: f ( x ) = 2 x + 1. f(x)=2x+1. f(x)=2x+1.
而用于训练和测试的数据点定义为 y = 2 x + 1 + n o i s e , y=2x+1+noise, y=2x+1+noise, 其中 n o i s e noise noise 满足 0 均值的正态分布。
导入依赖项:
import time
import numpy as np
from IPython import display
import matplotlib.pyplot as plt
from mindspore import dataset as ds
from mindspore.train.callback import Callback
from mindspore.common.initializer import Normal
from mindspore import Model, Tensor, context, nn
context.set_context(mode=context.GRAPH_MODE, device_target="CPU") # 设置为静态图模式,CPU支持此模式。
定义数据集生成函数 get_data()
:用于生成训练数据集和测试数据集。
def get_data(num, w=2.0, b=1.0):
for _ in range(num):
x = np.random.uniform(-10.0, 10.0)
noise = np.random.normal(0, 1)
y = x * w + b + noise
yield np.array([x]).astype(np.float32), np.array([y]).astype(np.float32)
# 用 yield 函数生成可迭代的生成器,当 num 很大时,可很有效的减小内存占用
用 get_data()
可生成训练数据,此处对数据类型进行展示:
eval_data = list(get_data(num))
#形如 [(np.array([x1]),np.array([y1]),
# (np.array([x2]),np.array([y2]),
# ...)]
定义数据集增强函数:
def create_dataset(num_data, batch_size=16, repeat_size=1):
input_data = ds.GeneratorDataset(list(get_data(num_data)), column_names=['data', 'label'])
# GeneratorDataset 将生成的数据转换为 MindSpore 的数据集,并且将生成的数据的 x,y 值存入到 data 和 label 的数组中。
input_data = input_data.batch(batch_size)
# 将 batch_size 个数据组合成一个 batch,则一共有 num_data/batch_size 个 batch。
input_data = input_data.repeat(repeat_size) # 将数据集数量倍增。非必须步骤。
return input_data
使用数据集增强函数生成训练数据,并查看训练数据的格式:
data_number = 1600
batch_number = 16
repeat_number = 1
ds_train = create_dataset(data_number, batch_size=batch_number, repeat_size=repeat_number)
print("The dataset size of ds_train:", ds_train.get_dataset_size()) # 返回一个训练回合下的 batch 数目
# dict_datasets = next(ds_train.create_dict_iterator()) # next() 返回迭代器的下一个项目
# # create_dict_iterator:Create an iterator over the dataset. The data retrieved will be a dictionary datatype.
# # dict_datasets 是一个 batch 的数据
print(dict_datasets.keys())
print("The x label value shape:", dict_datasets["data"].shape)
print("The y label value shape:", dict_datasets["label"].shape)
The dataset size of ds_train: 100
dict_keys(['data', 'label'])
The x label value shape: (16, 1)
The y label value shape: (16, 1)
定义训练网络:
class LinearNet(nn.Cell):
def __init__(self):
super(LinearNet, self).__init__()
self.fc = nn.Dense(1, 1, Normal(0.02), Normal(0.02)) # 全连接层
def construct(self, x): # 必须要有这个函数,MindSpore 对 construct 接口有一定约束
x = self.fc(x)
return x
查看刚初始化时的模型参数:
net = LinearNet()
model_params = net.trainable_params()
for param in model_params:
print(param, param.asnumpy())
Parameter (name=fc.weight, shape=(1, 1), dtype=Float32, requires_grad=True) [[-0.00981932]]
Parameter (name=fc.bias, shape=(1,), dtype=Float32, requires_grad=True) [-0.00863762]
装配神经网络并执行训练:
net = LinearNet()
net_loss = nn.loss.MSELoss() # 损失函数
opt = nn.Momentum(net.trainable_params(), learning_rate=0.005, momentum=0.9) # 优化器
model = Model(net, net_loss, opt)
model.train(1, ds_train, dataset_sink_mode=False)
# dataset_sink_mode 数据集下沉模式,支持 Ascend、GPU 计算平台,本例为 CPU 计算平台设置为 False
打印最终训练好的参数:
for net_param in net.trainable_params():
print(net_param, net_param.asnumpy())
Parameter (name=fc.weight, shape=(1, 1), dtype=Float32, requires_grad=True) [[2.0374265]]
Parameter (name=fc.bias, shape=(1,), dtype=Float32, requires_grad=True) [1.0209452]