MindSpore - 自定义损失函数 和 多输入参数的线性拟合

该文介绍了如何使用MindSpore构建一个拟合y'+1=1*x1+2*x2=y的神经网络模型,其中涉及自定义损失函数以处理假目标值+1操作。通过GeneratorDataset生成数据,利用Momentum优化器训练模型,最终实现网络输出接近真实目标值。代码示例展示了整个流程。
摘要由CSDN通过智能技术生成

在这里插入图片描述

自定义损失函数 和 多输入参数的 线性拟合

本文将基于 MindSpore 搭建一个 拟合 y ′ + 1 = 1 ∗ x 1 + 2 ∗ x 2 = y y' + 1 = 1 * x_1 + 2 * x_2 = y y+1=1x1+2x2=y 函数的算法。其中 y y y 是神经网络正向传播应该输出的值,也就是真正的目标值。而 y ′ y' y 是假的目标值,需要进行 + 1 +1 +1 操作才能得到真的目标值。

也就是要自定义损失函数,在损失函数中,需要对输入的临时目标值进行处理,也就是进行 + 1 +1 +1 操作,才得到真正的目标值。

用假的目标值训练网络,最终,网络的输出值要接近真正的目标值。

完整代码 和 注释 如下:

import numpy as np
from mindspore import dataset as ds
from mindspore.common.initializer import Normal
from mindspore import Model, Tensor, context, nn, set_seed, ops
import mindspore as ms
context.set_context(mode=context.GRAPH_MODE, device_target="CPU") # 设置静态图模式,CPU 支持此模式
set_seed(1)

class add_Loss(nn.Cell): # 自定义损失函数,参考链接:
    # https://www.mindspore.cn/docs/programming_guide/zh-CN/r1.6/loss.html#%E5%AE%9A%E4%B9%89%E6%8D%9F%E5%A4%B1%E5%87%BD%E6%95%B0
    def __init__(self):
        super(add_Loss, self).__init__()
        self.add = ops.Add()
        self.square = ops.Square()
        self.reduce_mean = ops.ReduceMean()
        
    def construct(self, x, y_): # 第一个参数 x 为神经网络前向输出值,第二个参数为 假的目标值。
        y = self.add(y_, 1.)  # 注意, 此处的运算操并非必须为 ops 操作,才能自动计算梯度。正常的计算也可以,比如 下面注释掉的 + 和 **2。
        loss = self.square(x - y)
        
        # y = y_ + 1.
        # loss = (x - y)**2
        
        loss = self.reduce_mean(loss)
        return loss

def get_data(num, w_1=1.0, w_2=2.0): 
    for _ in range(num):
        x_1 = np.random.uniform(-10.0, 10.0)
        x_2 = np.random.uniform(-10.0, 10.0)
        y_ = x_1 * w_1 + x_2 * w_2 - 1
        yield np.array([x_1, x_2]).astype(np.float32), np.array([y_]).astype(np.float32) # MindSpore 默认的计算精度为 Float32,所以也要匹配。
        # 用 yield 函数生成可迭代的生成器,当 num 很大时,可很有效的减小内存占用
        
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)

class LinearNet(nn.Cell):
    def __init__(self):
        super(LinearNet, self).__init__()
        self.fc = nn.Dense(2, 1) # 全连接层

    def construct(self, x): # 必须要有这个函数,MindSpore 对 construct 接口有一定约束
        x = self.fc(x)
        return x
    
net = LinearNet()

net_loss = add_Loss() # 采用自定义的损失函数
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)

# 测试一下
print(model.predict(Tensor([[1., 2.]], dtype=ms.float32))) # 最终输出结果为 [[4.996882]] 恰为想要的 1*1 + 2*2 = 5 的结果

[[4.996882]]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值