CNTK - 评估结果

  • 简述

    本章将解释如何测量 CNKT 中的模型性能。
  • 验证模型性能的策略

    在构建 ML 模型后,我们使用一组数据样本对其进行训练。由于这种训练,我们的 ML 模型学习并得出一些一般规则。当我们向模型提供新样本(即与训练时提供的不同样本)时,ML 模型的性能很重要。在这种情况下,模型的行为会有所不同。对这些新样本做出好的预测可能会更糟。
    但是该模型也必须适用于新样本,因为在生产环境中,我们将获得与用于训练目的的样本数据不同的输入。这就是原因,我们应该使用一组不同于我们用于训练目的的样本来验证 ML 模型。在这里,我们将讨论创建用于验证 NN 的数据集的两种不同技术。

    保留数据集

    它是创建数据集以验证 NN 的最简单方法之一。顾名思义,在这种方法中,我们将保留一组训练样本(比如 20%),并使用它来测试我们的 ML 模型的性能。下图显示了训练和验证样本之间的比率 -
    保留数据集
    保留数据集模型确保我们有足够的数据来训练我们的 ML 模型,同时我们将拥有合理数量的样本来获得对模型性能的良好测量。
    为了包含在训练集和测试集中,最好从主数据集中选择随机样本。它确保了训练集和测试集之间的均匀分布。
    以下是一个示例,其中我们使用scikit-learn库中的train_test_split函数生成自己的保留数据集。

    例子

    
    
    from sklearn.datasets import load_iris
    
    iris = load_iris()
    
    X = iris.data
    
    y = iris.target
    
    from sklearn.model_selection import train_test_split
    
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=1)
    
    # Here above test_size = 0.2 represents that we provided 20% of the data as test data.
    
    from sklearn.neighbors import KNeighborsClassifier
    
    from sklearn import metrics
    
    classifier_knn = KNeighborsClassifier(n_neighbors=3)
    
    classifier_knn.fit(X_train, y_train)
    
    y_pred = classifier_knn.predict(X_test)
    
    # Providing sample data and the model will make prediction out of that data
    
    sample = [[5, 5, 3, 2], [2, 4, 3, 5]]
    
    preds = classifier_knn.predict(sample)
    
    pred_species = [iris.target_names[p] for p in preds] print("Predictions:", pred_species)
    
    

    输出

    
    
    Predictions: ['versicolor', 'virginica']
    
    
    在使用 CNTK 时,我们需要在每次训练模型时随机化数据集的顺序,因为 -
    • 深度学习算法受随机数生成器的影响很大。
    • 我们在训练期间向 NN 提供样本的顺序会极大地影响其性能。
    使用保留数据集技术的主要缺点是它不可靠,因为有时我们会得到非常好的结果,但有时会得到糟糕的结果。
  • K折交叉验证

    为了使我们的 ML 模型更可靠,有一种称为 K-fold 交叉验证的技术。在本质上,K-fold 交叉验证技术与之前的技术相同,但它会重复几次——通常大约 5 到 10 次。下图代表其概念 -
    K折交叉验证

    K折交叉验证的工作

    K-fold 交叉验证的工作可以通过以下步骤来理解 -
    第 1 步- 与分发数据集技术一样,在 K 折交叉验证技术中,首先我们需要将数据集拆分为训练集和测试集。理想情况下,该比率为 80-20,即 80% 的训练集和 20% 的测试集。
    第 2 步 - 接下来,我们需要使用训练集训练我们的模型。
    第 3 步- 最后,我们将使用测试集来衡量我们模型的性能。保留数据集技术和 k-cross 验证技术之间的唯一区别是,上述过程通常重复 5 到 10 次,最后计算所有性能指标的平均值。该平均值将是最终的性能指标。
    让我们看一个小数据集的例子 -

    例子

    
    
    from numpy import array
    
    from sklearn.model_selection import KFold
    
    data = array([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0])
    
    kfold = KFold(5, True, 1)
    
    for train, test in kfold.split(data):
    
       print('train: %s, test: %s' % (data[train],(data[test]))
    
    

    输出

    
    
    train: [0.1 0.2 0.4 0.5 0.6 0.7 0.8 0.9], test: [0.3 1. ]
    
    train: [0.1 0.2 0.3 0.4 0.6 0.8 0.9 1. ], test: [0.5 0.7]
    
    train: [0.2 0.3 0.5 0.6 0.7 0.8 0.9 1. ], test: [0.1 0.4]
    
    train: [0.1 0.3 0.4 0.5 0.6 0.7 0.9 1. ], test: [0.2 0.8]
    
    train: [0.1 0.2 0.3 0.4 0.5 0.7 0.8 1. ], test: [0.6 0.9]
    
    
    正如我们所看到的,由于使用了更真实的训练和测试场景,k-fold 交叉验证技术为我们提供了更稳定的性能测量,但不利的一面是,验证深度学习模型需要大量时间。
    CNTK 不支持 k-cross 验证,因此我们需要编写自己的脚本来执行此操作。
  • 检测欠拟合和过拟合

    无论是使用 Hand-out 数据集还是 k 折交叉验证技术,我们都会发现用于训练的数据集和用于验证的数据集的指标输出会有所不同。

    检测过拟合

    这种称为过拟合的现象是我们的 ML 模型对训练数据进行了非常好的建模,但在测试数据上表现不佳,即无法预测测试数据。
    当 ML 模型从训练数据中学习特定模式和噪声的程度达到一定程度时,就会发生这种情况,从而对该模型从训练数据泛化到新数据(即未见数据)的能力产生负面影响。在这里,噪声是数据集中不相关的信息或随机性。
    以下是我们可以检测模型是否过拟合的两种方法 -
    • 过拟合模型将在我们用于训练的相同样本上表现良好,但在新样本上表现非常糟糕,即与训练不同的样本。
    • 如果测试集上的指标低于我们在训练集上使用的相同指标,则模型在验证期间过拟合。

    检测欠拟合

    我们的机器学习中可能出现的另一种情况是欠拟合。在这种情况下,我们的 ML 模型没有很好地对训练数据进行建模并且无法预测有用的输出。当我们开始训练第一个 epoch 时,我们的模型会欠拟合,但随着训练的进行,欠拟合会减少。
    检测我们的模型是否欠拟合的方法之一是查看训练集和测试集的指标。如果测试集上的指标高于训练集上的指标,我们的模型将欠拟合。