Scikit-learn 的 MLPClassifier:随机学习策略

Machine LearningMachine LearningBeginner
立即练习

This tutorial is from open-source community. Access the source code

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

本实验将指导你使用 Scikit-learn 的 MLPClassifier 来比较不同随机学习策略(包括随机梯度下降(SGD)和 Adam)的性能。MLPClassifier 是一个神经网络分类器,它使用反向传播来优化网络权重。本实验的目的是展示不同的随机学习策略如何影响 MLPClassifier 的训练损失曲线。我们将使用几个小数据集进行这个示例,尽管这些示例中显示的一般趋势似乎也适用于更大的数据集。

虚拟机使用提示

虚拟机启动完成后,点击左上角切换到“笔记本”标签,以访问 Jupyter Notebook 进行练习。

有时,你可能需要等待几秒钟让 Jupyter Notebook 完成加载。由于 Jupyter Notebook 的限制,操作验证无法自动化。

如果你在学习过程中遇到问题,可以随时向 Labby 提问。课程结束后提供反馈,我们会及时为你解决问题。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL sklearn(("Sklearn")) -.-> sklearn/CoreModelsandAlgorithmsGroup(["Core Models and Algorithms"]) sklearn(("Sklearn")) -.-> sklearn/DataPreprocessingandFeatureEngineeringGroup(["Data Preprocessing and Feature Engineering"]) sklearn(("Sklearn")) -.-> sklearn/UtilitiesandDatasetsGroup(["Utilities and Datasets"]) ml(("Machine Learning")) -.-> ml/FrameworkandSoftwareGroup(["Framework and Software"]) sklearn/CoreModelsandAlgorithmsGroup -.-> sklearn/neural_network("Neural Network Models") sklearn/DataPreprocessingandFeatureEngineeringGroup -.-> sklearn/preprocessing("Preprocessing and Normalization") sklearn/UtilitiesandDatasetsGroup -.-> sklearn/exceptions("Exceptions and Warnings") ml/FrameworkandSoftwareGroup -.-> ml/sklearn("scikit-learn") subgraph Lab Skills sklearn/neural_network -.-> lab-49215{{"Scikit-learn 的 MLPClassifier:随机学习策略"}} sklearn/preprocessing -.-> lab-49215{{"Scikit-learn 的 MLPClassifier:随机学习策略"}} sklearn/exceptions -.-> lab-49215{{"Scikit-learn 的 MLPClassifier:随机学习策略"}} ml/sklearn -.-> lab-49215{{"Scikit-learn 的 MLPClassifier:随机学习策略"}} end

导入必要的库

首先,我们需要导入必要的库,包括 MLPClassifier、MinMaxScaler、datasets 和 matplotlib.pyplot。我们还将导入 ConvergenceWarning 以在训练期间忽略收敛警告。

import warnings

import matplotlib.pyplot as plt

from sklearn.neural_network import MLPClassifier
from sklearn.preprocessing import MinMaxScaler
from sklearn import datasets
from sklearn.exceptions import ConvergenceWarning

定义不同的学习策略

接下来,我们需要定义想要比较的不同学习策略。我们将定义几种不同的学习率调度和动量参数,包括恒定学习率、带动量的恒定学习率、带 Nesterov 动量的恒定学习率、逆缩放学习率、带动量的逆缩放学习率、带 Nesterov 动量的逆缩放学习率以及 Adam。我们还将定义标签和绘图参数,以便稍后在绘图中使用。

## 不同的学习率调度和动量参数
params = [
    {
        "solver": "sgd",
        "learning_rate": "constant",
        "momentum": 0,
        "learning_rate_init": 0.2,
    },
    {
        "solver": "sgd",
        "learning_rate": "constant",
        "momentum": 0.9,
        "nesterovs_momentum": False,
        "learning_rate_init": 0.2,
    },
    {
        "solver": "sgd",
        "learning_rate": "constant",
        "momentum": 0.9,
        "nesterovs_momentum": True,
        "learning_rate_init": 0.2,
    },
    {
        "solver": "sgd",
        "learning_rate": "invscaling",
        "momentum": 0,
        "learning_rate_init": 0.2,
    },
    {
        "solver": "sgd",
        "learning_rate": "invscaling",
        "momentum": 0.9,
        "nesterovs_momentum": True,
        "learning_rate_init": 0.2,
    },
    {
        "solver": "sgd",
        "learning_rate": "invscaling",
        "momentum": 0.9,
        "nesterovs_momentum": False,
        "learning_rate_init": 0.2,
    },
    {"solver": "adam", "learning_rate_init": 0.01},
]

