Как реализовать гиперпараметр с использованием набора данных MNIST - PullRequest
0 голосов
/ 10 февраля 2019

В настоящее время я запускаю программу в блокноте Jupyter для классификации набора данных MNIST.Я пытаюсь использовать классификатор KNN, чтобы сделать это, и это занимает больше часа, чтобы бежать.Я новичок в классификаторах и гиперпараметрах, и, похоже, нет достойных руководств о том, как правильно реализовать один из них.Кто-нибудь может дать мне несколько советов о том, как использовать гиперпараметр для этой классификации?Я искал и видел GridSearchCv и RandomizedSearchCV.При просмотре их примеров кажется, что они выбирают разные имена атрибутов и меняют их на те, которые необходимы для их кода.Я не понимаю, как это можно сделать для набора данных MNIST, если данные представляют собой просто рукописные цифры.Видя, что есть только цифры, не может ли быть необходимость в гиперпараметре в этом случае?Это мой код, который я до сих пор работаю.Спасибо за любую помощь, которую вы можете предоставить.

# To support both python 2 and python 3
from __future__ import division, print_function, unicode_literals

# Common imports
import numpy as np
import os

# to make this notebook's output stable across runs
np.random.seed(42)

# To plot pretty figures
%matplotlib inline
import matplotlib
import matplotlib.pyplot as plt
plt.rcParams['axes.labelsize'] = 14
plt.rcParams['xtick.labelsize'] = 12
plt.rcParams['ytick.labelsize'] = 12

# Where to save the figures
PROJECT_ROOT_DIR = "."
CHAPTER_ID = "classification"

def save_fig(fig_id, tight_layout=True):
    image_dir = os.path.join(PROJECT_ROOT_DIR, "images", CHAPTER_ID)
    if not os.path.exists(image_dir):
        os.makedirs(image_dir)

    path = os.path.join(image_dir, fig_id + ".png")
    print("Saving figure", fig_id)
    if tight_layout:
        plt.tight_layout()
    plt.savefig(path, format='png', dpi=300)
def sort_by_target(mnist):
    reorder_train = np.array(sorted([(target, i) for i, target in enumerate(mnist.target[:60000])]))[:, 1]
    reorder_test = np.array(sorted([(target, i) for i, target in enumerate(mnist.target[60000:])]))[:, 1]
    mnist.data[:60000] = mnist.data[reorder_train]
    mnist.target[:60000] = mnist.target[reorder_train]
    mnist.data[60000:] = mnist.data[reorder_test + 60000]
    mnist.target[60000:] = mnist.target[reorder_test + 60000]
try:
    from sklearn.datasets import fetch_openml
    mnist = fetch_openml('mnist_784', version=1, cache=True)
    mnist.target = mnist.target.astype(np.int8) # fetch_openml() returns targets as strings
    sort_by_target(mnist) # fetch_openml() returns an unsorted dataset
except ImportError:
    from sklearn.datasets import fetch_mldata
    mnist = fetch_mldata('MNIST original')
    mnist["data"], mnist["target"]
mnist.data.shape
X, y = mnist["data"], mnist["target"]
X.shape
y.shape

#select and display some digit from the dataset
import matplotlib
import matplotlib.pyplot as plt

some_digit_index = 7201
some_digit = X[some_digit_index]
some_digit_image = some_digit.reshape(28, 28)
plt.imshow(some_digit_image, cmap = matplotlib.cm.binary,
           interpolation="nearest")
plt.axis("off")

save_fig("some_digit_plot")
plt.show()

#print some digit's label
print('The ground truth label for the digit above is: ',y[some_digit_index])
X_train, X_test, y_train, y_test = X[:60000], X[60000:], y[:60000], y[60000:]
#random shuffle
import numpy as np

shuffle_index = np.random.permutation(60000)
X_train, y_train = X_train[shuffle_index], y_train[shuffle_index]
from sklearn.model_selection import cross_val_predict
from sklearn.neighbors import KNeighborsClassifier

y_train_large = (y_train >= 7)
y_train_odd = (y_train % 2 == 1)
y_multilabel = np.c_[y_train_large, y_train_odd]

knn_clf = KNeighborsClassifier()
knn_clf.fit(X_train, y_multilabel)
knn_clf.predict([some_digit])

y_train_knn_pred = cross_val_predict(knn_clf, X_train, y_multilabel, cv=3, n_jobs=-1)
f1_score(y_multilabel, y_train_knn_pred, average="macro")

1 Ответ

0 голосов
/ 11 февраля 2019

Самым популярным гиперпараметром для KNN будет n_neighbors, то есть, сколько ближайших соседей вы считаете назначить метку для новой точки.По умолчанию установлено значение 5, но это может быть не лучшим выбором.Поэтому часто лучше найти лучший выбор для вашей конкретной проблемы.

Вот как вы найдете оптимальный гиперпараметр для вашего примера:

from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import GridSearchCV

param_grid = {"n_neighbors" : [3,5,7]}     

KNN=KNeighborsClassifier()

grid=GridSearchCV(KNN, param_grid = param_grid , cv = 5, scoring = 'accuracy', return_train_score = False)
grid.fit(X_train,y_train)

Что это делает, сравниваетпроизводительность вашей модели KNN с различными значениями n_neighbors, которые вы установили.Затем, когда вы сделаете:

print(grid.best_score_)
print(grid.best_params_)

, он покажет вам, какой был лучший показатель производительности и для какого выбора параметров он был достигнут.

Все это не имеет ничего общего с тем, что вы используете данные MNIST.Вы можете использовать этот подход для любой другой задачи классификации, если вы думаете, что KNN может быть разумным выбором для вашей задачи (что может быть спорным для классификации изображений).Единственное, что может измениться от одной задачи к другой, - это оптимальное значение гиперпараметров.

PS: я бы посоветовал не использовать терминологию y_multilabel, так как это может относиться к конкретной задаче классификации, где для каждой информацииу точки может быть несколько меток, что не так в MNIST (каждое изображение представляет только одну цифру за раз).

...