Поиск по сетке для настройки модели
В этой статье я познакомлю вас с очень мощным алгоритмом машинного обучения, которым является алгоритм поиска по сетке. В основном он используется при настройке гиперпараметров и выборе моделей в машинном обучении. Здесь я покажу вам, как реализовать этот алгоритм с помощью Python. В конце этой статьи вы узнаете, как применить его в реальной задаче и как выбрать самые эффективные гиперпараметры для нашей модели машинного обучения чтобы обеспечить максимальную точность.
Что такое поиск по сетке?
Поиск по сетке используется для точной настройки модели машинного обучения. Предположим, у вас есть список перспективных моделей. И вам нужно их настроить. Итак, как вы это сделаете?
Один из вариантов – повозиться с гиперпараметрами вручную, пока вы не найдете отличную комбинацию значений гиперпараметров. Это будет очень утомительная работа, и у вас может не хватить времени на изучение многих комбинаций.
Вместо этого вы можете использовать алгоритм поиска по сетке, чтобы найти нужные данные. Все, что вам нужно сделать, это указать ему, с какими гиперпараметрами вы хотите поэкспериментировать и какие значения необходимо попробовать, и он будет использовать перекрестную проверку для оценки всех возможных комбинаций значений гиперпараметров.
Также Вы должны знать, что можно рассматривать некоторые этапы подготовки данных как гиперпараметры. Например, поиск по сетке автоматически определит, следует ли добавлять функцию, в которой вы не были уверены. Аналогичным образом его можно использовать для автоматического поиска лучшего способа обработки выбросов, отсутствующих функций, выбора функций и т. д.
Обучение модели глубокого обучения
Теперь давайте посмотрим, как мы можем реализовать алгоритм поиска по сетке в глубоком обучении. Набор данных, который я буду использовать здесь, основан на диабете, который можно легко скачать отсюда.
Теперь приступим к импорту необходимых библиотек:
from sklearn.model_selection import GridSearchCV, KFold from keras.models import Sequential from keras.layers import Dense, Dropout from keras.wrappers.scikit_learn import KerasClassifier from keras.optimizers import Adam import sys import pandas as pd import numpy as np
А сейчас давайте импортируем и прочитаем набор данных.
columns = ['num_pregnant', 'glucose_concentration', 'blood_pressure', 'skin_thickness', 'serum_insulin', 'BMI', 'pedigree_function', 'age', 'class'] data_path = pd.read_csv("pima-indians-diabetes.csv") df = pd.read_csv(data_path, names=columns) df.head()
Теперь давайте удалим ненужные строки и заменим значения NaN на 0.
# Remove first 9 non-data rows df = df.iloc[9:] # Replace NaN (Not a Number) values with 0 in each column for col in columns: df[col].replace(0, np.NaN, inplace=True) df.dropna(inplace=True) # Drop all rows with missing values dataset = df.values # Convert dataframe to numpy array
Сейчас я разделю набор данных на функции и метки с помощью метода стандартного скаляра.
X = dataset[:,0:8] Y = dataset[:, 8].astype(int) # Normalize the data using sklearn StandardScaler from sklearn.preprocessing import StandardScaler scaler = StandardScaler().fit(X) # Transform and display the training data X_standardized = scaler.transform(X) data = pd.DataFrame(X_standardized)
А сейчас я создам функцию, чтобы сделать модель глубокого обучения.
def create_model(learn_rate, dropout_rate): # Create model model = Sequential() model.add(Dense(8, input_dim=8, kernel_initializer='normal', activation='relu')) model.add(Dropout(dropout_rate)) model.add(Dense(4, input_dim=8, kernel_initializer='normal', activation='relu')) model.add(Dropout(dropout_rate)) model.add(Dense(1, activation='sigmoid')) # Compile the model adam = Adam(lr=learn_rate) model.compile(loss='binary_crossentropy', optimizer=adam, metrics=['accuracy']) return model
И теперь я реализую алгоритм поиска по сетке, но, чтобы лучше понять его, давайте сначала обучим нашу модель, не применяя ее.
# Declare parameter values dropout_rate = 0.1 epochs = 1 batch_size = 20 learn_rate = 0.001 # Create the model object by calling the create_model function we created above model = create_model(learn_rate, dropout_rate) # Fit the model onto the training data model.fit(X_standardized, Y, batch_size=batch_size, epochs=epochs, verbose=1)
Результат:
Epoch 1/1
130/130 [==============================] - 0s 2ms/step - loss: 0.6934 - accuracy: 0.6000
Итак, без реализации алгоритма поиска по сетке мы получили точность в 60 %, и теперь давайте посмотрим, насколько мы можем повысить точность после реализации алгоритма в нашей модели глубокого обучения.
Реализация алгоритма поиска по сетке
Сначала я изменю функцию, которую создал выше, потому что для использования нашего алгоритма нам нужно применять некоторые из параметров к функции create_model.
def create_model(learn_rate, dropout_rate): # Create model model = Sequential() model.add(Dense(8, input_dim=8, kernel_initializer='normal', activation='relu')) model.add(Dropout(dropout_rate)) model.add(Dense(4, input_dim=8, kernel_initializer='normal', activation='relu')) model.add(Dropout(dropout_rate)) model.add(Dense(1, activation='sigmoid')) # Compile the model adam = Adam(lr=learn_rate) model.compile(loss='binary_crossentropy', optimizer=adam, metrics=['accuracy']) return model # Create the model model = KerasClassifier(build_fn=create_model, verbose=1)
А теперь применим наш алгоритм и сопоставим данные по нему:
# Define the parameters that you wish to use in your Grid Search along # with the list of values that you wish to try out learn_rate = [0.001, 0.02, 0.2] dropout_rate = [0.0, 0.2, 0.4] batch_size = [10, 20, 30] epochs = [1, 5, 10] seed = 42 # Make a dictionary of the grid search parameters param_grid = dict(learn_rate=learn_rate, dropout_rate=dropout_rate, batch_size=batch_size, epochs=epochs ) # Build and fit the GridSearchCV grid = GridSearchCV(estimator=model, param_grid=param_grid, cv=KFold(random_state=seed), verbose=10) grid_results = grid.fit(X_standardized, Y) # Summarize the results in a readable format print("Best: {0}, using {1}".format(grid_results.best_score_, grid_results.best_params_)) means = grid_results.cv_results_['mean_test_score'] stds = grid_results.cv_results_['std_test_score'] params = grid_results.cv_results_['params'] for mean, stdev, param in zip(means, stds, params): print('{0} ({1}) with: {2}'.format(mean, stdev, param))
Результат:
Best: 0.7959183612648322, using {'batch_size': 10, 'dropout_rate': 0.2, 'epochs': 10, 'learn_rate': 0.02}
В выходных данных вы можете видеть, что это дает нам лучшую комбинацию гиперпараметров, которая повышает точность нашей модели, и теперь она составляет 75 %.
Надеюсь, вам понравилась эта статья об алгоритме поиска по сетке в глубоком обучении.