文档反馈

问题文档片段

问题文档片段包含公式时,显示为空格。

提交类型
issue

有点复杂...

找人问问吧。

PR

小问题,全程线上修改...

一键搞定!

请选择提交类型

问题类型
规范和低错类

- 规范和低错类:

- 错别字或拼写错误,标点符号使用错误、公式错误或显示异常。

- 链接错误、空单元格、格式错误。

- 英文中包含中文字符。

- 界面和描述不一致,但不影响操作。

- 表述不通顺,但不影响理解。

- 版本号不匹配:如软件包名称、界面版本号。

易用性

- 易用性:

- 关键步骤错误或缺失,无法指导用户完成任务。

- 缺少主要功能描述、关键词解释、必要前提条件、注意事项等。

- 描述内容存在歧义指代不明、上下文矛盾。

- 逻辑不清晰,该分类、分项、分步骤的没有给出。

正确性

- 正确性:

- 技术原理、功能、支持平台、参数类型、异常报错等描述和软件实现不一致。

- 原理图、架构图等存在错误。

- 命令、命令参数等错误。

- 代码片段错误。

- 命令无法完成对应功能。

- 界面错误,无法指导操作。

- 代码样例运行报错、运行结果不符。

风险提示

- 风险提示:

- 对重要数据或系统存在风险的操作,缺少安全提示。

内容合规

- 内容合规:

- 违反法律法规,涉及政治、领土主权等敏感词。

- 内容侵权。

问题描述

请勾选同意隐私声明

下载Notebook下载样例代码查看源文件

评价指标 Metrics

当训练任务结束,常常需要评价函数(Metrics)来评估模型的好坏。不同的训练任务往往需要不同的Metrics函数。例如,对于二分类问题,常用的评价指标有precision(准确率)、recall(召回率)等,而对于多分类任务,可使用宏平均(Macro)和微平均(Micro)来评估。

MindSpore提供了大部分常见任务的评价函数,如AccuracyPrecisionMAEMSE等,由于MindSpore提供的评价函数无法满足所有任务的需求,很多情况下用户需要针对具体的任务自定义Metrics来评估训练的模型。

本章主要介绍如何自定义Metrics以及如何在mindspore.train.Model中使用Metrics。

详情可参考评价指标

自定义Metrics

自定义Metrics函数需要继承mindspore.train.Metric父类,并重新实现父类中的clear方法、update方法和eval方法。

  • clear:初始化相关的内部参数。

  • update:接收网络预测输出和标签,计算误差,每次step后并更新内部评估结果。

  • eval:计算最终评估结果,在每次epoch结束后计算最终的评估结果。

平均绝对误差(MAE)算法如式(1)所示:

(1)MAE=1ni=1n|yprediyi|

下面以简单的MAE算法为例,介绍clearupdateeval三个函数及其使用方法。

[1]:
import numpy as np
import mindspore as ms

class MyMAE(ms.train.Metric):
    def __init__(self):
        super(MyMAE, self).__init__()
        self.clear()

    def clear(self):
        """初始化变量_abs_error_sum和_samples_num"""
        self._abs_error_sum = 0  # 保存误差和
        self._samples_num = 0    # 累计数据量

    def update(self, *inputs):
        """更新_abs_error_sum和_samples_num"""
        y_pred = inputs[0].asnumpy()
        y = inputs[1].asnumpy()

        # 计算预测值与真实值的绝对误差
        abs_error_sum = np.abs(y - y_pred)
        self._abs_error_sum += abs_error_sum.sum()

        # 样本的总数
        self._samples_num += y.shape[0]

    def eval(self):
        """计算最终评估结果"""
        return self._abs_error_sum / self._samples_num

# 网络有两个输出
y_pred = ms.Tensor(np.array([[0.1, 0.2, 0.6, 0.9], [0.1, 0.2, 0.6, 0.9]]), ms.float32)
y = ms.Tensor(np.array([[0.1, 0.25, 0.7, 0.9], [0.1, 0.25, 0.7, 0.9]]), ms.float32)

error = MyMAE()
error.clear()
error.update(y_pred, y)
result = error.eval()
print(result)
0.1499999612569809

模型训练中使用Metrics

mindspore.train.Model是用于训练和评估的高层API,可以将自定义或MindSpore已有的Metrics作为参数传入,Model能够自动调用传入的Metrics进行评估。

在网络模型训练后,需要使用评价指标,来评估网络模型的训练效果,因此在演示具体代码之前首先简单拟定数据集,对数据集进行加载和定义一个简单的线性回归网络模型:

(2)f(x)=wx+b
[2]:
import numpy as np
from mindspore import dataset as ds

def get_data(num, w=2.0, b=3.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)

