Scikit-Learn MLPClassifier: 확률적 학습 전략 비교

Beginner

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

소개

이 실습에서는 Scikit-learn MLPClassifier 를 사용하여 SGD 와 Adam 을 포함한 다양한 확률적 학습 전략의 성능을 비교하는 과정을 안내합니다. MLPClassifier 는 역전파를 사용하여 신경망의 가중치를 최적화하는 신경망 분류기입니다. 이 실습의 목표는 서로 다른 확률적 학습 전략이 MLPClassifier 의 학습 손실 곡선에 어떤 영향을 미치는지 보여주는 것입니다. 이 예제에서는 여러 개의 작은 데이터셋을 사용하지만, 이러한 예제에서 보여주는 일반적인 경향은 대규모 데이터셋에도 적용되는 것으로 보입니다.

VM 팁

VM 시작이 완료되면 왼쪽 상단 모서리를 클릭하여 Notebook 탭으로 전환하여 연습을 위한 Jupyter Notebook에 접근합니다.

때때로 Jupyter Notebook 이 완전히 로드되기까지 몇 초 정도 기다려야 할 수 있습니다. Jupyter Notebook 의 제한으로 인해 작업의 유효성 검사를 자동화할 수 없습니다.

학습 중 문제가 발생하면 Labby 에게 문의하십시오. 세션 후 피드백을 제공하면 문제를 신속하게 해결해 드리겠습니다.

필요한 라이브러리 가져오기

먼저, 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 등 여러 가지 서로 다른 학습률 스케줄과 모멘텀 매개변수를 정의합니다. 또한, 나중에 플롯에 사용할 레이블과 plot_args 를 정의합니다.

## 서로 다른 학습률 스케줄과 모멘텀 매개변수
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": "red", "linestyle": "-"},
    {"c": "green", "linestyle": "-"},
    {"c": "blue", "linestyle": "-"},
    {"c": "red", "linestyle": "--"},
    {"c": "green", "linestyle": "--"},
    {"c": "blue", "linestyle": "--"},
    {"c": "black", "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, ["iris", "digits", "circles", "moons"]
):
    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 를 학습시켰습니다. 각 데이터셋에 대한 각 전략의 학습 곡선을 플롯하고 서로 다른 전략이 학습 손실 곡선에 어떤 영향을 미치는지 관찰했습니다. 데이터셋과 작업에 적합한 올바른 학습 전략을 선택하는 것이 중요함을 보여주었습니다.