Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

Matplotlib로 MLPClassifier의 loss_curve_ 손실 곡선 시각화하기

scikit-learn의 MLPClassifier(다층 퍼셉트론 분류기)는 학습 과정에서 각 반복(iteration)마다 계산된 손실(loss) 값을 loss_curve_ 속성에 저장합니다. 이 손실 곡선을 Matplotlib로 적절하게 시각화하면 학습률, 모멘텀, 솔버 등 하이퍼파라미터 설정에 따라 모델이 얼마나 잘 수렴하는지 한눈에 비교할 수 있습니다.

손실 곡선을 플롯하는 단계

  • 그림 크기를 설정하고 서브플롯 주변 및 사이의 여백(padding)을 조정합니다.
  • 다양한 학습 옵션을 담은 딕셔너리 리스트(params)를 만듭니다.
  • 각 설정에 대한 레이블(labels)과 플롯 스타일(plot_args) 목록을 준비합니다.
  • nrows=2, ncols=2로 구성된 figure와 subplot 집합을 생성합니다.
  • Iris(붓꽃), Digits(숫자 필기체) 데이터셋과 make_circles, make_moons로 생성한 합성 데이터셋을 로드합니다.
  • 각 데이터셋과 축(ax), 데이터셋 이름을 zip으로 묶어 순회합니다.
  • plot_on_dataset() 함수 내에서 현재 축의 제목을 설정하고, MinMaxScaler로 특성 값을 정규화합니다.
  • MLPClassifier 인스턴스를 각 파라미터 조합마다 생성하여 학습(fit)시키고, mlps 리스트에 저장합니다.
  • 학습된 각 MLP 객체의 mlp.loss_curve_plot() 메서드로 그립니다.
  • 마지막으로 show() 메서드로 그림을 화면에 출력합니다.

예제 코드

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

plt.rcParams["figure.figsize"] = [7.50, 3.50]
plt.rcParams["figure.autolayout"] = True

# 솔버, 학습률, 모멘텀 등 다양한 하이퍼파라미터 조합
params = [{'solver': 'sgd', 'learning_rate': 'constant', 'momentum': 0, 'learning_rate_init': 0.2},
    {'solver': 'sgd', 'learning_rate': 'constant', 'momentum': .9, 'nesterovs_momentum': False, 'learning_rate_init': 0.2},
    {'solver': 'sgd', 'learning_rate': 'constant', 'momentum': .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': .9, 'nesterovs_momentum': True, 'learning_rate_init': 0.2},
    {'solver': 'sgd', 'learning_rate': 'invscaling', 'momentum': .9, 'nesterovs_momentum': False, 'learning_rate_init': 0.2},
    {'solver': 'adam', 'learning_rate_init': 0.01}]

labels = ["constant learning-rate", "constant with momentum", "constant with Nesterov's momentum",
          "inv-scaling learning-rate", "inv-scaling with momentum", "inv-scaling with Nesterov's momentum", "adam"]

plot_args = [{'c': 'red', 'linestyle': '-'},
    {'c': 'green', 'linestyle': '-'},
    {'c': 'blue', 'linestyle': '-'},
    {'c': 'red', 'linestyle': '--'},
    {'c': 'green', 'linestyle': '--'},
    {'c': 'blue', 'linestyle': '--'},
    {'c': 'black', 'linestyle': '-'}]

def plot_on_dataset(X, y, ax, name):
    ax.set_title(name)
    X = MinMaxScaler().fit_transform(X)
    mlps = []
    if name == "digits":
        max_iter = 15  # digits는 데이터가 많아 빠른 비교를 위해 반복 횟수를 줄임
    else:
        max_iter = 400
    for label, param in zip(labels, params):
        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)
    for mlp, label, args in zip(mlps, labels, plot_args):
        ax.plot(mlp.loss_curve_, label=label, **args)

fig, axes = plt.subplots(2, 2)
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)]

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()

실행 결과

코드를 실행하면 iris, digits, circles, moons 네 개의 데이터셋에 대해 각각 2×2 격자 형태의 서브플롯에 손실 곡선이 그려집니다. 각 곡선은 색상과 선 스타일로 구분되며, 상단 중앙의 범례(legend)를 통해 어떤 하이퍼파라미터 조합인지 확인할 수 있습니다.

Matplotlib로 MLPClassifier의 loss_curve_ 손실 곡선 시각화하기

Matplotlib로 MLPClassifier의 loss_curve_ 손실 곡선 시각화하기

결과 해석 포인트

  • Adam 옵티마이저: 대부분의 데이터셋에서 가장 빠르고 안정적으로 손실이 감소하는 경향을 보입니다.
  • 모멘텀(momentum): SGD에 모멘텀을 추가하면 수렴 속도가 눈에 띄게 향상됩니다.
  • Nesterov 모멘텀: 일반적인 모멘텀과 유사하지만 경우에 따라 더 부드러운 수렴을 보입니다.
  • inv-scaling 학습률: 반복이 진행될수록 학습률이 점진적으로 감소하여 후반부에 안정적인 수렴을 보입니다.

이처럼 loss_curve_를 시각화하면 단순히 최종 정확도만 비교하는 것보다 각 옵티마이저와 학습률 전략의 수렴 특성을 직관적으로 이해할 수 있어, 모델 튜닝에 매우 유용합니다.