def create_dataset(num_data, batch_size=16):
    """加载数据集"""
    dataset = ds.GeneratorDataset(list(get_data(num_data)), column_names=['data', 'label'])
    dataset = dataset.batch(batch_size)
    return dataset

使用内置评价指标

使用MindSpore内置的Metrics作为参数传入Model时,Metrics可以定义为一个字典类型,字典的key值为字符串类型,字典的value值为MindSpore内置的评价指标,如下示例使用train.Accuracy计算分类的准确率。

[3]:
import mindspore.nn as nn
from mindspore.train import Model, MAE, LossMonitor

net = nn.Dense(1, 1)
loss_fn = nn.L1Loss()
optimizer = nn.Momentum(net.trainable_params(), learning_rate=0.005, momentum=0.9)

# 定义model,使用内置的Accuracy函数
model = Model(net, loss_fn, optimizer, metrics={"MAE": MAE()})

train_dataset = create_dataset(num_data=160)
eval_dataset = create_dataset(num_data=160)
train_dataset_size = train_dataset.get_dataset_size()

model.fit(10, train_dataset, eval_dataset, callbacks=LossMonitor(train_dataset_size))
epoch: 1 step: 10, loss is 5.908090114593506
Eval result: epoch 1, metrics: {'MAE': 5.1329233884811405}
epoch: 2 step: 10, loss is 3.9280264377593994
Eval result: epoch 2, metrics: {'MAE': 3.0886757612228393}
epoch: 3 step: 10, loss is 2.9104671478271484
Eval result: epoch 3, metrics: {'MAE': 2.461756193637848}
epoch: 4 step: 10, loss is 1.8725224733352661
Eval result: epoch 4, metrics: {'MAE': 2.11311993598938}
epoch: 5 step: 10, loss is 2.1637942790985107
Eval result: epoch 5, metrics: {'MAE': 1.6749439239501953}
epoch: 6 step: 10, loss is 1.3848766088485718
Eval result: epoch 6, metrics: {'MAE': 1.317658966779709}
epoch: 7 step: 10, loss is 1.052016258239746
Eval result: epoch 7, metrics: {'MAE': 1.043285644054413}
epoch: 8 step: 10, loss is 1.1781564950942993
Eval result: epoch 8, metrics: {'MAE': 0.8706761479377747}
epoch: 9 step: 10, loss is 0.8200418949127197
Eval result: epoch 9, metrics: {'MAE': 0.7817940771579742}
epoch: 10 step: 10, loss is 0.7065591812133789
Eval result: epoch 10, metrics: {'MAE': 0.7885207533836365}

使用自定义评价指标

如下示例在Model中传入上述自定义的评估指标MAE(),将验证数据集传入model.fit()接口边训练边验证。

验证结果为一个字典类型,验证结果的key值与metrics的key值相同,验证结果的value值为预测值与实际值的平均绝对误差。

[4]:
train_dataset = create_dataset(num_data=160)
eval_dataset = create_dataset(num_data=160)

model = Model(net, loss_fn, optimizer, metrics={"MAE": MyMAE()})

# 定义model,将自定义metrics函数MAE传入Model中
model.fit(10, train_dataset, eval_dataset, callbacks=LossMonitor(train_dataset_size))
epoch: 1 step: 10, loss is 0.7992362380027771
Eval result: epoch 1, metrics: {'MAE': 0.8640150725841522}
epoch: 2 step: 10, loss is 0.8377518653869629
Eval result: epoch 2, metrics: {'MAE': 0.9286439001560212}
epoch: 3 step: 10, loss is 0.894376277923584
Eval result: epoch 3, metrics: {'MAE': 0.8669328391551971}
epoch: 4 step: 10, loss is 0.8098692893981934
Eval result: epoch 4, metrics: {'MAE': 0.9018074989318847}
epoch: 5 step: 10, loss is 0.8556416630744934
Eval result: epoch 5, metrics: {'MAE': 0.8721640467643738}
epoch: 6 step: 10, loss is 0.8508825302124023
Eval result: epoch 6, metrics: {'MAE': 0.8601282179355622}
epoch: 7 step: 10, loss is 0.7443522810935974
Eval result: epoch 7, metrics: {'MAE': 0.9004024684429168}
epoch: 8 step: 10, loss is 0.7394096851348877
Eval result: epoch 8, metrics: {'MAE': 0.9380556881427765}
epoch: 9 step: 10, loss is 0.7989674210548401
Eval result: epoch 9, metrics: {'MAE': 0.8629323005676269}
epoch: 10 step: 10, loss is 0.6581473350524902
Eval result: epoch 10, metrics: {'MAE': 0.9144346475601196}