labels = [
    "恒定学习率",
    "带动量的恒定学习率",
    "带 Nesterov 动量的恒定学习率",
    "逆缩放学习率",
    "带动量的逆缩放学习率",
    "带 Nesterov 动量的逆缩放学习率",
    "Adam",
]

plot_args = [
    {"c": "红色", "linestyle": "-"},
    {"c": "绿色", "linestyle": "-"},
    {"c": "蓝色", "linestyle": "-"},
    {"c": "红色", "linestyle": "--"},
    {"c": "绿色", "linestyle": "--"},
    {"c": "蓝色", "linestyle": "--"},
    {"c": "黑色", "linestyle": "-"},
]

定义一个绘制学习曲线的函数

接下来,我们需要定义一个函数,该函数将为每个数据集上的每种学习策略绘制学习曲线。该函数接受数据集(X,y)、要绘制的轴以及数据集的名称。我们将使用 MinMaxScaler 对数据进行缩放,并使用 MLPClassifier 训练神经网络。我们将使用每种学习策略训练网络,忽略收敛警告,并在同一图上为每种策略绘制学习曲线。

def plot_on_dataset(X, y, ax, name):
    ## 对于每个数据集,绘制每种学习策略的学习情况
    print("\n在数据集 %s 上进行学习" % name)
    ax.set_title(name)

    X = MinMaxScaler().fit_transform(X)
    mlps = []
    if name == "digits":
        ## digits 数据集较大,但收敛相当快
        max_iter = 15
    else:
        max_iter = 400

    for label, param in zip(labels, params):
        print("训练:%s" % label)
        mlp = MLPClassifier(random_state=0, max_iter=max_iter, **param)

        ## 从图中可以看出,一些参数组合不会收敛,因此在这里被忽略
        with warnings.catch_warnings():
            warnings.filterwarnings(
                "ignore", category=ConvergenceWarning, module="sklearn"
            )
            mlp.fit(X, y)

        mlps.append(mlp)
        print("训练集得分:%f" % mlp.score(X, y))
        print("训练集损失:%f" % mlp.loss_)
    for mlp, label, args in zip(mlps, labels, plot_args):
        ax.plot(mlp.loss_curve_, label=label, **args)

加载或生成小型数据集

现在,我们需要加载或生成用于此示例的小型数据集。我们将使用鸢尾花数据集、手写数字数据集,以及使用 make_circles 和 make_moons 函数生成的两个数据集。

iris = datasets.load_iris()
X_digits, y_digits = datasets.load_digits(return_X_y=True)
data_sets = [
    (iris.data, iris.target),
    (X_digits, y_digits),
    datasets.make_circles(noise=0.2, factor=0.5, random_state=1),
    datasets.make_moons(noise=0.3, random_state=0),
]

绘制每个数据集的学习曲线

最后,我们可以使用 plot_on_dataset 函数为每个数据集绘制学习曲线。我们将创建一个 2x2 的图,并在单独的轴上绘制每个数据集。

fig, axes = plt.subplots(2, 2, figsize=(15, 10))

for ax, data, name in zip(
    axes.ravel(), data_sets, ["鸢尾花", "手写数字", "圆圈", "月亮"]
):
    plot_on_dataset(*data, ax=ax, name=name)

fig.legend(ax.get_lines(), labels, ncol=3, loc="upper center")
plt.show()

总结

在本实验中,我们使用了 Scikit-learn 的 MLPClassifier 来比较不同随机学习策略(包括 SGD 和 Adam)在几个小型数据集上的性能。我们定义了不同的学习率调度和动量参数,然后使用每种策略训练 MLPClassifier。我们在每个数据集上绘制了每种策略的学习曲线,并观察了不同策略如何影响训练损失曲线。我们展示了为数据集和手头任务选择正确学习策略的重要性。